////////////////////////////////////////////////////////////////////////////////
// Namespace
(function(){

  function function_name(fn){
    return fn.name ? fn.name : fn.toString().match(/^\s*function\s+([^\s\(]+)/)[1];
  }

  function namespace_for(parts){
    var space = this;

    for (var i=0; i < parts.length; i++) {
      space = space[parts[i]] = space[parts[i]] || {};
    };
    return space;
  }

  window.namespace = function(){
    var parts = arguments[0].split(".")
        space = namespace_for(parts);

    for (var i=1; i < arguments.length; i++) {
      space[function_name(arguments[i])] = arguments[i]
    };
  }
})();


////////////////////////////////////////////////////////////////////////////////
// Some global conditions and methods
(function(){

  function inspect(o){
    out = [];
    for (var m in o){ out.push(m+": "+o[m]) }
    return out.join("\n")
  }

  window.inspect = inspect;

  function ready(callback){
    $(document).ready(callback);
  }

  window.ready = ready;

})();

////////////////////////////////////////////////////////////////////////////////
// Array extensions
(function(){

  /////////////////////////////////////////////////////////////////////////////
  Array.prototype.remove = function(o){
    var out = []
    for (var i=0; i < this.length; i++) {
      if(o != this[i]){
        out.push(this[i])
      }
    };
    return out;
  }

  /////////////////////////////////////////////////////////////////////////////
  Array.prototype.flatten = function(){
    var o = [];
    function flatten(a){
      for (var i=0; i < a.length; i++) {o.push(a[i])};
    }
    for (var i=0; i < this.length; i++) {
      if(this[i] != undefined){
        if (Object.prototype.toString.call(this[i]) === '[object Array]'){
          flatten(this[i])
        } else {
          o.push(this[i]);
        }
      }
    };
    return o;
  }

  Array.prototype.compact = function(){
    var o = [];
    for (var i=0; i < this.length; i++) {
      if(this[i] != null || this[i] != undefined){
        o.push(this[i])
      }
    };

    return o;
  }

  /////////////////////////////////////////////////////////////////////////////
  Array.prototype.uniq = function(){
    var o = [],  map = {};
    for (var i=0; i < this.length; i++) {
      if(this[i] in map == false){
        map[this[i]] = true;
        o.push(this[i])
      }
    };
    return o;
  }

  // Converts an array into a hash key/pair object
  // [1,2,3] => {1:null, 2:null, 3:null}
  // [["foo", "bar"]] => {foo:"bar"}
  Array.toHash = function(arr){
    var hash = {}
    for (var i=0; i < arr.length; i++) {
      var o = arr[i]
      if(o.shift){
        var k = o.shift()
        hash[k] = o
      } else {
        hash[o] = null
      }
    }
    return hash;
  }
})();