// *******************************************************
//
// wbCore - Extensions for Prototype
// Copyright 2008 Holodyn Corporation
//
//  Element.upOr()
//  Element.setValues()
//  Element.toggleValues()
//  Element.addRow()
//
//  Enumerable.setValues()
//  Enumerable.toggleValues()
//
// *******************************************************
//
// v100 Build to Mootools
//
// *******************************************************

String.prototype.reverse = function(){
  stxt = this.split('');
  rtxt = stxt.reverse();
  return rtxt.join('');
}

var $F = function(key){
  return $( key ).getValue();
  };

var Element_PrototypeBridge = {

  // -----------------------------------------------------
  // Prototype => Mootools
  inspect: function() {
    var element;if(!(element=$(this))) return;
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(property,attribute) {
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  // -----------------------------------------------------
  // Prototype => Mootools
  descendants: function(str){
    var element;if(!(element=$(this))) return;
    return element.getChildren(str);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  insert: function(elm){
    var element;if(!(element=$(this))) return;
    return element.appendChild(elm);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  show: function(){
    var element;if(!(element=$(this))) return;
    return element.setStyle('display', '');
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  hide: function(){
    var element;if(!(element=$(this))) return;
    return element.setStyle('display', 'none');
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  writeAttribute: function(key, val){
    var element, elements=[];if(!(element=$(this))) return;
    return element.setProperty(key,val);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  readAttribute: function(key, val){
    var element, elements=[];if(!(element=$(this))) return;
    return element.getProperty(key,val);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  setValue: function(/*element,*/val){
    var element, elements=[];if(!(element=$(this))) return;
    switch(element.getTag()){
      case 'select':
        var values = Object.isArray(val) ? val : String(val).split(',');
        $each(element.options, function(option){
          if(values.indexOf(option.value) >= 0) option.selected = true;
            else option.selected = false;
        });
      default:
        this.value = val;
    }
    return element;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  clear: function(){
    var element;if(!(element=$(this))) return;
    element.value='';return element;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  observe: function(/*element,*/ev, fn){
    var element;if(!(element=$(this))) return;
    return element.addEvent(ev,fn);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  stopObserving: function(/*element,*/ev, fn){
    var element;if(!(element=$(this))) return;
    return element.removeEvent(ev,fn);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  fire: function(/*element,*/){
    var element;if(!(element=$(this))) return;
    var ev = arguments.length > 0 ? arguments[0] : null;
    var ar = arguments.length > 1 ? arguments[1] : [];
    var dl = arguments.length > 2 ? arguments[2] : 0;
    return ev ? element.fireEvent(ev,ar,dl) : element;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  addClassName: function(/*element,*/className){
    var element;if(!(element=$(this))) return;
    return element.addClass(className);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  removeClassName: function(/*element,*/className){
    var element;if(!(element=$(this))) return;
    return element.removeClass(className);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  hasClassName: function(/*element,*/className){
    var element;if(!(element=$(this))) return;
    return element.hasClass(className);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  toggleClassName: function(/*element,*/className){
    var element;if(!(element=$(this))) return;
    return element.toggleClass(className);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  update: function(/*element,*/html) {
    var element;if(!(element=$(this))) return;
    return element.setHTML( html );
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  identify: function(/*element,*/) {
    var element;if(!(element=$(this))) return;
    var id = String(element.id), self = arguments.callee;
    if(!self.counter)self.counter=1;if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.setProperty('id', id);return id;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  select_v1: function(str){
    if($type(this)=='element')
      return $ES(str,this);
    return $ES(this);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  select: function(set){
    if($type(this)!='element') set=this;
    if(Object.isString(set)) set=[set];
    var res = [];
    for(var i=0;i<set.length;i++){
      if($type(this)=='element')
        res.extend($ES(set[i],this));
      else
        res.extend($ES(set[i]));
    }
    return res;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  next: function(/*element,*/str){
    var element;if(!(element=$(this))) return;
    return element.getNext(str);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  previous: function(/*element,*/str){
    var element;if(!(element=$(this))) return;
    return element.getPrevious(str);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  up: function(/*element,*/str){
    var element;if(!(element=$(this))) return;
    var elm = element;
    while(elm.getParent){
      elm=elm.getParent(str ? str : '');
      if(str){
        if(elm.match(str))
          return elm;
      } else
        return elm;
      }
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  down: function(/*element,*/str){
    var element;if(!(element=$(this))) return;
    // return element.getFirst( str ? str : '' );
    if(Object.isUndefined(str))
      return element.getFirst();
    return element.getElement(str);
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  enable: function(elm){
    var element;if(!(element=$(this)) && !(element=$(elm))) return;
    if( element.getTag()=='form' )
      fields = $$(element.getElementsByTagName('input'), element.getElementsByTagName('select'), element.getElementsByTagName('textarea'));
      else fields = [element];
    fields.each(function(el){el.disabled=false;});
    return element;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  disable: function(elm){
    var element;if (!(element = $(this)) && !(element=elm)) return;
    if( element.getTag()=='form' )
      fields = $$(element.getElementsByTagName('input'), element.getElementsByTagName('select'), element.getElementsByTagName('textarea'));
      else fields = [element];
    fields.each(function(el){el.disabled=true;});
    return element;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  serialize: function(options){
    var element;if(!(element=$(this))) return;
    options = $merge({ 'hash': false, 'submit': false, 'disabled': false, 'helpmulti': false }, options);
    var fields, key, value, subt = false, submit = options.submit, result = [];
    if( options.fields )fields = options.fields;
      else fields = $$(element.getElementsByTagName('input'), element.getElementsByTagName('select'), element.getElementsByTagName('textarea'));
    fields.each(function(el){
      if(el.name && (!el.disabled || options.disabled === true)) {
        var key = el.name, value = el.getValue();
        if(value !== false && el.type != 'file' && (el.type != 'submit' || (!subt && submit !== false && (!submit || key == submit) && (subt = true)))) {
          var qs = function(val){ result.push(key + '=' + encodeURIComponent(val)); };
          if ($type(value) == 'array'){
            if(options.helpmulti === true && !/\[\]$/.test(name)) name = name+'[]';
            value.each(qs);
          } else qs(value);
        }
      }
    });
    return result.join('&');
    }
  };

var Element_PrototypeBridge_M11 = {

  // -----------------------------------------------------
  // Prototype => Mootools
  getDimensions: function(elm){
    var element;if(!(element=$(this)) && !(element=$(elm))) return;
    var display = element.getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};
    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  getWidth: function(elm){
    var element;if(!(element=$(this)) && !(element=$(elm))) return;
    return element.getDimensions().width;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  getHeight: function(el){
    var element;if(!(element=$(this)) && !(element=$(elm))) return;
    return element.getDimensions().height;
    },

  // -----------------------------------------------------
  // Prototype => Mootools
  match: function(str){
    if (!(elmx = $(this))) return;
    var elms=elmx.getParent().getElements(str);
    return elms.indexOf(elmx) >= 0 ? true : false;
    }

};

var Element_PackageCustom = {

  // -----------------------------------------------------
  // Custom Function
  // Returns Current OR Parent Element
  upOr: function(/*element,*/str){
    var element;if(!(element=$(this))) return;
    if(element.match(str)) return element;
      else return element.up(str);
    },

  // -----------------------------------------------------
  // Custom Function
  // Set Multiple Value Pairs on Multiple Elements
  setValues: function(/*element,*/evals){
    var element;if(!(element=$(this))) return;
    if(!Object.isHash(evals)) evals = $H(evals);
    var kI, keyNames, Keys=evals.keys();
    for(kI=0;kI<Keys.length;kI++){
      keyNames = Keys[kI].replace(/\s+/g,'').split('.');
      eval('element.'+keyNames.join('.')+' = evals.get(Keys[kI]);');
    }
    return element;
  },

  // -----------------------------------------------------
  // Custom Function
  // Toggle Value Pairs on Multiple Elements
  toggleValues: function(/*element,*/evals){
    var element;if(!(element=$(this))) return;
    if(!Object.isHash(evals)) evals = $H(evals);
    var kI, vI, keyNames, elmValue, Keys=evals.keys();
    for(kI=0;kI<Keys.length;kI++){
      keyNames = Keys[kI].replace(/\s+/g,'').split('.'); keyValues = evals.get(Keys[kI]);
      eval('try{ elmValue = element.'+keyNames.join('.')+'; } catch(e) { elmValue = null; }');
      if(Object.isArray(keyValues)){
        vI = null;
        if(!Object.isUndefined(elmValue))
          for(vI=0;vI<keyValues.length;vI++)
            if( (elmValue == (Object.isArray(keyValues[vI])?keyValues[vI][1]:keyValues[vI]))
                || (Object.isString(elmValue)
                    && Object.isArray(keyValues[vI])
                    && elmValue.match(keyValues[vI][0]))
              ) break;
        vI = isNaN(vI) ? 0 : (vI<keyValues.length-1 ? vI+1 : 0);
        elmValue = Object.isArray(keyValues[vI]) ? keyValues[vI][1] : keyValues[vI];
      } else if(elmValue == keyValues) elmValue = null;
        else elmValue = keyValues;
      eval('element.'+keyNames.join('.')+' = elmValue;');
    }
    return element;
  },

  // -----------------------------------------------------
  // Custom Function
  // Add Table Row
  addRow: function(/*element,*/rowData,cellData,cells){
    var element;if (!(element = $(this))) return;
    var i, key, newRow = $(document.createElement('TR'));
    for(key in rowData)
      newRow.setProperty(key,rowData[key]);
    for(i=0;i<cells.length;i++){
      var newCell = $(document.createElement('TD'));
      var tmpCell = (cells[i].content != undefined?cells[i].content:(cellData.content != undefined?cellData.content:''));
      for(key in cellData)
        if(key.match(/replace/))
          tmpCell = tmpCell.replace(cellData[key][0],cellData[key][1]);
        else if(key.match(/style/))
          newCell.style[cellData[key][0]] = cellData[key][1];
        else if(!key.match(/content/))
          newCell.setProperty(key,cellData[key]);
      for(key in cells[i])
        if(key.match(/replace/))
          tmpCell = tmpCell.replace(cells[i][key][0],cells[i][key][1]);
        else if(key.match(/style/))
          newCell.style[cells[i][key][0]] = cells[i][key][1];
        else if(!key.match(/content/))
          newCell.setProperty(key,cells[i][key]);
      newCell.update( tmpCell );
      newRow.appendChild(newCell);
    }
    if(element.nodeName == 'TR')
      element.up().insertBefore(newRow,element.next());
    else
      element.appendChild(newRow);
    return newRow;
  }

};

if( /^1.1/.test(MooTools.version) ){
  Element.extend(Element_PrototypeBridge);
  Element.extend(Element_PrototypeBridge_M11);
  Element.extend(Element_PackageCustom);
} else {
  Element.implement(Element_PrototypeBridge);
  Element.implement(Element_PackageCustom);
}

var Enumerable_CustomMethods = {

  // -----------------------------------------------------
  // Prototype => Mootools
  setValue: function(val){
    if(!this.length||!arguments)return this;
    for(var eI=0;eI<this.length;eI++)
      if(Object.isElement(this[eI]))
        this[eI].setValue(val);
  },

  // -----------------------------------------------------
  // Custom Function
  // Set Multiple Value Pairs on Multiple Elements
  setValues: function(){
    if(!this.length||!arguments)return this;
    var mode = 'set', properties = $A(arguments);
    if(Object.isString(properties[0])&&properties[0].match(/^mode/i)){
      mode = properties.shift().replace(/^mode\:(\w+)$/i,'$1');
      properties = properties.shift();
    }
    var evals = Object.isHash(properties[0]) ? properties[0] : $H(properties[0]);
    if(Object.isString(properties[0]) && properties.length==2){
      evals = new Hash();
      evals.set(properties[0],properties[1])
    } else if(properties.length>1)
      for(var aI=1;aI<properties.length;aI++)
        evals.merge(properties[0]);
    for(var eI=0;eI<this.length;eI++)
      if(Object.isElement(this[eI]) || Object.isArray(this[eI]))
        if(mode=='toggle') this[eI].toggleValues(evals);
          else this[eI].setValues(evals);
    return this;
  },

  // -----------------------------------------------------
  // Custom Function
  // Toggle Value Pairs on Multiple Elements
  toggleValues: function(){
    if(!this.length||!arguments)return this;
    return this.setValues('mode:toggle',arguments);
  }

};
Object.extend(Array.prototype, {
  // -----------------------------------------------------
  // Prototype => Mootools
  setValue:       Enumerable_CustomMethods.setValue,
  // -----------------------------------------------------
  // Custom Function
  setValues:      Enumerable_CustomMethods.setValues,
  toggleValues:   Enumerable_CustomMethods.toggleValues
  });

Object.extend({
  // -----------------------------------------------------
  // Prototype => Mootools
  isUndefined:  function(mo){ return typeof mo == "undefined"; },
  isString:     function(mo){ return (typeof mo=='string'); },
  isNumber:     function(mo){ return (typeof mo=='number'); },
  isElement:    function(mo){ return !!(mo && mo.nodeType == 1); },
  isArray:      function(mo){ return mo != null && typeof mo == "object" && 'splice' in mo && 'join' in mo; },
  isFunction:   function(mo){ return (typeof mo=='function'); },
  isObject:     function(mo){ return (Object.isUndefined(mo) || mo.constructor.toString().indexOf("Object") == -1)?false:true; },
  isHash:       function(mo){ return Object.isUndefined(mo) ? false : (typeof(mo.hasKey)=='function' ? true : false); },
  toJSON:       function(object){
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }
    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;
    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }
    return '{' + results.join(', ') + '}';
    },
  inspect: function(object) {
    try {
      if (Object.isUndefined(object)) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : String(object);
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
    }
  });

/*
  Array Functions
  */
Object.extend(Array.prototype, {
  // -----------------------------------------------------
  // Prototype => Mootools
  toJSON: function(){
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
    },
  first: function() {
    return this[0];
    },
  last: function() {
    return this[this.length - 1];
    }
  });

/*
  Hash Functions
  */
Object.extend(Hash.prototype, {
  // -----------------------------------------------------
  // Prototype => Mootools
  toJSON: function(){
    return Object.toJSON(this.obj);
    }
  });

/*
  String Functions
  */
Object.extend(String.prototype, {
  // -----------------------------------------------------
  // Prototype => Mootools
  inspect: function(useDoubleQuotes) {
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
      if (character in String.specialChar) {
        return String.specialChar[character];
      }
      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  toJSON: function() {
    return this.inspect(true);
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  interpolate: function(data){
    var reg, tmp = String(this);
    for(var i in data){
      reg = new RegExp( '\#\{'+i+'\}', "g" );
      tmp = tmp.replace( reg ,data[i] );
    }
    return tmp;
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  isJSON: function(){
    return /^\{.*\}/.test(this);
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  evalJSON: function(fn){
    if(typeof(JSON)=='object')
      if(typeof(JSON.parse)=='function')
        return JSON.parse(this,fn);
      elseif(typeof(JSON.decode)=='function')
        return JSON.decode(this);
    }
  });

/*
  AJAX Functions
    */
Ajax.PeriodicalUpdater = function(container, url, options){
  options = $merge({'method':'get','frequency':6000,'decay':0}, options);
  var fn = function(){new Ajax(url,{}).request();};
  fn.periodical( options.frequency, {} );
  };

/*
  Event Functions
    */
Object.extend(Event, {
  // -----------------------------------------------------
  // Prototype => Mootools
  observe: function(obj,act,func){
    return obj.addEvent(act, func);
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  stopObserving: function(obj,act,func){
    return obj.addEvent(act, func);
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  pointerX: function(event){
    var docElement = document.documentElement,
     body = document.body || { scrollLeft: 0 };
    return event.pageX || (event.clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));
    },
  // -----------------------------------------------------
  // Prototype => Mootools
  pointerY: function(event){
    var docElement = document.documentElement,
     body = document.body || { scrollTop: 0 };
    return  event.pageY || (event.clientY +
       (docElement.scrollTop || body.scrollTop) -
       (docElement.clientTop || 0));
    }
  });

