/******************************************************************************
 * Created 2008-08-19.
 *
 * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
 *
 * Copyright (C) 2008
 *   Wyatt Baldwin <self@wyattbaldwin.com>
 *   All rights reserved
 *
 * Licensed under the MIT license.
 *
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *****************************************************************************/
window.util = {
  __name__: 'util',
  __parent__: window,

  keys: function (obj) {
    var keys = [];
    for (var key in obj) {
      keys.push(key);
    }
    return keys;
  },

  items: function (obj) {
    var items = [];
    for (var key in obj) {
      items.push(obj[key]);
    }
    return items;
  },

  NameSpace: function (name, parent, definition) {
    if (typeof(definition) == 'undefined') {
      definition = parent;
      parent = window;
    }
    var ns = definition || {};
    ns.__name__ = name;
    ns.__parent__ = parent;
    parent[name] = ns;
    return ns;
  },

  Class: function (namespace, name, base, definition) {
    base = base || Function;
    definition = definition || {};
    // Create the skeleton of the class. The statements in this function will
    // be called whenever ``new <namespace>.<name>`` is called (that is,
    // whenever an instance is created from the class.
    var cls = function () {
      this.__init__.apply(this, arguments);
    };
    // Set "special" class attributes.
    cls.superclass = base;
    cls.__name__ = name;
    cls.__namespace__ = namespace;
    // Set class's initial attributes to base class's attributes.
    cls.prototype = {};
    for (var attr in base.prototype) {
      cls.prototype[attr] = base.prototype[attr];
    }
    // Add user-friendly default toString method.
    var default_string_value = ['<class ', name, '>'].join('');
    cls.prototype.toString = function () {
      return default_string_value;
    };
    cls.prototype.__class__ = cls;
    // Add class attributes, overriding base class attributes.
    for (var attr in definition) {
      cls.prototype[attr] = definition[attr];
    }
    // Ensure the class has an initialization method.
    var __init__ = cls.prototype.__init__;
    cls.prototype.__init__ = __init__ || function () {};
    // Set the class's constructor to the function defined above.
    cls.prototype.constructor = cls;
    // Add the class to the specified namespace/namespace.
    namespace[name] = cls;
    // Added this because it might be useful in certain scenarios.
    return cls;
  }
};
