function _lib () {
	this.wroot = 'http://' + location.hostname + '/';
	this.DEBUG = false;
	this.urlencode = function (str) {
		var str = str.toString();
		var arr = str.split(" ");
		var a;
		for (a in arr) arr[a] = encodeURIComponent(arr[a]);
		return arr.join("+");
	}
	this.buildQuery = function (qr) {
		var a, b, s;
		var arr = new Array(), arr2;
		for (a in qr) {
			if (typeof qr[a] == "object" && qr[a] !== null) {
				arr2 = new Array();
				for (b in qr[a]) arr2[arr2.length] = encodeURIComponent(a + "[]") + 
					"=" + encodeURIComponent(qr[a][b]);
				arr[arr.length] = arr2.join("&");
			}
			else arr[arr.length] = encodeURIComponent(a) + "=" + encodeURIComponent(qr[a]);
		}
		return arr.join("&");
	}
	this.buildQueryURL = function (qr) {
		var a, b, s;
		var arr = new Array(), arr2;
		for (a in qr) {
			if (typeof qr[a] == "object" && qr[a] !== null) {
				arr2 = new Array();
				for (b in qr[a]) arr2[arr2.length] = this.urlencode(a + "[]") + 
					"=" + this.urlencode(qr[a][b]);
				arr[arr.length] = arr2.join("&");
			}
			else arr[arr.length] = this.urlencode(a) + "=" + this.urlencode(qr[a]);
		}
		return arr.join("&");
	}
	this.parseInt = function (s, radix) {
		if (typeof(s) != "string") s = s.toString();
        s = s.trim(" ").split("");
		var s1 = "", found = false;
		var sign = 1, a;
		
		for (a = 0; a < s.length; a++) {
			if (a == 0) {
				if (s[a] == "+") {
					sign = 1;
					a++;
				}
				else if (s[a] == "-") {
					sign = -1;
					a++;
				}
			} 
			if (!this.isNaN(s[a])) {
				s1 += s[a];
				found = true;
			}
			else break;
		}
		if (!found) return NaN;
						
		var ret2 = 0;
		radix = radix || 10;		
		var s = s1.split("");
		
		for (a = 0; a < s.length; a++) {
			ret2 += s[a] * this.pow(radix, s.length - a - 1);
		}
		return ret2 * sign;
	}
	this.pow = function (num, power) {	
		if (power == 0) return 1;
		var ret1 = 1, a;
		for (a = 0; a < power; a++) ret1 *= num;
		return ret1;
	}
	this.genUID = function (num, minA, minN) {
	    var uid, a;
		uid = "";
	    if ( num <=0 || minA < 0 || minN < 0 || ((minA + minN) > num) ) return null;
		 
	    for (a = 1; a <= num; a++) {
	    	if (a <= minA) uid += this.chr(this.ord("A") + Math.rand(1, 26) - 1);
	    	else if (a <= (minA + minN)) uid += Math.rand(1, 10) - 1;
			else uid += Math.rand(0, 1) == 0 ? this.chr(this.ord("A") + 
				Math.rand(1, 26) - 1) : Math.rand(1, 10) - 1;
	    }
	    return uid.shuffle();
	}
	this.ord = function (c) {
		if (c.length > 0) return c.charCodeAt(0);
		else return null;
	}
	this.chr = function (ascii) {
		return String.fromCharCode(ascii);
	}
    this.toPHP = function (arr, op) {
        var i, first = false, pos, key, data, cnt = 0;
        //var phpIntMax = 2147483647;
        
        if (typeof op == "undefined") {
            first = true;
            op = new Array();
        }
        //a:8:{i:5;a:2:{i:0;s:3:"Dip";i:1;s:2:"Fh";}i:6;i:56;i:7;N;i:8;b:0;i:9;b:1;i:10;d:78.45;i:11;d:-67.34;s:3:"sex";s:2:"ML";}
        pos = op.length;
        op.push("");
        
        for (i in arr) {
            if (typeof(arr[i]) == "function") continue;
            cnt++;
            
            //Keys
            key = typeof i == 'string' ? i : ('' + i);
            op.push('s:' + key.length + ':"' + key + '";'); //this.addSlashes(i)
            
            if (typeof(arr[i]) == "object" && arr[i] !== null) this.toPHP(arr[i], op);
            else {
                if (typeof(arr[i]) == "boolean") op.push(arr[i] ? "b:1;" : "b:0;");
                else if (typeof arr[i] == 'undefined') op.push('N;');
                else if (arr[i] === null) op.push('N;');
                else if (typeof(arr[i]) == "number" &&
                     (arr[i] == Number.NEGATIVE_INFINITY || arr[i] == Number.POSITIVE_INFINITY || this.isNaN(arr[i]))) op.push('N;');
                else {
                    data = typeof arr[i] == 'string' ? arr[i] : ('' + arr[i]);
                    op.push('s:' + data.length + ':"' + data + '";'); //this.addSlashes(i)
                }
            }
        }
        
        op[pos] = 'a:' + cnt + ':{';
        op.push("}");
        //
        if (first) {
            return op.join("");
        }
    }
    this.addSlashes = function (s) {
        var ret, regex1 = /(\\{1})/gi, regex2 = /(\${1})/gi, regex3 = /("{1})/gi, regex4 = /('{1})/gi;
        ret = s;
        if (typeof(ret) != "string") ret = ret.toString();
        /*ret = ret.split("\\").join("\\\\");
        ret = ret.split("$").join("\\$");
        ret = ret.split("\"").join("\\\"");
        //ret = ret.split("'").join("\\'");*/

        ret = ret.replace(regex1, "\\\\");
        ret = ret.replace(regex2, "\\$");
        ret = ret.replace(regex3, "\\\"");
        //ret = ret.replace(regex4, "\\'");
        
        return ret;
    }
    this.objLength = function (obj) {
        var cnt = 0, i;
        for (i in obj) if (typeof(obj[i]) != "function") cnt++;
        return cnt;
    }
    this.objString = function (o) {
        var i, str = "";
        for (i in o) {
				try {
            str += i + " => " + ((o[i] !== null && typeof o[i] == "object") ? "{\n" + this.objString(o[i]) +
                "}" : o[i]) + "\n";
				}
				catch (e) { }
        }
        return str;
    }
    this.array2Obj = function (arr) {
        var i, o = new Object();
        for (i in arr) o[i] = arr[i];
        return o;
    }
    this.objConcat = function (obj1, obj2 /*,...*/) {
        var i, len, itr, obj, o = new Object();
        len = arguments.length;
        for (itr = 0; itr < len; itr++) {
            obj = arguments[itr];
            if (typeof obj != "object" || obj === null) continue;
            for (i in obj) o[i] = obj[i];
        }
        return o;
    }
    this.uniqueObject = function (obj) {
        var temp = new Object(), ret = new Object(), i;
        for (i in obj) {
            if (typeof temp[obj[i]] == 'undefined') { //use this to manage indexes.
                temp[obj[i]] = i;
                ret[i] = obj[i];
            }
        }
        return ret;
    }
    this.uniqueArray = function (arr) {
        var temp = new Object(), ret = new Array(), i;
        for (i in arr) {
            if (typeof temp[arr[i]] == 'undefined') { //use this to manage indexes.
                temp[arr[i]] = i;
                ret[i] = arr[i];
            }
        }
        return ret;
    }
    this.getAsNumberArray = function (val) {
        var ret;
        if (typeof val != 'object' || val === null) {
			ret = new Array();
			if (val || val === 0) ret[0] = val;
		}
		else ret = this.objConcat(val);
		return ret;
    }
    this.arrayFlip = function (arr) {
        var ret = new Object(), i;
        for (i in arr) ret[arr[i]] = arr[i];
        return ret;
    }
	this.parseTemplate = function (template) {
		var regex = /(\{)(\$)([^ \f\n\r\t\v\}]+)(\})/gi, i, variable, tmpPattern, pattern;
		tmpPattern = template.match(regex);
		pattern = new Object();
		
		regex = /([^ \f\n\r\t\v\.]+)(\.*)/gi;
		for (i = 0; i < tmpPattern.length; i++) {
			if (typeof pattern[tmpPattern[i]] != 'undefined') continue;
			variable = tmpPattern[i].substring(2, tmpPattern[i].length - 1);
			variable = variable.replace(regex, '[\'$1\']');
			pattern[tmpPattern[i]] = variable;
		}
		return pattern;
	}    	
    this.formatItem = function (dataobject, template, pattern) {
    	var store, output, i;
    	store = new Object(); 			
    	output = template;
    	pattern = pattern || this.parseTemplate(template);
    	
    	for (i in pattern) {
    		if (typeof store[i] != 'undefined') continue;
    		try {
    			eval('store[i] = dataobject' + pattern[i] + ';');
    		}
    		catch (e) {}
    	}	
    	
    	for (i in store) {
    		output = output.split(i);
    		output = output.join(store[i]);
    	}		
    	return output;
    }
    this.isIE = function () {
        return navigator.appName == 'Microsoft Internet Explorer';
    }
    this.isOpera = function () {
        return navigator.userAgent.toLowerCase().indexOf("opera") != -1;
    }
    this.isNaN = function (s) {
        if (isNaN(s)) return true;
        if (typeof(s) != "string") s = s.toString();
        return s.trim().length == 0;
    }
    this.copyForm = function (fi) {
        var a, o, obj = new Object();
        for (a = 0; a < fi.length; a++) {
            o = fi[a];
            if (!o.id || o.id == "") continue;
            if (o.nodeName.toUpperCase() == "INPUT" &&
                (o.type.toUpperCase() == "RADIO" || o.type.toUpperCase() == "CHECKBOX") ) {
                if (o.checked) obj[o.id] = o.value;
            }
            else obj[o.id] = o.value;
        }
        return obj;
    }
    this.toNames = function (f) {
        var a, fi = f.elements;
        for (a = 0; a < fi.length; a++) if (fi[a].id.length > 0) fi[a].name = fi[a].id;
    }
    this.PHPErr = function (o) {
        var er = new FormErr();
        er.ers = o.ers;
        er.elts = o.elts;
        return er;
    }
    this.createGlobalVarName = function (Obj) {
        if ($GlobalInstances.reuse_pos.length > 0) {
            Obj._varpos = $GlobalInstances.reuse_pos[$GlobalInstances.reuse_pos.length - 1];
            $GlobalInstances.reuse_pos = $GlobalInstances.reuse_pos.slice(0, -1);
        }
        else {
            Obj._varpos = $GlobalInstances.instances.length;	    	
        }
        Obj._varname = "$GlobalInstances.instances[" + Obj._varpos + "]";
        $GlobalInstances.instances[Obj._varpos] = Obj;
    }
    this.deleteGlobalVarName = function (Obj) {
        if (typeof Obj._varpos != "undefined" && Obj._varpos) {
	       delete $GlobalInstances.instances[Obj._varpos];
           $GlobalInstances.reuse_pos[$GlobalInstances.reuse_pos.length] = Obj._varpos;
           Obj._varpos = Obj._varname = null;
        }
    }
    this.createCallBack = function (Obj, category, callback, callbackobj) {
        var funcname = "", objname = "";
		var use, i, func, useobj, cb, cbIndex;
		
		if (typeof callback == "function") func = true;
        else if (typeof callback == "string") {
    	    func = false;
    	
    	    if (typeof callbackobj == "object" && callbackobj !== null) useobj = true;
            else if (typeof callbackobj == "undefined" ||  callbackobj === null) useobj = false;
            else return;
        }
        else return;
        
		if (!this.isCallBackCategory(Obj, category)) Obj._cbKinds[category] = new Array();
		
		for (i in Obj._cbKinds[category]) {
			cb = Obj._cbKinds[category][i];
			if (cb.callback === callback) {
				if (func) return i;
				else {
					if (useobj && callbackobj === cb.callbackobj) return i;
					else if (!useobj && !callbackobj && !cb.callbackobj) return i;
				}
			}
		}
		
		if (Obj._cbData.length == 0) Obj._cbData.push(null);		
		
		use = {index: Obj._cbData.length, callback: callback, callbackobj: callbackobj, category: category};
		Obj._cbData.push(use);
		
		cbIndex = use.index
		Obj._cbKinds[category][cbIndex] = use;
		
    	if (func) {
    	   funcname = Obj._varname + "._cbData[" + cbIndex + "].callback";
        }
        else {
    	    funcname = callback;
    	
    	    if (useobj) objname = Obj._varname + "._cbData[" + cbIndex + "]" + ".callbackobj.";
            else objname = "";
        }
		
		use.toString = new Function('', 'return ("' + objname + funcname + '");');
		
        return use.index;
    }
	this.isCallBackCategory = function (Obj, category) {
		return typeof Obj._cbKinds[category] != 'undefined';
	}
	this.callBacks = function (Obj, category) {
		return typeof Obj._cbKinds[category] != 'undefined' ? Obj._cbKinds[category] : new Array();
	}
    this.deleteCallBack = function (Obj, index) {
        var i;
		try {
			delete Obj._cbKinds[Obj._cbData[index].category][index];
    	    delete Obj._cbData[index];
		}
		catch (e) { try { delete Obj._cbData[index]; } catch (e) { } }
    }
    this.deleteCallBacks = function (Obj) {
        var i;
        for (i in Obj._cbData) try { delete Obj._cbData[i]; } catch (e) { }
		for (i in Obj._cbKinds) try { delete Obj._cbKinds[i]; } catch (e) { }
        Obj._cbData = new Array();
		Obj._cbKinds = new Object();
    }  
    this.callSingleCallBack = function (Obj, index/*, args*/) {
        var result, args = arguments, i, str, argsstr = '';
		for (i = 2; i < args.length; i++) argsstr += 'args[' + i + ']' + (i == (args.length - 1) ? '' : ',');
		
		str = 'result = ' + Obj._cbData[index] + '(' + argsstr + ');';
		try { eval(str); } catch (e) { }
		return result;
    }  
    this.callMultipleCallBack = function (Obj, category/*, args*/) {
		var result = new Array(), index, i, str, args = arguments, argsstr = '';
		if (!this.isCallBackCategory(Obj, category)) return result;
		
		for (i = 2; i < args.length; i++) argsstr += 'args[' + i + ']' + (i == (args.length - 1) ? '' : ',');
		
		for (index in Obj._cbKinds[category]) {
			str = 'result[' + index + '] = ' + Obj._cbData[index] + '(' + argsstr + ');';
			try { eval(str); } catch (e) { }
		}
		return result;
    }    	
	this.LPad = function (val, len, padstr) {	
		var a = "";
		padstr = typeof padstr == "undefined" ? "0" : padstr;
		for (i = val.toString().length; i < len; i++) a += padstr;
		a += val;
		return a;
	}
	this.instanceOf = function (object, constructor) {
        while (object != null) {
            if (object == constructor.prototype) return true;
            else object = object.__proto__;
        }
        return false;
    }
    this.addIcons = function (iconArray, args) { //set icons
    	var i, oImg, oIcon, oParent;
    	
    	oParent = document.createElement("DIV");
    	oIcon = document.createElement("IMG");
    	oParent.appendChild(oIcon);
    		
    	for (i in args) {
    		if ($Lib.isNaN(i)) continue;
    	
    		if (args[i]) {
    			oImg = new Image;
    			oImg.src = args[i]; //PreLoad				
    			oIcon.src = oImg.src;			
    			iconArray[i] = oParent.innerHTML;
    		}
    		else if (typeof iconArray[i] == 'undefined') {
    			iconArray[i] = "";
    		}
    	}
    }	
	this.getIcon = function (iconArray, item) {
		var type = 0;
		if (item.subtype > 0 && typeof iconArray[item.subtype] != 'undefined') type = item.subtype;
		else if (typeof iconArray[item.type] != 'undefined') type = item.type;
		return type > 0 ? iconArray[type] : "[Icon]";
	}
    this.addEvent = function (obj, event, handler) {
    	if (obj.attachEvent) obj.attachEvent("on" + event, handler);
    	else obj.addEventListener(event, handler, false);
    }
}
String.prototype.trim = function (removeChar) {
	var returnString = this.toString(); //inputString;
	if (!removeChar) removeChar = " ";		
	while(''+returnString.charAt(0)==removeChar)
		returnString=returnString.substring(1,returnString.length);		
	while(''+returnString.charAt(returnString.length-1)==removeChar)
		returnString=returnString.substring(0,returnString.length-1);
	return returnString;

}
String.prototype.parseInt = function (radix) {
	return $Lib.parseInt(this.toString(), radix);
};
String.repeat = function (sc, mult) {
	var s = "", a;
	for (a = 0; a < mult; a++) s += sc;
	return s;
};
Math.rand = function (min, max) {
	if (min > max) return null;
	else if (min == max) return 0;
	else return Math.round(Math.random() * (max - min)) + min;
}
String.prototype.shuffle = function () {
	var str = "", i, s = this.toString();
	
	while (s.length > 0) {
		i = Math.rand(0, s.length - 1);
		str += s.charAt(i);
		s = s.substring(0, i) + s.substring(i + 1, s.length);
	}
	return str;	
}

$GlobalInstances = {instances: new Array(), reuse_pos: new Array()};
$Lib = new _lib();

function FormErr () {
	this.ers = new Array();
	this.elts = new Array();
	
	this.reg = function (er, elt) {		
		this.ers[this.ers.length] = er;
		this.elts[this.elts.length] = elt; //change this, cold be element or array
	}	
	this.ResetBorders = function (f, prevCol) {	
	   var a, fi = f.elements;
   	for (a = 0; a < fi.length; a++) {
   		//if (fi[a].id == "") alert(fi[a].type);
   		//if (typeof(fi[a].length) != "undefined") alert(fi[a].id);
   		if (fi[a].type.toLowerCase() == "text" || fi[a].type.toLowerCase() == "password" ||
   			fi[a].nodeName.toUpperCase() == "TEXTAREA")	fi[a].value = fi[a].value.trim();
   		fi[a].style.borderColor = prevCol;
   		if (fi[a].type.toLowerCase() == "radio" || fi[a].type.toLowerCase() == "checkbox")
   			fi[a].style.borderWidth = "0px";
   		if (fi[a].nodeName.toUpperCase() == "SELECT" ||
   			(fi[a].nodeName.toUpperCase() == "INPUT" && fi[a].type.toUpperCase() == "CHECKBOX") ||
   			(fi[a].nodeName.toUpperCase() == "INPUT" && fi[a].type.toUpperCase() == "RADIO")
               ) {
   			fi[a].parentNode.style.borderWidth = "0px";
   			fi[a].parentNode.style.borderStyle = "none";
   		}
   	}
	}
	this.updateBorder = function (hc) {
		var x, y;
		for (x in this.elts) {
			var o = this.elts[x];
			if (!o) continue;
			if (typeof(o) == "string") o = document.getElementById(o);
			if (typeof(o.id) != "undefined") { //check whether it's an array
				if (o.nodeName.toUpperCase() == "SELECT" ||
					(o.nodeName.toUpperCase() == "INPUT" && o.type.toUpperCase() == "CHECKBOX") ||
					(o.nodeName.toUpperCase() == "INPUT" && o.type.toUpperCase() == "RADIO")
                    ) o = o.parentNode;
				o.style.borderColor = hc;
				o.style.borderWidth = "1px";
				o.style.borderStyle = "solid";
			}
			else {
				for (y in o) {
					var oo = o[y];
					if (!oo) continue;
			         if (typeof(oo) == "string") oo = document.getElementById(oo);
					if (oo.nodeName.toUpperCase() == "SELECT" ||
					(oo.nodeName.toUpperCase() == "INPUT" && oo.type.toUpperCase() == "CHECKBOX") ||
					(oo.nodeName.toUpperCase() == "INPUT" && oo.type.toUpperCase() == "RADIO")
                    ) oo = oo.parentNode;
                    oo.style.borderColor = hc;
					oo.style.borderWidth = "1px";
					oo.style.borderStyle = "solid";
				}
			}
		}				
	}
	this.display_error = function (output) {
        var sinfo = output;
        sinfo.innerHTML = "<div  align=\"left\" class=\"error\"><ul><li>" + this.ers.join("<li>") +
        		"</ul>The Invalid Item(s) are highlighted below.</div>";
    	this.updateBorder("#FF0000");
    	sinfo.style.display = "block"; sinfo.style.visibility = "visible";
    	//if (focus) focus.focus();
    	sinfo.tabIndex = 0;
      try { sinfo.focus(); } catch (e) { }
    }
	this.toString = function () {
		return this.ers + "";
	} 
};
