Array.prototype.append = function (obj) {
    this[this.length] = obj;
};

top.isEmpty = isEmpty = function isEmpty( obj ) {
  if (!top.valid(obj)) return true;
  if (typeof obj == "function") {
    return (obj.length <= 0);
  }
  for ( var i in obj ) {
    return false;
  }
  return true;
};

top.bind = bind = function bind( obj, payload ) {
    Element.extend(obj);
    if ( top.valid (payload) ) {
      if ( typeof payload == 'function' ) {
        payload( obj );
      } else if ( typeof payload == 'object' ) {
        if ( top.valid( payload.action ) && payload.action == 'function' ) {
          payload.action( obj );
        }
      } else {
        payload = obj;
      }
    }
    return obj;
};

top.toNumeric = toNumeric = function ( candidate ) {
    return isNumeric( candidate ) ? parseFloat( candidate ) : 0;
};

top.isNumeric = isNumeric = function ( candidate ) {
    var decRE = new RegExp("^[^\\.]*\\.?[^\\.]*$");
    var digitRE = new RegExp( '^[\\-\\+]?[\\d\\.]+$' );
    return decRE.match( candidate ) && digitRE.match( candidate );
};

top.valid = valid = function ( obj ) {
    return obj != null && typeof obj != 'undefined' && obj;
};

top.taint = taint = function taint( obj, action ) {
    top.taintElem(true, obj, action);
};

top.untaint = untaint = function untaint( obj, action ) {
    top.taintElem(false, obj, action);
};

top.taintElem = taintElem = function taintElem( shouldTaint, obj, action ) {
    if ( !valid( obj ) ) return;
    var elem = bind( obj, action );
    elem.writeAttribute( 'tainted', shouldTaint );
};

top.tainted = tainted = function tainted( obj ) {
    if ( !valid( obj ) ) return false;
    var elem = bind( obj );
    return ( elem.readAttribute('tainted') != null );
};

top.assignToElem = assignToElem = function (elem, val) {
    if ( top.valid(elem) && top.valid(val) ) {
        top.elem = elem;
        if ( typeof elem.setValue == 'function') {
            elem.setValue( val );   
        } else {
            elem.value = val;
        }
    }
};

/*
=============================
    Class Updater

    As PrototypeJS's PeriodicalUpdater has issues with multiple
    updater threads being called upon ajax completion, we use this class
    to wrap around a method that is closer to the native settimeout/setinterval
    functions.
=============================
*/
top.Updater = Updater = function Updater (divToUpdate, interval, url, params)
{
       this.divToUpdate = divToUpdate;
       this.interval = interval;
       this.url = url;
       this.params = params;
       this.executor = new PeriodicalExecuter(this.getUpdate.bind(this), this.interval);
};

/*
    Updater.stop()
*/
top.Updater.prototype.stop = function() {
   /* if ( top.valid(top.debug) ) { top.debug.log('#############  calling halt', this); } */
   if (this.executor) {
       this.executor.stop();
   }
};

/*
    Updater.getUpdate()
*/
top.Updater.prototype.getUpdate = function() {
   var options = {
       method: "POST",
       asynchronous: true,
       parameters: this.params,
       evalScripts: true,
       evalJSON: true,
       divToUpdate: this.divToUpdate,
       onComplete: function (obj, Json) {
           try {
                /*
                As we call AJAX.Updater, the only code we need here is anything additional to
                the html arriving downstream.

                Debug logs here use string 'updater' as context since the "this" keyword
                here is different due to the asynchronous usage of onComplete
                */
                /* if ( top.valid(top.debug) ) { top.debug.log('updater iteration complete', 'Updater'); } */
                if ( obj.requestJSON ) {
                    json = obj.requestJSON;
                    if ( json.payload ) {
                        /* if ( top.valid(top.debug) ) { top.debug.log('have json payload', 'Updater'); } */
                        top.headeractions( json );
                    }
                }
           } catch ( updateE ) {
                if ( top.valid(top.debug) ) { top.debug.log('ERROR: ' + updateE, this); }
           }
       }
   };
   var oRequest = new Ajax.Updater(
        options.divToUpdate,
        this.url,
        options
   );
};

/*
New prototype methods.

    getSelectedOption:
        Returns a reference to the actual HTMLOptionElement selected by a user.
        Returns null if the HTMLOptionElement is unavailable.
        Usage: $('someID').getSelectedOption()
*/

if ( top.valid( Element ) && top.valid( Element.addMethods )) {
    Element.addMethods({
            getSelectedOption: function ( element ) {
                element = $( element );
                var index = element.selectedIndex;
                if ( !top.valid( element.options ) || !top.valid( index ) ) { return null; }
                return $( element.options[index] );
            }
        });
}

/**
 * @contributor Matthew Foster
 * @date                February 4th 2007
 * @purpose     This class should be considered an "abstract" it is never intended to be a concrete class, notice there is no initialize function.
 *              This class is intended to be extended from, allowing an overwritable yet base functions for processing ajax requests.  The proposed advantage to this structure
 *              Is that during debugging all of your requests are being processed in the same area, thus allowing an easier target for reviewing ajax data.  As well as handling
 *              more of what I believe to be the monotoneous routines involved in sending ajax requests.

Ajax.Application = {};

Ajax.Application.Base = Class.create();

Object.extend(Ajax.Application.Base.prototype,
              {
                  sendRequest : function(dto, cb){
                      var p = "";

                      if(typeof dto == "object")
                          p = $H(dto).toQueryString();
                      else if(typeof dto == "string")
                      p = dto;
                      else
                          throw { message : "object sent to sendRequest was invalid type.  Type = " +typeof dto };

                      new Ajax.Request(this.url,
                                       {
                                           parameters   : p,
                                           onComplete   : this.receiveRequest.bind(this, cb),
                                           onFailure    : this.ajaxFailure.bind(this),
                                           onException  : this.ajaxException.bind(this)
                                       }
                                      );
                  },
                  receiveRequest : function(cb, eAja){
                      cb(eAja);
                  },
                  ajaxFailure : function(){
                      if(typeof console == "object")
                          console.log("Ajax Request failed args = %o ", arguments);
                      else
                          alert("Ajax request has failed. Application integrity has been compromised.");
                  },
                  ajaxException : function(){
                      if(typeof console == "object")
                          console.log("ajax exception occured args = %o", arguments);
                  }
              }
             );
 */

/**
 * Author:  Matthew Foster
 * Date:    April 10th 2007

Ajax.RequestQueue = Class.create();

Object.extend(Object.extend(Ajax.RequestQueue.prototype, Ajax.Application.Base.prototype),
              {

                  initialize : function(url, options){


                      this.url = url;

                      this.options = {
                          onFinish : function(){
                              if(typeof console == "object")
                                  console.log("you should really overwrite this ya know");
                          }
                      };

                      Object.extend(this.options, options || {});

                      this.parameters = [];
                      this.flow = false;

                      this.stackCount = 0;

                  },
                  add : function(obj){
                      if(!obj instanceof Ajax.RequestQueue.DTO)
                          throw { message : "unable to add object, its not an instance of Ajax.RequestQueue.DTO" };

                      this.parameters.push(obj);

                  },
                  start : function(){
                      if(this.flow)
                          return false;

                      this.flow = true;
                      this._send();
                  },
                  _send : function(){

                      var obj = this.parameters.shift();

                      this.sendRequest(obj.parameters, obj.onComplete);
                  },
                  receiveRequest : function(cb, eAja){

                      cb(eAja);

                      if(this.parameters.length == 0){
                          this.flow = false;
                          this.options.onFinish();
                      }
                      else
                          this._send();
                  }
              }
             );

Ajax.RequestQueue.DTO = Class.create();

Object.extend(Ajax.RequestQueue.DTO.prototype,
              {
                  initialize : function(parameters, onComplete){
                      this.parameters = parameters;
                      this.onComplete = onComplete;
                  }
              }
             );
 */


/*
    Backs up a form element to a hidden input tag,
    along with appropriate details necessary to
    retrieve and re-enable the element at a later time.
*/
top.disableWithBackup = disableWithBackup = function disableWithBackup( elemId ) {
    var sourceElem = $(elemId);
    if ( ! top.valid( sourceElem ) ) return;
    sourceElem.writeAttribute("backup",elemId);
    sourceElem.writeAttribute("id", false);
    var backupId = sourceElem.identify();
    var attributes = {
        type: 'hidden',
        id: elemId,
        name: sourceElem.name || elemId,
        value: sourceElem.value || '',
        backup: backupId
    };
    var backupElem = new Element('input', attributes);
    top.newElem = sourceElem.insert({'before':backupElem});
    
    var backupElem = $( elemId );
    if (  top.valid( backupElem ) ) {
        backupElem._setValue = top.newElem.setValue;
        backupElem.setValue = function ( val ) {
            try {
                var backupElem = top.getBackupElement( this.identify() );
                if ( top.valid( backupElem ) ) {
                    var backupElem = backupElem.setValue(val);
                }
            } catch (e) {
                if (top.valid(top.debug)) {
                    top.debug.log('ERROR: ' + e, this);
                }
            }
            this._setValue(val);
        }
    }
    sourceElem.disable();    
}

/*
    Re-enables an element that was backed up using the
    disableWithBackup method
*/
top.enableFromBackup = enableFromBackup = function enableFromBackup( elemId ) {
    var sourceElem = $(elemId);
    if ( ! top.valid( sourceElem ) ) return;
    var backupElem = top.getBackupElement( elemId );
    if ( ! top.valid( backupElem ) ) return;
    sourceElem.writeAttribute("id", false);
    backupElem.writeAttribute("id", elemId);
    backupElem.writeAttribute("backup", false);
    
    var sourceVal = $F(sourceElem);
    if ( top.valid( sourceVal ) ) {
        backupElem.value = sourceVal;
    }

    sourceElem.remove();
    backupElem.enable();
}

/*
    Returns boolean whether or not a form element is currently backed
    up by the method disableWithBackup within the current DOM
*/
top.isElementBackedUp = isElementBackedUp = function isElementBackedUp( elemId ) {
    var backupElem = top.getBackupElement( elemId );
    return ( top.valid( backupElem ) ) ? true : false;
}

top.getBackupElement = getBackupElement = function getBackupElement( elemId ) {
    var sourceElem = $(elemId);
    if ( ! top.valid( sourceElem ) ) return null;
    var backupId = sourceElem.readAttribute('backup');
    if ( ! top.valid( backupId ) ) return null;
    var backupElem = $( backupId );
    return backupElem;
}
