var onloadChain = new sl_onloadChain();

function sl_onloadChain() {
	this.chain = window.onload ? [window.onload] : Array();
	this.add = function(f) {
		this.chain.push(f);
	}
	
	window.onload = function(e) {
		for (var i = 0; i < this.onloadChain.chain.length; i++) {
			this.onloadChain.chain[i](e);
		}
	};
	window.onloadChain = this;
};

function dg(id,p,t,a) {
	if (document.getElementById(id)) {
		return document.getElementById(id);
	} else if (p) {
		var d = document.createElement(t);
		recursiveSet(d,a);
		d.id = id;
		p.appendChild(d);
		return d;
	}
	return false;
};

function stopEvent(e) {
	if (!e && window.event) e = window.event;
	if (e) {
		e.cancelBubble = true;
		if (e.preventDefault) {
			e.preventDefault();
		}
	}
	return false;
};

function getKeyFromEvent(e) {
	var k = window.event ? (event ? event.keyCode : e.keyCode) : e.which;
	if ((k >= 0x30 && k <= 0x39) || (k >= 0x41 && k <= 0x5A)) {
		return String.fromCharCode(k).toLowerCase();
	} else if (k < 0x30) {
		var a = [0,1,2,3,4,5,6,7,'backspace','tab',10,11,12,'enter',14,15,'shift',
		'ctrl','alt','pause','caps',21,22,23,24,25,26,'escape',28,29,30,31,'space',
		'pgup','pgdown','end','home','left','up','right','down',41,42,43,44,'insert','delete',47];
		return a[k];
	} else {
		switch (k) {
			case 109: return "minus";
			case 61: return "plus";
			case 144: return "numlock";
			case 188: return "lt";
			case 190: return "gt";
			case 191: return "?";
			case 220: return "|";
			case 222: return "}";
			case 219: return "{";
			default: return k;		
		}
	}
};

function serverRequestInterface(ref,base) {
	this.base = base;
	this.requests = Array();
	this.ref = ref;
	
	this.request = function(action,data,callback) {
		this.requests.push(new this.requestObject(action,data,callback,this));
	};
	
	this.requestObject = function(action,data,callback,parent) {
		this.newHTTPRequest = function() { 
			if (window.XMLHttpRequest) { 
				 return new XMLHttpRequest();
			} else if (window.ActiveXObject) {
				 return new ActiveXObject("Microsoft.XMLHTTP");
			}
		};
		this.ref = parent.ref;
		this.parent = parent;
		this.action = action;
		this.data = "v="+escape(serialize(data));
		this.dataRaw = data;
		this.callback = callback;
		this.conn = this.newHTTPRequest();
		this.conn.ob = this;
		this.conn.onreadystatechange = function() {
			switch (this.readyState) {
				case 4:
				if (this.ob.callback) {
					this.ob.callback(this,evalVars(this.responseText),this.ob);
				}
				break;
			}
		};
		this.conn.open("POST", parent.base+"?action="+action, true);
		this.conn.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.conn.setRequestHeader("Content-length", this.data.length);
		this.conn.setRequestHeader("Connection", "close");
		this.conn.send(this.data);
		
	};
};

function serialize (mixed_value) {
    // http://kevin.vanzonneveld.net
    // +   original by: Arpad Ray (mailto:arpad@php.net)
    // +   improved by: Dino
    // +   bugfixed by: Andrej Pavlovic
    // +   bugfixed by: Garagoth
    // +      input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
    // +   bugfixed by: Russell Walker (http://www.nbill.co.uk/)
    // +   bugfixed by: Jamie Beck (http://www.terabit.ca/)
    // +      input by: Martin (http://www.erlenwiese.de/)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
    // +   improved by: Le Torbi (http://www.letorbi.de/)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
    // +   bugfixed by: Ben (http://benblume.co.uk/)
    // -    depends on: utf8_encode

    var _utf8Size = function (str) {
        var size = 0,
            i = 0,
            l = str.length,
            code = '';
        for (i = 0; i < l; i++) {
            code = str.charCodeAt(i);
            if (code < 0x0080) {
                size += 1;
            } else if (code < 0x0800) {
                size += 2;
            } else {
                size += 3;
            }
        }
        return size;
    };
    var _getType = function (inp) {
        var type = typeof inp,
            match;
        var key;

        if (type === 'object' && !inp) {
            return 'null';
        }
        if (type === "object") {
            if (!inp.constructor) {
                return 'object';
            }
            var cons = inp.constructor.toString();
            match = cons.match(/(\w+)\(/);
            if (match) {
                cons = match[1].toLowerCase();
            }
            var types = ["boolean", "number", "string", "array"];
            for (key in types) {
                if (cons == types[key]) {
                    type = types[key];
                    break;
                }
            }
        }
        return type;
    };
    var type = _getType(mixed_value);
    var val, ktype = '';

    switch (type) {
    case "function":
        val = "";
        break;
    case "boolean":
        val = "b:" + (mixed_value ? "1" : "0");
        break;
    case "number":
        val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value;
        break;
    case "string":
        val = "s:" + _utf8Size(mixed_value) + ":\"" + mixed_value + "\"";
        break;
    case "array":
    case "object":
        val = "a";
/*
            if (type == "object") {
                var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
                if (objname == undefined) {
                    return;
                }
                objname[1] = this.serialize(objname[1]);
                val = "O" + objname[1].substring(1, objname[1].length - 1);
            }
            */
        var count = 0;
        var vals = "";
        var okey;
        var key;
        for (key in mixed_value) {
            if (mixed_value.hasOwnProperty(key)) {
                ktype = _getType(mixed_value[key]);
                if (ktype === "function") {
                    continue;
                }

                okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
                vals += this.serialize(okey) + this.serialize(mixed_value[key]);
                count++;
            }
        }
        val += ":" + count + ":{" + vals + "}";
        break;
    case "undefined":
        // Fall-through
    default:
        // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
        val = "N";
        break;
    }
    if (type !== "object" && type !== "array") {
        val += ";";
    }
    return val;
};

function evalVars(txt) {
	try {
		eval("var rv = "+txt+";");
		return rv;
	} catch (e) {
		return false;
	}
};

function recursiveSet(d,a) {
	for (var i in a) {
		if (typeof(a[i]) == "object") {
			recursiveSet(d[i],a[i]);
		} else {
			d[i] = a[i];
		}
	}
};

function removeChildNodes(d) {
	if (!d) return;
	while (d.childNodes.length) {
		d.removeChild(d.childNodes[0]);
	}
};

//{d:this.results,h:"left",v:"top"},d:{d:this.d,h:"left",v:"bottom"}

function positionElementRelative(d1,d2,offx,offy) {
	var db1 = getDBox(d1.d);
	var db2 = getDBox(d2.d);
	positionElement(d1.d,transformPos(db2,d2.h)-transformPos(db1,d1.h,true)+(offx?offx:0),transformPos(db2,d2.v)-transformPos(db1,d1.v,true)+(offy?offy:0));
};

function transformPos(b,pos,relative) {
	switch (pos) {
		case "left":return relative?0:b.x1;
		case "right":return b.x2-(relative?b.x1:0);
		case "top":return relative?0:b.y1;
		case "bottom":return b.y2-(relative?b.y1:0);
	}
	return false;
};

function positionElement(d,x,y,w,h) {
	if (x != null) { d.style.left = x+"px"; }
	if (y != null) { d.style.top = y+"px"; }
	if (w) { d.style.width = w+"px"; }
	if (h) { d.style.height = h+"px"; }
};

function getDBox(d, noScrollOffset) { 
	if (!d) return false;
	if (d == "mouse") {
		return {x1:mouseX,y1:mouseY,x2:mouseX+1,y2:mouseY+1,w:1,h:1};
	}
	var rv = Object();
	rv.y1 = rv.x1 = 0;
	rv.x2 = d.offsetWidth;
	rv.y2 = d.offsetHeight;
	if (d) {
		do {
			rv.x1 += d.offsetLeft - (d.scrollLeft && !noScrollOffset ? d.scrollLeft : 0);
			rv.y1 += d.offsetTop - (d.scrollTop && !noScrollOffset ? d.scrollTop : 0);
			d = d.offsetParent;
		} while(d)
	}
	rv.x2 += rv.x1;
	rv.y2 += rv.y1;
	rv.w = rv.x2 - rv.x1;
	rv.h = rv.y2 - rv.y1;
	rv.x = rv.x1;
	rv.y = rv.y1;
	return rv;
};

function imgRot(id,srcs,go) {
	var p = dg(id);
	if (go) {
		var step = 0.01;
		var fadeTime = 0.2;
		
		if (p.fadePos % 1 < fadeTime + (step / 2)) {
			var i = p.fadePos | 0;
			
			if (i == 1) p.first = 0;
			var o1 = Math.min(1,(p.fadePos % 1) / fadeTime);
			var o2 = 1 - o1;
			
			dg(id+"_"+i).style.opacity = o2;
			dg(id+"_"+i).style.display = o2 > (step / 2) && ! p.first? "block" : "none";
			
			dg(id+"_"+((i + 1)%p.imgCount)).style.opacity = o1;
			dg(id+"_"+((i + 1)%p.imgCount)).style.display = o1 > (step / 2) ? "block" : "none";
		}
		p.fadePos += step;
		p.fadePos = Math.round(p.fadePos / step) * step;
		if (p.fadePos >= p.imgCount) {
			p.fadePos = 0;
		}
	} else {
		p.first = 1;
		p.fadePos = 0;
		p.imgCount = srcs.length;
		
		for (var i = 0; i < srcs.length; i++) {
			var img = dg(id+"_"+i,p,"img",{
				src:srcs[i],
				style:{
					position:"absolute",
					top:"0px",
					left:"0px",
					opacity:0.0,
					display:"none"
				}
			});
		}
		setInterval("imgRot('"+id+"',null,1)", 50);
	}
};

