window.onloadListeners = new Array();
function addOnLoadListener(listener) {
    window.onloadListeners[window.onloadListeners.length] = listener;
}

window.onload = function() {
    for (var i=0; i<window.onloadListeners.length; i++) {
	var func = window.onloadListeners[i];
	func.call();
    }
};

window.additionalEvents = new Array();
function setAdditionalEvent(fromName, toName) {
    window.additionalEvents[fromName] = toName;
}

function getAdditionalEvent(name) {
    if (window.additionalEvents[name]) {
	return window.additionalEvents[name];
    } else {
	return null;
    }
}

var CWS= new Object();
CWS.Replace = Class.create();
CWS.Replace.prototype = {
    initialize: function(element, html) {
	element = $(element);
	if (element.outerHTML) {
	    element.outerHTML = html.stripScripts();
	} else {
	    var range = element.ownerDocument.createRange();
	    range.selectNodeContents(element);
	    element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
	}
	setTimeout(function() {html.evalScripts()}, 10);
    }
};

var Effect = new Object();

Effect.Highlight = Class.create();
Effect.Highlight.prototype = {
    initialize: function(element) {
	this.element = $(element);
	this.start  = 153;
	this.finish = 255;
	this.current = this.start;
	this.fade();
    },
  
    fade: function() {
	if (this.isFinished()) return;
	if (this.timer) clearTimeout(this.timer);
	this.highlight(this.element, this.current);
	this.current += 17;
	this.timer = setTimeout(this.fade.bind(this), 250);
    },
  
    isFinished: function() {
	return this.current > this.finish;
    },
  
    highlight: function(element, current) {
	element.style.backgroundColor = "#ffff" + current.toColorPart();
    }
}

function includeHTML(name, target, insertion) {
    var url = getURL(name);
    if ($(target) && url) {
	var addFunc = getAdditionalEvent(target);
	if (addFunc) {
	    var afterFunc = function() {
		updateAfterHook($(target).parentNode);
		addFunc.call();
	    }
	} else {
	    var afterFunc = function() {
		updateAfterHook($(target).parentNode);
	    }
	}
	var myAjax = new Ajax.Updater
	    (
	     {success: target},
	     url,
	     {
		 insertion: insertion,
		 onFailure: reportError,
		 onComplete: afterFunc
	     });
    }
}

window.URLHash = new Array();
function addURL(name, url) {
    window.URLHash[name] = url;
}

function getURL(name) {
    if (window.URLHash[name].call) {
	return window.URLHash[name].call();
    } else {
	return window.URLHash[name];
    }
}

function updateAfterHook(node) {
    setXHRHook(node);
    setOnEventHook(node);
    setEffect(node);
}

function setXHRHook(doc) {
    if (!doc) {
	doc = document;
    }
    var as = doc.getElementsByTagName("a");
    for (var i=0; i<as.length; i++) {
	if (inClass(as[i], "xhr")) {
	    //alert(as[i].className);
	    //alert(as[i]);
	    as[i].onclick = xhrHook;
	}
    }
}

function setOnEventHook(doc) {
    if (!doc) {
	doc = document;
    }
    var tags = ["input", "select", "div"];
    var events = ["click", "change", "mouseover"];
    for (var i=0; i<tags.length; i++) {
	var es = doc.getElementsByTagName(tags[i]);
	for (var j=0; j<es.length; j++) {
	    for (var k=0; k<events.length; k++) {
		var func = getOnEvent(es[j], events[k]);
		//alert(func);
		if (func) {
		    es[j]["on"+events[k]] = window[func];
		}
	    }
	}
    }
}

function setEffect(doc) {
    if (!doc) {
	doc = document;
    }
    var tags = document.getElementsByClassName("effect_highlight", doc);
    for (var i=0; i<tags.length; i++) {
	new Effect.Highlight(tags[i]);
    }
}

function update_estimate() {
    var a = document.getElementById("update_estimate");
    a.onclick();
}

function hover() {
    if (!this.hoverd) {
	this.hoverd = true;
	this.orgClassName = this.className;
	this.onmouseout = function() {
	    this.className = this.orgClassName;
	    //alert(this.className);
	    this.hoverd = false;
	};
	var cs = this.className.split(" ");
	var c = cs[0]+"Hover";
	cs.push(c);
	this.className = cs.join(" ");
	//alert(this.className);
    }
}

addOnLoadListener(setXHRHook);

function inClass(node, arg) {
    var cs = node.className.split(" ");
    for (var i=0; i<cs.length; i++) {
	if (cs[i] == arg) {
	    return true;
	}
    }
    return false;
}

function getUpdate(node) {
    return getClassArg(node, "update");
}

function getEvent(node) {
    return getClassArg(node, "event");
}

function getOnEvent(node, event) {
    return getClassArg(node, "on_"+event);
}

function getTarget(node) {
    return getClassArg(node, "target");
}

function getClassArg(node, pre) {
    pre += "_";
    var cs = node.className.split(" ");
    for (var i=0; i<cs.length; i++) {
	if (cs[i].indexOf(pre) != -1) {
	    return cs[i].substr(pre.length);
	}
    }
    return false;
}

function xhrHook() {
    var update = getUpdate(this);
    var event = getEvent(this);
    var target = getTarget(this);
    //alert(update);
    //alert(event);
    if (update) {
	var form = getParentByTagName(this, "form");
	if (event) {
	    form["event"].value = event;
	}
	var param = Form.serialize(form);
	param += "&update="+update;
	//alert(param);
	var eval = false;
	if (inClass(this, "evalScripts")) {
	    eval = true;
	}
	xhrSubmit(this.href, update, param, eval);
	form["event"].value = "";
    } else {
	var form = getParentByTagName(this, "form");
	anchorSubmit(form, this.href, event, target);
    }
    return false;
}

function getParentByTagName(node, name) {
    if (node.nodeName != name.toUpperCase()) {
	return getParentByTagName(node.parentNode, name);
    }
    return node;
}

function xhrSubmit(url, target, param, eval) {
    if ($(target) && url) {
	var addFunc = getAdditionalEvent(target);
	if (addFunc) {
	    var afterFunc = function() {
		updateAfterHook($(target));
		addFunc.call();
	    }
	} else {
	    var afterFunc = function() {
		updateAfterHook($(target));
	    }
	}
	var myAjax = new Ajax.Updater
	    (
	     {success: target},
	     url,
	     {
		 parameters: param,
		 onFailure: reportError,
		 onComplete: afterFunc,
		 insertion: CWS.Replace,
		 evalScripts: eval
	     });
    }
}

function anchorSubmit(form, href, event, target) {
    var action = form.action;
    form.action = href;
    if (event) {
	form["event"].value = event;
    }
    if (target) {
	form.target = target;
    }
    form.submit();
    form.action = action;
    form["event"].value = "";
    form.target = "";
}

function jump(name) {
    var url = getURL(name);
    if (url) {
	location.href = url;
    }
}

function setUPFilename(id, filename) {
    var div = document.getElementById(id);
    if (div) {
        div.value = filename;
    }
}