/* DOM convenience */
var _$elemCache = new Object();
function $(id, reload) {if(!_$elemCache[id]||reload){var e = document.getElementById(id);_$elemCache[id] = e;return e;} else return _$elemCache[id];}
function x$(id){_$elemCache[id]=null;}
function $$(id){$(id,true)}
function _pos(e){if(e.s3)e=e.container();var x=0,y=0;while(e){x+=e.offsetLeft;y+=e.offsetTop;try{e=e.offsetParent;}catch(ex){e=null;}}return{x:x,y:y};}
function _dim(e){if(e.s3)e=e.container();return (!e||!e.offsetWidth)?{w:0,h:0}:{w:e.offsetWidth,h:e.offsetHeight};};
function _absolute(e){if(e.s3)e=e.container();if(e.style.position=='absolute')return;var p=_pos(e);var w=e.clientWidth;var h=e.clientHeight;e.style.position='absolute';e.style.left=(document.all?p.x+1:p.x)+'px';e.style.top=(document.all?p.y+1:p.y)+'px';}

/* Object convenience */
function _inject(d,s){for(var p in s)d[p]=s[p];return d;}
function _extend(d,s){for(var p in s)if(!d[p])d[p]=s[p];return d;}

var $obj = _inject(new Object(),{
	count: 0,
	ects: new Object(),
	timeout: function(o,f,t){var id=$chr.fromNum(this.count++);this.ects[id]=o;setTimeout('$obj.cb("'+id+'","'+f+'")',t);},
	cb:  function(i,f){var o=$obj.ects[i];if(o!=null){o[f]();this.ects[i]=null;}}
});

var $try = _inject(new Object(),{these: function(){for(var i=0,a=arguments;i<a.length;i++){try{return(a[i])();}catch(e){}}return null;}});

var $chr = _inject(new Object(),{
	chrs:'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
	fromNum: function(n){return this.base(n,10)},
	toNum: function(s){return this.from(s,10)},
	base: function(n,b){var s='';while(n>=b){s=this.chrs.charAt(n%b)+s;n=Math.floor(n/b);}return this.chrs.charAt(n)+s;},
	from: function(s,b){if(!this.revc){this.revc=new Object();for(var i=0;i<this.chrs.length;i++)this.revc[this.chrs.charAt(i)]=i;}
		var r=0,i=0;for(var p=0;i=s.length-p-1,p<s.length;p++)r+=this.revc[s.charAt(p)]*(i>0?Math.pow(b,i):1);return r;
	},
	guid: function(){return this.base(new Date().getTime(),62)+$rnd.str(8);}
});

var $rnd = _inject(new Object(),{
	num: function(x,y){return(Math.floor(Math.random()*(y-x)))+x;},
	str: function(len){var s='';while(s.length<len)s+=$chr.chrs.charAt(this.num(0,62));return s;}
});

/* misc? */
function _time(){return(new Date()).getTime();}

/* Collections */
var $a = {
	add: function(a,o){a[a.length]=o;},
	addAll: function(a,a2){if(a)for(var i=0;i<a2.length;i++)a[a.length]=a2[i];},
	insert: function(a,p,o) {if(p<0)p=0;if(p>a.length)p=a.length;for(var i=a.length;i>p;i--)a[i]=a[i-1];a[p]=o;},
	removeAt: function(a,p) {if(p==-1||!a||a.length<=0)return null;var tmp=a[p];for(var i=p+1;i<a.length;i++)a[i-1]=a[i];a.length=a.length-1;return tmp;},
	remove: function(a,o) {return $a.removeAt(a,$a.indexOf(a,o));},
	indexOf: function(a,tst) {for(var i=0;i<a.length;i++)if(a[i]==tst)return i;return -1;},
	call: function(a,f){if(a&&a.length>0)for(var i in a)f(a[i]);}
}

/* component core */
function c$(id) { return $comp.reg[id]; }

var $comp = _inject(new Object(),{
	reg: new Object(),
	r: function(c, id) {
		c.id = id;
		this.reg[id] = c;
		this.foundation(c);
	},
	register: function(c, id) {
		this.r(c,id);
		c.start();
	},
	child: function(p,c,id) {
		if(!p.kids)p.kids=new Array();
		$a.add(p.kids,c);
		c.parent=p;
		this.r(c,id);
		c.start();
	},
	clearChildren: function(c){if(c.kids&&c.kids.length>0)$a.call(c.kids,function(o){x$(o.id)});},
	repaint: function(c){if(c.drawHtml&&c.callRepaint()&&c.container()!=null){var h=c.drawHtml();if(h)c.container().innerHTML=h;}},
	foundation: function(c){
		_extend(c,{
			s3:true,
			container: function(){return $(this.id);},
			start:function(){this.repaint();},
			callRepaint: function(){return true;},
			repaint: function(){if(this.kids)$comp.clearChildren(this);$comp.repaint(this);},
			hide: function(){if(!this.doHide||this.doHide()){var cx=this.container();if(cx){cx.style.visibility='hidden';this.showing=false;}}},
			show: function(){if(!this.doShow||this.doShow()){var cx=this.container();if(cx){cx.style.visibility='visible';this.showing=true;}}},
			visible: function(){return (this.container())?this.showing:false;},
			deleteKid: function(n){if(this.kids&&this.kids.length>0)for(var i in this.kids){if(this.kids.id==n)$a.removeAt(i);this.deleteKid(n);}}
		});
		if (c.handleDrop) {
			$a.add($drag.drops,c);
			if(!c.dropTarget)c.dropTarget=function(){var c=this.container();var p=_pos(c);return [p.x,p.y,parseInt(c.style.width),parseInt(c.style.height),this]}
		}
	}
});

/* DOM walker */
function _bubble(e,h){if(!e)return;var cid=null;while(e){if(e.className&&e.className.indexOf("component")>-1){cid=e.id;break;}e=e.parentNode;}if(!cid)return;var c=c$(cid);if(c==null||h.pop(e,c))_bubble(e.parentNode,h);}

/* event helpers */
var _$events = ["Click","MouseOver","MouseOut","MouseDown","MouseUp","Blur","Change","Submit","Keyup","Keydown"];
for(var i in _$events)eval('function do'+_$events[i]+'(e,extra){_event("'+_$events[i]+'",e,extra);}');
function _event(t,e,ext) {_bubble(e,{t:t, e:ext, o:e,pop:function(e,c){ var r=false;var m=t;if(c[m='handle'+m])return c[m](this.o,this.e);else if(c['handleEvent'])return c['handleEvent'](this.t,this.o,this.e);return true;}});}



/* listen/channel calling */
var $listen = _inject(new Object(),{
	_c:new Object(),
	call:function(c,f){$a.call($listen._c[c],f);},
	listen: function(e,f){if(!this._c[e])this._c[e]=new Array();$a.add(this._c[e],f);},
	stop: function(e,f){$a.remove(this._c[e],f);}
});


/* document mouse channels */
document.onmousedown = function(event) {$listen.call("document.onmousedown",function(a){a(event?event:window.event)})}
document.onmouseup = function(event) {$listen.call("document.onmouseup",function(a){a(event?event:window.event)})}
document.onmousemove = function(event) {$listen.call("document.onmousemove",function(a){a(event?event:window.event)})}


/* drag and drop */
var $drag = _inject(new Object(),{drops:new Array(),zones:null,coff:null,item:null,
	dragThis: function(i){this.stage=i;$listen.listen('document.onmouseup',_dndup);$listen.listen('document.onmousemove',_dndmov);},
	stop: function(){$listen.stop('document.onmousemove',_dndmov);$listen.stop('document.onmouseup',_dndup);}
});


function doDrag(e){$drag.dragThis(e)}
function initDrag(){if(!$drag.staging){$drag.staging=true;var e=$drag.stage;_bubble(e,{o:e,pop:function(e,c){if (!c['doDrag'])return true;var el=c['doDrag'](this.o);if(el.s3)el=el.container();if(el)$drag.item={elem:el,comp:c};else{$drag.abort=true;$drag.stop()};$drag.stage=null;return false;}});$drag.staging=false;}}
function _dndmov(e) {
	if ($drag.stage) initDrag();
	if ($drag.abort){
		$drag.abort=false;
		$drag.item=null;
		return;
	}
	var i = $drag.item;
	if (!i){$drag.stop();return;}
	if (!$drag.moved){
		$drag.moved=true;
		var a=new Array();
		var d,p;
		for(var j in $drag.drops)if((d=$drag.drops[j].dropTarget(i.elem,i.comp)))$a.add(a,[$drag.drops[j], d]);
		if(!i.comp.dragPos){i.comp._rdp=true;i.comp.dragPos=function(x,y){return x;};}
		var z=new Array();
		for(var k in a){p=_pos(a[k][1]);d=_dim(a[k][1]);a[k][0].dndz={x:p.x,y:p.y,w:d.w,h:d.h};z[z.length]=a[k][0]};
		$drag.zones=z;
		$drag.coff={x:e.clientX-parseInt(i.elem.style.left),y:e.clientY-parseInt(i.elem.style.top)};
		i.elem.style.visibility='visible';
	}
	var x=e.clientX;
	var y=e.clientY;
	var t={x:(x-$drag.coff.x),y:(y-$drag.coff.y)};
	t=i.comp.dragPos({x:t.x,y:t.y},{x:$drag.coff.x,y:$drag.coff.y});
	i.elem.style.left=t.x+'px';
	i.elem.style.top=t.y+'px';
	a=$drag.zones;
	for(j in a){
		var q,c=a[j];q=c.dndz;
		if (q.x<=x && q.y<=y && x<=q.x+q.w && y<=q.y+q.h){
			if(!c._dragover){c._dragover=true;if(c.handleDragOver)c.handleDragOver();}
		}else if(c._dragover){c._dragover = false;if(c.handleDragOut)c.handleDragOut();}
	}
}

function _dndup(e){
	if ($drag.stage){$drag.stage=null;return;}
	if(!$drag.moved){$drag.abort=true;return;}
	var a=$drag.zones;var i=$drag.item;$drag.moved=false;$drag.item=null;$drag.zones=null;var t=null;var d=null;
	for(var j in a){t=a[j];if(t._dragover){d=t;if(t.handleDrop)t.handleDrop(i.elem,i.comp);t._dragover=false;}if(t.dragComplete)t.dragComplete();a[j]=null;}
	if(i.comp.dragComplete)i.comp.dragComplete(d,{x:(e.clientX-$drag.coff.x),y:(e.clientY-$drag.coff.y)});
	if(i.comp._rdp)i.comp.dragPos=null;
}



/* ajax */
var $ajax= _inject(new Object(),{
	handlers: ['','onLoading','onLoaded','onInteractive', 'onComplete'],
	jsonGet: function(u,ha,he){if(!ha.jcb){ha.jcb=ha.callback;ha.callback=function(c){this.jcb($json.parse(c.responseText));}};this.get(u,ha,he);},
	jsonPost: function(u,d,ha,he){if(!ha.jcb){ha.jcb=ha.callback;ha.callback=function(c){this.jcb($json.parse(c.responseText));}};this.post(u,d,ha,he);},
	get: function(u,ha,he){return $xhr.doRequest('GET',this.wipeIEsButt(u),'',he,ha);},
	post: function(u,d,ha,he){return $xhr.doRequest('POST',this.wipeIEsButt(u),d,he,ha);},
	successCode: function(r){return r.status==undefined||r.status==0||(r.status>=200&&r.status<300);},
	wipeIEsButt: function(u){var tmp=document.location +'';return tmp.substring(0,tmp.indexOf('/',10))+u;},

	count: 1,
	asy: new Object(),
	prime: function(o){var id=$chr.fromNum(this.count++);this.asy[id]=o;return id;},
	callback:  function(id,c){if(o=this.asy[id]){o.callback(c);this.asy[id]=null;}},
	newId: function(){return $chr.fromNum(this.count++);},
	handle: function(i,h,c){return $try.these(function(){h[this.handlers[i]](c);})},
	error: function(h,e,c,i){return $try.these(function(){h['onException'](e,c,i);})}
});

var i = 4234234443;
var d = new Date();
d.setTime(i);

var $xhr = {
transport:null,
getHTTP: function(){
	return $try.these(
		function(){ return new XMLHttpRequest() },
		function(){ return new ActiveXObject("Msxml2.XMLHTTP") },
		function(){ return new ActiveXObject("microsoft.XMLHTTP") },
		function(){ return new ActiveXObject("Msxml2.XMLHTTP.4.0") },
		function(){ return new ASVRequest() });
},
doRequest: function(m,u,d,he,ha) {
	he=(he!=null)?he:[];
	var async=(ha&&ha.callback);
	var id=$ajax.prime(ha);
	var c=this.getHTTP();

	if(ha) {
		c.onreadystatechange =function(){
			if(c.readyState>0)$ajax.handle(c.readyState,ha,c);
			if (c.readyState==4) {
				$ajax.callback(id,c);
				/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
				c.onreadystatechange = function(){};
				c=null;
			}
		}
	}
	try{c.open(m,u,async);} catch(e){ $ajax.error(ha, e, c,-1); return null; }
	for(var i=0;i<he.length;i++){c.setRequestHeader(he[i][0], he[i][1]);}
	c.setRequestHeader('x-ajax-reqid', $ajax.newId());
	if (m=='POST') {
		c.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		// mozilla can chop two chars, so adding two spaces to the post
		d += "  ";
	}
	try {c.send(d);} catch(e){$ajax.error(ha,e,c,-1);}
	return c;
}}



var _pop = function(s){alert($json.toString(s));}
var $json = {
	toString: function(o) {if (typeof(o) == 'array') return $json.array(o);else return $json.object(o); },
	m: {'\b': '\\b','\t': '\\t','\n': '\\n','\f': '\\f','\r': '\\r','"' : '\\"','\\': '\\\\'},
	array: function (x) { var a = ['['], b, f, i, l = x.length, v; for (i = 0; i < l; i += 1) { v = x[i]; f = $json[typeof v]; if (f) { v = f(v);if (typeof v == 'string') {if (b) a[a.length] = ',';a[a.length] = v;b = true;}}}a[a.length] = ']';return a.join('');},
	'boolean': function (x) {return String(x);},'null': function (x) {return "null";},
	number: function (x) {return isFinite(x) ? String(x) : 'null';},
	object: function (x) {if (!x) return 'null';if (x instanceof Array) return $json.array(x);var a = ['{'], b, f, i, v;for (i in x) {v = x[i];f = $json[typeof v];if (f) {v = f(v);if (typeof v == 'string') {if (b) a[a.length] = ',';a.push($json.string(i,true), ':', v);b = true;}}}a[a.length] = '}';return a.join('');},
	string: function (x,n) {if (/["\\\x00-\x1f]/.test(x)) {x = x.replace(/([\x00-\x1f\\"])/g,function(a, b) {var c = $json.m[b];if (c) return c;c = b.charCodeAt();return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);});}return (n&&x.match(/^([A-Za-z0-9_]+)$/)) ? x : '"' + x + '"';},
	parse: function (s) {return eval('(' + s + ')');}
}

// ANIMATION AND FUN...
var animClock = 30;

function _c(e) {return (e && e.s3)?e.container():e;}
function _hide(e){e=_c(e);e.style.display='none';e.style.visibility='hidden';}
function _show(e){e=_c(e);e.style.visibility='visible';e.style.display='block';}
function _moveTo(e,p){e=_c(e);if(p.x)e.style.left=p.x+'px';if(p.y)e.style.top=p.y+'px';}
function _moveBy(e,t){e=_c(e);var p=_pos(e);e.style.left=(t.x+p.x)+'px';e.style.top=(t.y+p.y)+'px';}
function _resize(e,d){e=_c(e);if(d.w)e.style.width=d.w+'px';if(d.h)e.style.height=d.h+'px';}
function _mimic(e,t){_moveTo(t,_pos(e));_resize(t,_dim(e));}

function _amove(e, tgt, t, fu) {
	e=_c(e);
	_show(e);
	var p = _pos(e);
	var q = _dim(e);
	p.w = q.w;
	p.h = q.h;
	new _am(e,p,tgt, t, fu);
}
// element, position (with dimension), target, time, function
function _am(e, p, g, t, f) {
	this.e = e;this.p = p;this.g = g;this.t = t;this.f = f;this.d = {};
	for (i in g) this.d[i] = g[i]-p[i];
	this.q = 3.1/(2*t);
	this.s = _time();

	this.tock = function() {
		var et,o={};
		if ((et=_time()-this.s) <t) {
			var fact = Math.abs(Math.sin(et*this.q));
			for (i in this.g)o[i]=Math.round(fact*this.d[i])+this.p[i];
			if (o.x) _moveTo(this.e,o);
			if (o.w) _resize(this.e,o);
			$obj.timeout(this,'tock', animClock);

		} else {
			for (i in this.g)o[i]=Math.round(fact*this.d[i])+this.p[i];
			if (this.g.x) _moveTo(this.e, this.g);
			if (this.g.w) _resize(this.e, this.g);
			if (this.f) this.f();
		}
	}
	this.tock();
}

function _create(id, cname) {
	var e = document.createElement('div');
	_absolute(e);
	_hide(e);
	if (cname) {e.className = cname;}
	if (id) {e.id = id;}
	document.body.insertBefore(e,document.body.childNodes[0]);
	return e;
}

function _create(id, cname) {
	var e = document.createElement('div');
	_absolute(e);
	_hide(e);
	if (cname) {e.className = cname;}
	if (id) {e.id = id;}
	document.body.insertBefore(e,document.body.childNodes[0]);
	return e;
}

function _vp() {
	var w=window,d=document;
	var ox=0,oy=0;
	if(typeof(w.pageYOffset)=='number') {
		//Netscape compliant
		oy = w.pageYOffset;
		ox = w.pageXOffset;
	} else if( d.body && ( d.body.scrollLeft || d.body.scrollTop ) ) {
		//DOM compliant
		oy = d.body.scrollTop;
		ox = d.body.scrollLeft;
	} else if( d.documentElement && ( d.documentElement.scrollLeft || d.documentElement.scrollTop ) ) {
		//IE6 standards compliant mode
		oy = d.documentElement.scrollTop;
		ox = d.documentElement.scrollLeft;
	}

	return {w:(w.innerWidth || (d.documentElement.clientWidth || d.body.clientWidth)),
			h:(w.innerHeight || (d.documentElement.clientHeight || d.body.clientHeight)),
			x:ox,y:oy};
}

function _cpos(d) {
	var vp = _vp();
	return {x:((vp.w/2)-((d.w)/2)+vp.x), y:((vp.h/2)-((d.h)/2)+vp.y),w:d.w,h:d.h};
}


