/*******************
 * Handy Functions *
 *******************/
function include(js){
    var remote = document.createElement('script');
    remote.setAttribute('src', js);
    try{
        window.document.getElementsByTagName("head")[0].appendChild(remote);
    }catch(er){
        window.document.body.appendChild(remote);
    }
};//END FUNCTION include
function NewWindow(mypage, myname, w, h, scrll, pos){
    var win=null;
    if(pos=="random"){
        LeftPosition=(screen.width)?Math.floor(Math.random()*(screen.width-w)):100;
        TopPosition=(screen.height)?Math.floor(Math.random()*((screen.height-h)-75)):100;
    }
    if(pos=="center"){
        LeftPosition=(screen.width)?(screen.width-w)/2:100;
        TopPosition=(screen.height)?(screen.height-h)/2:100;
    }else if((pos!="center" && pos!="random") || pos==null){
        LeftPosition=0;
        TopPosition=20
    }
    settings='width='+w+',height='+h+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scrll+',location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=no';
    win=window.open(mypage,myname,settings);
};//END FUNCTION NewWindow
function addEvent( obj, type, fn ){
    if( obj.attachEvent ){
        obj['e'+type+fn] = fn;
        obj[type+fn] = function(){
            obj['e'+type+fn]( window.event );
        }
        obj.attachEvent( 'on'+type, obj[type+fn] );
    } else {
        obj.addEventListener( type, fn, false );
    }
    return true;
};//END FUNCTION addEvent
function removeEvent( obj, type, fn ){
    if( obj.detachEvent ){
        obj.detachEvent( 'on'+type, obj[type+fn] );
        obj[type+fn] = null;
    } else {
        obj.removeEventListener( type, fn, false );
    }
    return true;
};//END FUNCTION removeEvent
function numberOnly(evt){
    var keyCode = evt.which ? evt.which : evt.keyCode;
    if(keyCode == 9 || keyCode == 8){
        return true;
    }else if (keyCode == 46 || (keyCode >= 48 && keyCode <= 57)){
        if (keyCode == 46){
            var srcEl = evt.srcElement ? evt.srcElement : evt.target;
            if (srcEl.value.indexOf(".") > -1 ){
                return false;
            }
        }
        return true;
    }else{
        return false;
    }
};
function getUrlParameters(){
    if(!document.location.href.istr("?")){
        return [];
    }
    var queryString = document.location.href.split("?")[1];
    var pairs = queryString.split("&");
    var parameters = new Array();
    for(i=0; i<pairs.length; i++){
        var t = pairs[i].split("=");
        parameters[t[0]]=t[1];
    }
    return parameters;
};//END FUNCTION getUrlParameters

 /*****************
 * Array methods *
 *****************/
    Array.prototype.implode = function(glue){
        return ( ( this instanceof Array ) ? this.join ( glue ) : this );
    };//END FUNCTION Array.implode
    Array.prototype.print_r = function (return_val) {
        var output = "", pad_char = " ", pad_val = 4;
        var formatArray = function (obj, cur_depth, pad_val, pad_char) {
            if (cur_depth > 0) {
                cur_depth++;
            }
            var base_pad = repeat_char(pad_val*cur_depth, pad_char);
            var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
            var str = "";
            if (typeof obj === 'object' && obj !== null && obj.constructor && obj.constructor.name !== 'PHPJS_Resource') {
                str += "Array\n" + base_pad + "(\n";
                for (var key in obj) {
                    if(key!="print_r" && key!="implode"){
                        if (obj[key] instanceof Array) {
                            str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char);
                        } else {
                            str += thick_pad + "["+key+"] => " + obj[key] + "\n";
                        }
                    }
                }
                str += base_pad + ")\n";
            } else if(obj == null || obj == undefined) {
                str = '';
            } else { // for our "resource" class
                str = obj.toString();
            }
            return str;
        };
        var repeat_char = function (len, pad_char) {
            var str = "";
            for(var i=0; i < len; i++) {
                str += pad_char;
            }
            return str;
        };
        output = formatArray(this, 0, pad_val, pad_char);
        if (return_val !== true) {
            if (document.body) {
                echo(output);
            }
            else {
                try {
                    XULDocument;
                    echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">'+output+'</pre>');
                }
                catch(e) {
                    echo(output);
                }
            }
            return true;
        } else {
            return output;
        }
    };//END FUNCTION Array.print_r
    Array.prototype.http_build_query = function (){
        var list = []
        for(key in this){
            if(typeof(this[key])!="function"){
                list[list.length] = key+"="+this[key];
            }
        }
        return list.implode("&");
    };//END FUNCITON Array.http_build_query
    Array.prototype.keys = function(){
        var keys = new Array();
        for(key in this){
            keys[keys.length] = key;
        }
        return keys;
    };//END FUNCTION Arra.keys
    Array.prototype.values = function(){
        var values = new Array();
        for(key in this){
            values[values.length] = this[key];
        }
        return values;
    };//END FUNCTION Arra.values
    Array.prototype.remove = function(index){
        var val = this[index];
        delete this[index];
        this.reindex();
        return  val;
    };//END FUNCTION Array.remove
    Array.prototype.reindex = function(){
        var tmp = new Array();
        for(key in this){
            tmp[key] = this[key];
        }
        for(key in tmp){
            this[key] = tmp[key];
        }
        while(this.length > tmp.length){
            this.pop();
        }
    };//END FUNCTION Array.reindex

 /******************
 * String methods *
 ******************/
    String.prototype.explode = function (delimiter, limit){
        var emptyArray = {
            0 : ''
        };
        if (arguments.length < 2 || typeof arguments[0] == 'undefined' || typeof arguments[1] == 'undefined' ){
            return null;
        }
        if ( delimiter === '' || delimiter === false || delimiter === null ){
            return false;
        }
        if( typeof delimiter == 'function' || typeof delimiter == 'object' || typeof this == 'function'){
            return emptyArray;
        }
        if( delimiter === true ){
            delimiter = '1';
        }
        if (!limit){
            return this.toString().split(delimiter.toString());
        }else{
            var splitted = this.toString().split(delimiter.toString());
            var partA = splitted.splice(0, limit - 1);
            var partB = splitted.join(delimiter.toString());
            partA.push(partB);
            return partA;
        }
    };//END FUNCTION String.explode
    String.prototype.trim = function(){
        return this.replace(/^\s+|\s+$/g, '');
    };//END FUNCTION String.trim
    String.prototype.toFloat = function(){
        try{
            var float = parseFloat(this);
        }catch(er){
            return this;
        }
        return float;
    };//END FUNCTION String.toFloat
    String.prototype.ucwords = function (){
        return this.toLowerCase().replace(/\w+/g, function(s){
            return s.charAt(0).toUpperCase() + s.substr(1);
        });
    };//END FUNCTION String.ucwords
    String.prototype.istr = function(needle, bool){
        var pos = 0;
        pos = this.toLowerCase().indexOf( (needle+'').toLowerCase() );
        if (pos == -1){
            return false;
        }else{
            if (bool) {
                return this.substr( 0, pos );
            }else{
                return this.slice( pos );
            }
        }
    };//END FUNCTION istr
    String.prototype.urlencode = function(){
        // URL-encodes String
        //
        // version: 910.813
        // discuss at: http://phpjs.org/functions/urlencode
        // +   original by: Philip Peterson
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: AJ
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: travc
        // +      input by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: Lars Fischer
        // +      input by: Ratheous
        // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Joris
        // %          note 1: This reflects PHP 5.3/6.0+ behavior
        // *     example 1: urlencode('Kevin van Zonneveld!');
        // *     returns 1: 'Kevin+van+Zonneveld%21'
        // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
        // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
        // *     example 3: urlencode('http://www.google.nl/search?q=php.js&;ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
        // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
        var hexStr = function (dec) {
            return '%' + (dec < 16 ? '0' : '') + dec.toString(16).toUpperCase();
        };

        var ret = '',
        unreserved = /[\w.-]/; // A-Za-z0-9_.- // Tilde is not here for historical reasons; to preserve it, use rawurlencode instead

        for (var i = 0, dl = this.length; i < dl; i++) {
            var ch = this.charAt(i);
            if (unreserved.test(ch)) {
                ret += ch;
            }
            else {
                var code = this.charCodeAt(i);
                if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters); https://developer.mozilla.org/index.php?title=en/Core_JavaScript_1.5_Reference/Global_Objects/String/charCodeAt
                    ret += ((code - 0xD800) * 0x400) + (this.charCodeAt(i+1) - 0xDC00) + 0x10000;
                    i++; // skip the next one as we just retrieved it as a low surrogate
                }
                // We never come across a low surrogate because we skip them, unless invalid
                // Reserved assumed to be in UTF-8, as in PHP
                else if (code === 32) {
                    ret += '+'; // %20 in rawurlencode
                }
                else if (code < 128) { // 1 byte
                    ret += hexStr(code);
                }
                else if (code >= 128 && code < 2048) { // 2 bytes
                    ret += hexStr((code >> 6) | 0xC0);
                    ret += hexStr((code & 0x3F) | 0x80);
                }
                else if (code >= 2048) { // 3 bytes (code < 65536)
                    ret += hexStr((code >> 12) | 0xE0);
                    ret += hexStr(((code >> 6) & 0x3F) | 0x80);
                    ret += hexStr((code & 0x3F) | 0x80);
                }
            }
        }
        return ret;
    };//END FUNCTION urlencode

/***************************
 * Element Collector Class *
 ***************************/
var Collector = Class.create({
    initialize: function(name){
        this.collection = [];
        this.idPrefix = name;
    },
    getIndex: function (element){
        for(key in this.collection){
            if(element.id == this.collection[key].id){
                return key;
            }
        }
    },
    add: function(element, index){
        if(!index){
            index = this.collection.length;
        }
        element.setAttribute('id', this.idPrefix + "_" + index);
        this.collection.push(element);
    },
    remove:  function (element, removeFromDom){
        if(removeFromDom){
            var parentNode = element.parentNode;
            parentNode.removeChild(element);
        }
        var index = this.getIndex(element);
        delete this.collection[index];
        this.collection.reindex();
    },
    get: function (index){
        if(!index){
            return this.collection;
        }else{
            return this.collection[index];
        }
    },
    set: function (index, element){
        if(index){
            this.collection[index] = element;
        }
    },
    removeAfter: function(element, removeFromDom){
        var index = parseInt(this.getIndex(element))+1;
        this.truncate(index, removeFromDom);
    },
    removeBefore: function(element, removeFromDom){
        for(key in this.collection){
            if(this.collection[key]!=element){
                this.remove(this.collection[key],removeFromDom);
            }else{
                break;
            }
        }
    },
    truncate: function (length, removeFromDom){
        while(this.collection.length > length){
            var element = this.collection.pop();
            if(removeFromDom){
                var parentNode = element.parentNode;
                parentNode.removeChild(element);
            }
        }
        this.collection.reindex();
    },
    clear: function(removeFromDom){
        this.truncate(0,removeFromDom);
    }
});

/**********************
 * AJAX Request Class *
 **********************/
var ajaxRequest = Class.create({
    initialize: function(servlet){
        this.servlet = servlet;
        this.parameters = [];
        this.postVars = [];
        this.handler = false;
        if (window.XMLHttpRequest) {
            this.httpRequest = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
        }
    },
    addParameter: function(name, value){
        this.parameters[name]=value;
    },
    addPostVar: function(name, value){
        postVars[name]=value;
    },
    setSeed: function(){
        this.addParameter("seed",Math.random());
    },
    execute: function(){
        if(!this.handler){
            return false;
        }
        this.setSeed();
        var request_url = this.servlet + "?" + this.parameters.http_build_query();
        if($("request_url")){
            $("request_url").innerHTML = "";
            var myLink = document.createElement("a");
            myLink.setAttribute("href", request_url);
            myLink.setAttribute("target", "_blank");
            myLink.innerHTML = "request_url = " + request_url;
            $("request_url").appendChild(myLink);
        }
        this.httpRequest.onreadystatechange = this.handler;
        if(this.postVars.length>0){
            var postData = this.postVars.http_build_query();
            this.httpRequest.open('POST', request_url, true);
            this.httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            this.httpRequest.setRequestHeader("Content-length", postData.length);
            this.httpRequest.setRequestHeader("Connection", "close");
            this.httpRequest.send(postData);
        }else{
            this.httpRequest.open('GET', request_url, true);
            this.httpRequest.send(null);
        }
    },
    status: function(){
        return this.httpRequest.status;
    },
    readyState: function(){
        return this.httpRequest.readyState;
    },
    responseText: function(){
        return this.httpRequest.responseText;
    },
    responseXML: function(){
        return this.httpRequest.responseXML;
    }
});
