/**
 * (c) COPYRIGHT AVIATION SOFTWARE INC. 2003-2011
 */

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();
        }
      } else {
        payload = obj;
      }
    }
    return obj;
}

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

/*
 * appendElement
 *
 * Recursively clones and then injects an arbitrary HTML DOM Element into a specified area
 *
 * arguments:
 *   destinationID   id of destination element
 *   templateID      id of element wrapping the template to use
 *   position        prototype js position type (i.e., bottom, top, etc)
 */
function appendElement( destinationID, templateID, position ) {
    var destination = $(destinationID);
    var template = $(templateID);

    if ( valid( destination ) && valid( template ) ) {
        var elem = template.cloneNode(true);
        elem.writeAttribute('id', false);
        elem.identify();
        obj = {};
        obj['' + position] = elem;
        top.newElem = destination.insert(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.capitalize = capitalize = function capitalize(str) {
    if ( typeof str != 'string' ) return '';
    return str.charAt(0).toUpperCase() + str.slice(1);
}



/*
=============================
    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, flags)
{
    this.divToUpdate = divToUpdate;
    this.interval = interval;
    this.url = url;
    this.evalJS = true;
    this.evalJSON = true;
    this.evalScripts = true;
    if(flags) {
        if(flags.evalJS && typeof flags.evalJS == 'boolean') {
            this.evalJS = flags.evalJS;
            delete flags.evalJS;
        }
        if(flags.evalJSON && typeof flags.evalJSON == 'boolean') {
            this.evalJSON = flags.evalJSON;
            delete flags.evalJSON;
        }
        if(flags.evalScripts && typeof flags.evalScripts == 'boolean') {
            this.evalScripts = flags.evalScripts;
            delete flags.evalScripts;
        }
    }
    this.params = params;
    this.executor = new PeriodicalExecuter(this.getUpdate.bind(this), this.interval);
    this.toString = toStringLog;
};

/*
    Updater.debug()
*/
top.Updater.prototype.debug = function(ls) {
  ls = ls || new LogStream();
  ls.println("Updater {");
  ls.entab();
  ls.println("divToUpdate=>" + this.divToUpdate);
  ls.println(",interval=>" + this.interval);
  ls.println(",url=>" + this.url);
  ls.println(",params=>" + this.params);
  ls.println(",executing=>" + ( this.executor.timer != null  ? 'true' : 'false' ));
  ls.detab();
  ls.println("}");
  return ls;
}

/*
    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: this.evalScripts,
       evalJSON: this.evalJSON,
       evalJS: this.evalJS,
       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 );
                    }
                }
                try{
                    top.transport = obj;
                    jr = new JSONSnippetReceiver(obj);
                    jr.process();
                } catch (e) {
                    if (top.debug && top.debug.log) {
                        top.problematicTransport = obj;
                        top.e = e;
                        top.debug.log('JSON Exception caught (for debugging, please check top.problematicTransport): ' + e, 'Updater');
                    }
                }
           } catch ( updateE ) {
                if ( top.valid(top.debug) ) { top.debug.log('ERROR: ' + updateE, this); }
           }
       }
   };
   var oRequest = new Ajax.Updater(
        options.divToUpdate,
        this.url,
        options
   );
};

top.radioGroupValue = radioGroupValue = function radioGroupValue( groupName ) {
    var val = '';
    if ( ! top.valid( groupName ) ) return val;
    var selector = 'input[name="' + groupName + '"]';
    var group = $$(selector);
    if ( group.length <= 0 ) return val;
    var elem = group.detect( function( e ) {
        var checked = false;
        try {
            checked = e.type == 'radio' && typeof e.checked == 'boolean' && e.checked;
        } catch (e) {}
        return checked;
    } );
    if (top.valid(elem)) val = elem.getValue();
    return val;
}


top.numbersonly = numbersonly = function numbersonly(myfield, e, dec)
{
    var key;
    var keychar;

    if (window.event)
        key = window.event.keyCode;
    else if (e)
    key = e.which;
    else
        return true;
    keychar = String.fromCharCode(key);

    // control keys 
    if ((key==null) || (key==0) || (key==8) ||
        (key==9) || (key==13) || (key==27) )
        return true;

    // numbers
    else if ((("0123456789").indexOf(keychar) > -1))
    return true;

    // decimal point jump
    else if (dec && (keychar == "."))
    {
        myfield.form.elements[dec].focus();
        return false;
    }
    else
        return false;
}

top.decimalsonly = decimalsonly = function decimalsonly(myfield, e)
{
    var key;
    var keychar;

    if (window.event)
        key = window.event.keyCode;
    else if (e)
    key = e.which;
    else
        return true;
    keychar = String.fromCharCode(key);

    // control keys
    if ((key==null) || (key==0) || (key==8) ||
        (key==9) || (key==13) || (key==27) )
        return true;

    // numbers
    else if ((("0123456789.").indexOf(keychar) > -1))
        return true;

    else
        return false;
}

top.alphanumericonly = alphanumericonly = function alphanumericonly(myfield, e, dec)
{
    var key;
    var keychar;

    if (window.event)
        key = window.event.keyCode;
    else if (e)
    key = e.which;
    else
        return true;
    keychar = String.fromCharCode(key);

    // control keys
    if ((key==null) || (key==0) || (key==8) ||
        (key==9) || (key==13) || (key==27) )
        return true;

    // numbers
    else if ((("0123456789").indexOf(keychar) > -1))
    return true;

    // decimal point jump
    else if (dec && (keychar == "."))
    {
        myfield.form.elements[dec].focus();
        return false;
    }
    // lowercase
    else if ((("abcdefghijklmnopqrstuvwxyz").indexOf(keychar) > -1))
    return true;
    // uppercase
    else if ((("ABCDEFGHIJKLMNOPQRSTUVWXYZ").indexOf(keychar) > -1))
    return true;
    else
        return false;
}

