/*
-------------------------------------------------------------
 eSRO Basket Site
'' Version: 3.3.3.2
'' Jan 07, 2008 
 Powered by: TopTix LTD.
-------------------------------------------------------------
 global_functions.js - functions library for genral use
 UPDATED - saved using ANSI
-------------------------------------------------------------
*/
//-----------------------------------------------------------
//class collection - for use server-side and client-side
//-----------------------------------------------------------
function Collection(strNames,strValues,strDelimeter){
    var col=new clsCollection;
    if (typeof(strNames)!='undefined' && typeof(strValues)!='undefined' && typeof(strDelimeter)!='undefined'){
        col.fill(strNames,strValues,strDelimeter);
    }
    return col
}
function clsCollection(){
    this._values=new Array(); //keyed array
    this._firstKey=null; //root of index linked list, used for iteration
    this._lastKey=null; //tail of index LL, used for addition
    this._currentNode=null; //pointer to current LL node
    this._length=0;
    if (typeof(clsCollection._inited)=='undefined'){ //init methods
        clsCollection.prototype.add=function(key,value){
            //add key to LL
            var node={key:key,prev:null,next:null}
            if (this._lastKey==null){
                this._firstKey=node;
                this._lastKey=node;
            }else{
                this._lastKey.next=node;
                node.prev=this._lastKey;
                this._lastKey=node;
            }
            //add value to hash
            this._values[key]={val:value,node:node};
            //update length
            this._length++;
        }
        
        clsCollection.prototype.insertBefore=function(key,value,before){
            if (!this._values[before]){
                this.add(key,value);
                return;
            }
            
            var node={key:key,prev:null,next:null}
            if (this._firstKey==this._values[before].node)
                this._firstKey = node;
            
            node.prev = this._values[before].node.prev;
            if (this._values[before].node.prev!=null)
                this._values[before].node.prev.next = node;
            this._values[before].node.prev = node;
            node.next = this._values[before].node;
            this._values[key]={val:value,node:node};
            this._length++;
        }
        clsCollection.prototype.getItem=function(key){
            if (this._values[key])
                return this._values[key].val;
        }
        clsCollection.prototype.exists=function(key){
            return (this._values[key]?true:false);
        }
        clsCollection.prototype.remove=function(key){
            var val,node;
            //remove from index LL
            node=this._values[key].node;
            if (node.prev){
                node.prev.next=node.next;
            }
            if (node.next){
                node.next.prev=node.prev;
            }
            if (node==this._lastKey) this._lastKey=node.prev;
            if (node==this._firstKey) this._firstKey=node.next;
            //update current
            if (this._current==node)
                this._current=node.next;
            node=null;
            //remove from hash
            val=this._values[key].val;
            this._values[key]=null;
            //update length
            this._length--;
            //return removed value
            return val;
        }
        clsCollection.prototype.getlength=function(){
            return this._length;
        }
        clsCollection.prototype.fill=function(strNames,strValues,strDelimeter){
            var arrNames=strNames.split(strDelimeter);
            var arrValues=strValues.split(strDelimeter);
            for (var i=0;i<arrNames.length && i<arrValues.length;i++)
                this.add(arrNames[i],arrValues[i]);
        }
        clsCollection.prototype.fromString=function(strValues,delimeterM,delimeterP){
      
            if (typeof(delimeterM)=='undefined') delimeterM=","
            if (typeof(delimeterP)=='undefined') delimeterP=":"
            var arrItems = strValues.split(delimeterM);
            var arrItem = null;
            for (var i=0;i<arrItems.length;i++){
                arrItem = arrItems[i].split(delimeterP);
                this.add(arrItem[0],arrItem[1]);
            }
        }
        //ELIR
        clsCollection.prototype.fromStringEx=function(strValues,delimeterM,delimeterP)
        {
            if (typeof(delimeterM)=='undefined') delimeterM=","
            if (typeof(delimeterP)=='undefined') delimeterP=":"
            var arrItems = strValues.split(delimeterM);
            var arrItem = null;
            var aa =new String()
            
            for (var i=0;i<arrItems.length;i++)
            {
                arrItem = arrItems[i].split(delimeterP);
                var strToRemove = "";
                
                strToRemove += arrItem[0] + delimeterP
            
                this.add(arrItem[0],arrItems[i].replace(strToRemove, ""));
            }
        }
        //END ELIR
        clsCollection.prototype.moveNext=function(){
            if (this._current)
                this._current=this._current.next;
            else
                this._current=this._firstKey;
            if (this._current)
                return this._current.key;
            return;
        }
        clsCollection.prototype.movePrevious=function(){
            if (this._current)
                this._current=this._current.prev;
            else
                this._current=this._lastKey;
            if (this._current)
                return this._current.key;
            return;
        }
        clsCollection.prototype.reset=function(){
            this._current=null;
        }
         clsCollection.prototype.moveFirst=function(){
            this._current=this._firstKey;
        }
        clsCollection.prototype.moveLast=function(){
            this._current=this._lastKey;
        }
        clsCollection.prototype.moveToKey=function(key){
            if (this._values[key])
                this._current=this._values[key].node;
        }
        clsCollection.prototype.getCurrentKey=function(){
                if (this._current) return this._current.key;
        }
        clsCollection.prototype.toString=function(delimeterM,delimeterP){
            if (typeof(delimeterM)=='undefined') delimeterM=","
            if (typeof(delimeterP)=='undefined') delimeterP=":"
            var str='';
            for (var cur=this._firstKey;cur;cur=cur.next){
                str+=cur.key+delimeterP+this._values[cur.key].val;
                if (cur.next) str+=delimeterM;
            }
            return str;
        }
        clsCollection._inited=true;
    }
}
//-----------------------------------------------------------
//general string functions
//-----------------------------------------------------------
function escapeChars(string,chars){
    var rx,helper=new clsEscapeHelper(),e;

    if (typeof (string) == "undefined" || string==null) {
        return string;
    } if (typeof(chars)=="string"){ //build the regex by using another regex
        chars=chars.toString()
        var stuffingHelper=new clsStuffingHelper("\\");
        var rx2=/([\\\(\)\[\]\{\}\|\\^\$\*\+\?\.])/g;
        try{
            chars=chars.replace(rx2,stuffingHelper.stuff); //newer versions
        }catch(e){
            if (e!="dynamic replace not supported") throw e;
            
            while (rx2.test(chars)) chars=chars.replace(RegExp.$1,"\\"+RegExp.$1); //older versions
        }
        rx=new RegExp("(["+chars+"])","g")
    }else //if (RegExp.prototype.isPrototypeOf(chars)) - otherwise will be converted to string on newer versions
       rx=chars;
        
    try{
        string=string.replace(rx,helper.escape); //newer versions
    }catch(e){
        if (e!="dynamic replace not supported") throw e;
        while (rx.test(string)) string=string.replace(RegExp.$1,escape(RegExp.$1)); //older versions
    }
    return string;
}
function escapeLiteral(string){
    return escapeChars(string,/([\n\r\f\v\t'"])/g)
}
function JSLiteral(string){
    var rx=/([\n\b\f\r\t\\"'])/g;
    var helper=new clsJSEscapeHelper();
    if (typeof (string) == "undefined") return "undefined";
    try{
        string=string.replace(rx,helper.escape);
    }catch(e){//older versions
        if (e!="dynamic replace not supported") throw e;
        
        if (rx.test(string)){ 
            string=string.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/'/g,"\\'");
            string=string.replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\f/,"\\f").replace(/\v/g,"\\v").replace(/\t/g,"\\t");
        }
    }
    return "\""+string+"\"";
}
function clsJSEscapeHelper(){
    if (typeof(clsJSEscapeHelper._inited)=='undefined'){ //init methods
        clsJSEscapeHelper.prototype.skpChars = { "\n": "\\n", "\t": "\\t", "\b": "\\b", "\f": "\\f", "\r": "\\r", "\\": "\\\\", "\"": "\\\"", "\'": "\\'" };
    
        clsJSEscapeHelper.prototype.escape=function(match){
            return clsJSEscapeHelper.prototype.skpChars[match];
        }
        clsJSEscapeHelper.prototype.escape.toString=function(){throw "dynamic replace not supported"};
        clsJSEscapeHelper._inited=true;
    }
}
function clsEscapeHelper(){
    if (typeof(clsEscapeHelper._inited)=='undefined'){ //init methods
        clsEscapeHelper.prototype.escape=function(match){
            return escape(match);
        }
        clsEscapeHelper.prototype.escape.toString=function(){throw "dynamic replace not supported"};
        clsEscapeHelper._inited=true;
    }
}
function clsStuffingHelper(stuffingChars){
    this.stuffingChars=stuffingChars;
    if (typeof(clsStuffingHelper._inited)=='undefined'){ //init methods
        clsStuffingHelper.prototype.stuff=function(match){
            return this.stuffingChars+match;
        }
        clsStuffingHelper.prototype.stuff.toString=function(){throw "dynamic replace not supported"};
        clsStuffingHelper._inited=true;
    }
}
function JSONDeserialize(str) {
    var result =!(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                    str.replace(/"(\\.|[^"\\])*"/g, ''))
                    ) &&
                eval('(' + str + ')');
    return result;
}
function JSONSerialize(v, serializeObjectMethods) {
    var s;
    if (typeof (v) == "undefined") {
        return "undefined";
    } else if (v == null) {
        return "null"
    } else
    //the constructor can come from other window, so checking by name is necessary 
    if (v.constructor.getName()=="Array") {
        s = "["
        for (var i = 0; i < v.length; i++)
            s += (i > 0 ? "," : "") + JSONSerialize(v[i]);
        return s + "]";
    } else if (v.constructor.getName()=="Object") {
        var s = "{", i = 0;
        for (member in v) {
            var val = v[member];
            if (typeof(val)!="undefined" && !(!serializeObjectMethods && val.constructor.getName()=="Function"))
                s += (i++ > 0 ? "," : "") + member + ":" + JSONSerialize(v[member])
        }
        return s + "}";
    } else if (v.constructor.getName()=="String")
        return JSLiteral(v);
    else
        return v.toString();
}
function Exception(number, source, descriptionFormat) {
    this.number = number;
    this.source = source;

    if (arguments.length > 2) {
        var args = arguments;
        descriptionFormat = descriptionFormat.replace(/{(\d)}/g, function(match, n) { return args[parseInt(n, 10) + 2]; });
    }
    this.description = descriptionFormat;

    var func, callStack = new Array();
    func = arguments.callee.caller;
    while (func) {
        callStack.push(func);
        func = func.caller;
    }
    if (callStack.length > 0)
        this.callStack = callStack;

    this.toString = function() {
        var str = "Description: " + this.description
						+ "\nNumber: " + this.number;
        if (this.callStack) {
            var funcNames = new Array(), funcName;
            var regex = /.*function\s*([\w\d]+)/;
            for (var i = 0; i < this.callStack.length; i++) {
                funcName = regex.exec(this.callStack[i]);
                if (funcName)
                    funcNames[i] = funcName[1];
                else
                    funcNames[i] = "anonymous";
            }
            str += "\nCall stack: " + funcNames.join('->');
        }
        return str;
    }

}
String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d)}/g, function(match, n) { return args[parseInt(n, 10)]; })
};
String.prototype.trim = function() {
    return /^\s*(.*?)\s*$/.exec(this)[1];
};
Function.prototype.getName = function() {
    return /.*function\s*([\w\d]+)/.exec(this)[1];
}
function getJSObject(obj) {
    obj.item = function(key) { return this[key]; };
    return obj;
}
function getJSArrItem(arr, index) {
    return arr[index];
}