/* moo.toolkit: MIT LICENSE */

/*---------------------------------------------------------------------------------------------------------*/
//# [1kb] moo.ray: array functions
/*---------------------------------------------------------------------------------------------------------*/

function $S() {
  if (arguments.length == 1){
    if(typeof arguments[0] == 'string') {
      if (arguments[0].charAt(0) == '#' && arguments[0].indexOf(' ') == -1)
        return $(arguments[0].slice(1)) || null;
      return dom.getSelector(arguments[0]);
    }
    else return arguments[0];
  }
  var elements = [];
  arguments.each(function(sel){
    if (typeof sel == 'string') {
      dom.getSelector(sel).each(function(el){
        elements.push(el);
      });
    }
    else elements.push(sel);
  });
  return elements;
}

function $e(array){
  var nArray = [];
  for (i=0;el=array[i];i++) nArray.push(el);
  return nArray;
}

Array.prototype.each = function(func){
  for(var i=0;ob=this[i];i++) func(ob, i);
}

Array.prototype.action = function(actions){
  this.each(function(el){
    if (actions.initialize) actions.initialize(el);
    for(action in actions){
      if (action.slice(0,2) == 'on') el[action] = actions[action];
    }
  });
}

Array.prototype.find = function(mode){
  var elements = [];
  this.each(function(el){
    el = el[mode];
    while (el.nodeType != 1) el = el[mode];
    elements.push(el);
  });
  if (elements.length == 1) return elements[0];
  return elements;
}

/*---------------------------------------------------------------------------------------------------------*/
//# [2kb] moo.dom:target html elements using css selectors
/*---------------------------------------------------------------------------------------------------------*/

dom = {
  getSelector: function(selector){
    var params = [];
    selector.split(' ').each(function(arg, j){
      params[j] = param = [];
      if (arg.indexOf('#') > -1) {
        var bits = arg.split('#');
        param['tag'] = bits[0] || '*';
        param['id'] = bits[1];
      }
      else if (arg.indexOf('.') > -1) {
        var bits = arg.split('.');
        param['tag'] = bits[0] || '*';
        param['class'] = bits[1];
      }
      else param['tag'] = arg;
    });
    this.filter = [document];
    params.each(function(param, k){
      if (k == 0 && param['id']) {
        var id = $(param['id']);
        if (param['tag'] == '*' || id.tagName.toLowerCase() == param['tag'])
          this.filter = [id];
        else return [];
      }
      else {
        this.filter = this._getElementsWithTagName(param['tag']);
        if (param['class']) this.filter = this._getElementsWithClassName(param['class']);
        else if (param['id']) this.filter = this._getElementsWithId(param['id']);
      }
    }.bind(this));
    return this.filter;
  },

  sheets: [],

  append: function(sheet){
    this.sheets.push(sheet);
  },

  start: function(){
    this.sheets.each(function(sheet){
      this.update(sheet);
    }.bind(this));
  },

  //based on Behaviour by Ben Nolan (http://bennolan.com/behaviour/)
  update: function(sheet){
    for (selector in sheet){
      selector.split(',').each(function(comb){
        var elements = this.getSelector(comb.replace(/^\s*|\s*$/g,"")) || null;
        elements.each(function(element){
          sheet[selector](element);
        });
      }.bind(this));
    }
  },

  _getElementsWithId: function(id){
    var found = [];
    this.filter.each(function(el){
      if (el.id == id) found.push(el);
    });
    return found;
  },

  _getElementsWithClassName: function(className){
    var found = [];
    this.filter.each(function(el){
      if (Element.hasClassName(el, className)) found.push(el);
    });
    return found;
  },

  _getElementsWithTagName: function(tagName){
    var found = [];
    this.filter.each(function(el){
      $e(el.getElementsByTagName(tagName)).each(function(tn){
        found.push(tn);
      });
    });
    return found;
  }
};

/*---------------------------------------------------------------------------------------------------------*/
//# [2.5kb] prototype.lite: mini version of prototype, modified
/*---------------------------------------------------------------------------------------------------------*/

/*  Prototype JavaScript framework
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
/*--------------------------------------------------------------------------*/

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

Object.extend = function(destination, source) {
  for (property in source) destination[property] = source[property];
  return destination;
}

Function.prototype.bind = function(object) {
  var __method = this;
  return function() {
    return __method.apply(object, arguments);
  }
}

Function.prototype.bindAsEventListener = function(object) {
var __method = this;
  return function(event) {
    __method.call(object, event || window.event);
  }
}

function $() {
  if (arguments.length == 1) return get$(arguments[0]);
  var elements = [];
  arguments.each(function(el){
    elements.push(get$(el));
  });
  return elements;

  function get$(el){
    if (typeof el == 'string') el = document.getElementById(el);
    return el;
  }
}

if (!window.Element) var Element = new Object();

Object.extend(Element, {
  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },

  hasClassName: function(element, className) {
    element = $(element);
    if (!element) return;
    var hasClass = false;
    element.className.split(' ').each(function(cn){
      if (cn == className) hasClass = true;
    });
    return hasClass;
  },

  setStyle: function(element, style) {
    element = $(element);
    for (name in style)
      element.style[camelize(name)] = style[name];
  },

  addClassName: function(element, className) {
    element = $(element);
    Element.removeClassName(element, className);
    element.className += ' ' + className;
  },

  removeClassName: function(element, className) {
    element = $(element);
    if (!element) return;
    var newClassName = '';
    element.className.split(' ').each(function(cn, i){
      if (cn != className){
        if (i > 0) newClassName += ' ';
        newClassName += cn;
      }
    });
    element.className = newClassName;
  },

  cleanWhitespace: function(element) {
    element = $(element);
    $e(element.childNodes).each(function(node){
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node);
    });
  }
});


