var state = {
	main: function(){},
	cache: {},
	startup: []
};

var isKHTML = navigator.userAgent.indexOf("KHTML")>=0;
var isGecko = (!isKHTML) && navigator.product == "Gecko";
var isIE = (!isGecko) && navigator.cpuClass != undefined && navigator.appName == "Microsoft Internet Explorer";
var isIE5 = isIE && (!Function.apply);
var isIE55 = isIE && (document.onmousewheel == undefined);

function forEachItem(items, call, nonLinear)
{
	if (nonLinear == true){
		for (var i in items)
			if (call(items[i], i) == -1)
				return;
	}else if((items.length != undefined) && (typeof items) != 'string'){
		for (var i=0; items[i]; i++)
			if (call(items[i], i) == -1)
				return;
	}else{
		call(items, 0);
	}
}

var _customEventHandlers = Array();
function registerCustomEvent(sEvent)
{
	if (!(sEvent in _customEventHandlers)){
		_customEventHandlers[sEvent] = Array();
	}
}

function fireCustomEvent(node, sEvent)
{
	var
		ret = true,
		bubble = true,
		e = {
			currentTarget: node,
			target: null,  
			timeStamp: 0,
			type: sEvent,
			bubbles: true,
			stopPropogation: function(){
				bubble = false;
			},
			cancelable: true,
			preventDefault: function(){
				if (e.cancelable){
					ret = false;
				}
			}
		}
		;
	forEachItem(
		_customEventHandlers[sEvent],
		function(handler, i){
			forEachAncestor(
				handler.node,
				function(handlerNode){
					if (handlerNode == node){
						e.target = handlerNode;
						handler.call(e);
						if (!bubble)
							return -1;
					}
				}
			);
		}
	);
	return ret;
}

function hookEvent(node, sEvent, call)
{
	if (sEvent in _customEventHandlers){
                _customEventHandlers[sEvent].push({node:node, call:call });
		return;
	}else if (node.addEventListener) {
		node.addEventListener(sEvent, call, false);
	}else if (node.attachEvent) {
		node.attachEvent("on"+sEvent, call);
	}
	if (eventHooks){
		eventHooks.push({node:node, event:sEvent, call:call});
	}
}

function getEventTarget(e)
{
	return (e.srcElement || e.target);
}

function unloadEventHooks()
{
	forEachItem(
		eventHooks,
		function(hook, i){
			if (!hook)
				return;
			if (hook.node.removeEventListener){
				hook.node.removeEventListener(hook.event, hook.call, false);
				eventHooks[i] = null;
			}else{
				hook.node.detachEvent("on"+hook.event, hook.call);
			}
		}
	);
}

var eventHooks;
if (isIE || isGecko){
	eventHooks = Array();
}

function unloadEvent()
{
	//fireCustomEvent(state, "enterstasis");
	if (eventHooks)
		unloadEventHooks();
}

hookEvent(window, "unload", unloadEvent);
registerCustomEvent("go");

function _readyStateCanvasCheck()
{
	if (document.body){
		clearInterval(state._readyStateTimer);
		state._readyStateTimer = setInterval(_readyStateApplicationCheck, 250);
	}
}

function _applicationReady()
{
	if (state.ready)
		return;
	state.ready = true;
	fireCustomEvent(state, "go");
	setClass(document.body, "ready");
}

function _readyStateApplicationCheck()
{
	if (document.readyState=="complete"){
		clearInterval(state._readyStateTimer);
		_applicationReady();
	}
}

window.onload = _applicationReady;
state._readyStateTimer = setInterval(_readyStateCanvasCheck, 100);

try{
	document.writeln('<style type="text/css">.not-ready { visibility:hidden } div.legacy { display:none }</style>');
}catch(e){}

function forEachAncestor(node, call)
{
	var top = (node.ownerDocument || document).documentElement;
	do{
		if (call(node) == -1)
			return;
	}while(node.parentNode && (node = node.parentNode) != top)
}

function getTag(node)
{
	return String(node.tagName).toLowerCase();
}

function getElements(node, sSelector, max)
{
	var t, c, nodes;
	if (typeof(node) == 'string' ){
		max = sSelector;
		sSelector = node;
		node = document;
	}
	if (!max){
		max = 10000;  
	}
	t = sSelector.split('.');
	c = t[1];  
	t = t[0] == '' ? '*' : t[0];
	if (isIE55 && t == '*'){
		nodes = node.all;
	}else{
		nodes = node.getElementsByTagName(t);
	}
	if (!c){  
		return nodes || array();
	}else{
		c = ' '+c+' ';
	}
	var returns = Array();
	forEachItem(
		nodes,
		function(n, i) {
			if ((' '+n.className+' ').indexOf(c)<0)
				return;
			returns.push(n);
			if (returns.length == max)
				return -1;
		}
	);
	return returns;
}

function getElement(node, sSelector){
	if (typeof(node) == 'string' ){
		sSelector = node;
		node = document;
	}
	if (sSelector.charAt(0) == '#' ){
		return node.getElementById(sSelector.substr(1));
	}else{
		return getElements(node, sSelector, 1)[0] || null;
	}
}

function getAncestor(node, sSelector)
{
	var t, c, nodes, top = (node.ownerDocument || node.document).documentElement;
	t = sSelector.split('.');
	if (t[1]){
		c = ' '+ t[1] + ' ';
	}
	t = t[0] != '' ? t[0] : null;
	do {
		if (t && getTag(node) != t)
			continue;
		if (c && (' '+node.className+' ').indexOf(c)<0)
			continue;
		return node;
	} while ((node = node.parentNode) && node != top);
	return null;
}

function getNextSibling(node)
{
	while (node = node.nextSibling){
		if (node.nodeValue == null)
			return node;
	}
	return null;
}

function getFirstChild(node)
{
	node = node.firstChild;
	if (node.nodeValue == null)
		return node;
	return getNextSibling(node);
}

function setClass(node, className)
{
	if (!hasClass(node, className)){
		node.className += " "+ className;
	}
}

function hasClass(check, className)
{
	if (typeof(check) != 'string'){
		check = check.className;
	}
	return ((' '+check+' ').indexOf(' '+className+' ') >= 0);
}

function forEachStyleRule(x, call)
{
	if (x.styleSheets){
		x = x.styleSheets;
		for (var i=0; i!=x.length; i++){
			if (forEachStyleRule(x[i].cssRules, call) == -1)
				return -1;
		}
	}else{
		if (x.cssRules){
			x = x.cssRules;
		}
		for (var i=0; i!=x.length; i++){
			if (x[i].styleSheet){
				if (forEachStyleRule(x[i].styleSheet, call) == -1)
					return -1;
			}else{
				if (call(x[i]) == -1)
					return -1;
			}
		}
	}
}

function addShadow(n)
{
	var u,w,h;
	if (n.type == 'load'){
		n = getEventTarget(n);
	}
	if (getTag(n) == 'img'){
		w = n.width;
                h = n.height;
		n = getAncestor(n, '.shadow');
        	u = "url(\"/shadows/shadow_" + w + "x" + h + ".png" + "\")";
        	if (n.style.backgroundImage != u){
			n.style.backgroundImage = u;
		}
	}
}

function addShadows(root)
{
	if (!(root && root.tagName)){
		root = document;
	}
        forEachItem(
		getElements(root, "span.shadow"),
		function(n) {
			var i=getFirstChild(n);
			if (i) switch (getTag(i)){
				case 'a':
				case 'img':
					i = getElement(n,'img');
					break;
				default:
					i = null;
			}
			if (i){
				if ((i.width>0 && i.height>0) || (i.complete == true)) {
					addShadow(i);
				}else{
					hookEvent(i, "load", addShadow);
				}
			}else{
				addShadow(n);
			}
		}
	);
}

hookEvent(state, "go", addShadows);

