var Util = new function() {

	// Util objects container
	this.Objects = new Array();

}

// inits script
Util.initPageJs = function() {
	if(Util.explorer(6, "<=")) {
		Util.IEsucks(document.getElementById("contentWrap"));
	}
}

// runs when DOM is ready
$(document).ready(function() {
	Util.initPageJs();
});

// Initialize any element with the init-class within container
Util.initElements = function(container) {
	var i, element, elements, definition;

	// additional initializations based on class name
	elements = this.getElementsByClassName("init([:a-zA-Z])+", container);
	// add container to elements
	if(this.getTypeDefinitionByClassName("init", container)){
		elements[elements.length] = container;
	}

	for(i = 0; element = elements[i]; i++) {
		// get init definition
		definition = this.getTypeDefinitionByClassName("init", element);
		// if object exists, init element
		if(definition && typeof(this.Objects[definition]) == "object") {
			this.Objects[definition].init(element);
		}
	}
}

Util.tabs = function(link) {

/*	link.onfocus = link.blur();*/

	if(!link.options) {
		link.options = new Array();

		tabs = link.parentNode.parentNode.getElementsByTagName("li");
		for(i = 0; tab = tabs[i]; i++) {
			link.options[link.options.length] = tab.className;
		}

		link.wrapper = link;

		while(!link.wrapper.className.match(/border/g)) {
			link.wrapper = link.wrapper.parentNode;
		}
		
	}

	for(i = 0; option = link.options[i]; i++) {
		Util.removeClassName(link.wrapper, option);
	}
	Util.addClassName(link.wrapper, link.parentNode.className);
	link.blur();
}

Util.advancedSearch = function(element) {
	if(element.parentNode.className.match(/open/g)) {
		Util.removeClassName(element.parentNode, "open");
		$("#advancedSearch").hide("normal");
	}
	else {
		Util.addClassName(element.parentNode, "open");
		$("#advancedSearch").show("slow");
	}
}

Util.boligTyper = function(element){
	var id, node, i;
	id = element.id;
	if(element.checked) {
		for(i = 0; node = element.parentNode.childNodes[i]; i++){
			if(node.nodeName.toLowerCase() == "input" && node != element) {
				node.disabled = "disabled";
			}
			else if(node.nodeName.toLowerCase() == "label" && (Util.explorer() ? node.getAttribute("htmlFor") != id : node.getAttribute("for") != id)) {
				Util.addClassName(node, "disabled");
			}
			else if(node.className == "notice") {
				node.style.display = "block";
			}
		}
	}
	else {
		for(i = 0; node = element.parentNode.childNodes[i]; i++){
			if(node.nodeName.toLowerCase() == "input" && node != element) {
				node.disabled = false;
			}
			else if(node.nodeName.toLowerCase() == "label" && (Util.explorer() ? node.getAttribute("htmlFor") != id : node.getAttribute("for") != id)) {
				Util.removeClassName(node, "disabled");
			}
			else if(node.className == "notice") {
				node.style.display = "none";
			}
		}
	}
}


Util.editValue = function(element) {
	var input = element.getElementsByTagName("input")[0];
	//var span = element;
	//Util.removeClassName(input, "hidden");
	Util.addClassName(input, "focus");

	input.onblur = Util.unEditValue;
	Util.editField = element;
	input.focus();
}

Util.unEditValue = function() {
	var element = Util.editField;
	var input = element.getElementsByTagName("input")[0];
//	span.innerHTML = input.value;
	//if(input.value) {
		Util.removeClassName(input, "focus");
	//}
	//Util.addClassName(input, "hidden");
}

Util.layOverId = function(id) {
	var layOver = Util.makeLayOver();
	layOver.parentNode.container_id = id;

	//var layIn = document.getElementById(id).cloneNode(true);
	var layIn = document.getElementById(id+"Content");
	//Util.removeClassName(layIn, "hidden");
	layOver.appendChild(layIn);
	Util.initElements(layOver);
}
Util.layOverUrl = function(url) {
	var layOver = Util.makeLayOver();
	var layIn = document.createElement("div");
	layIn.id = "layIn";
	layOver.appendChild(layIn);

	//alert(layOver.id);
	Util.Ajax.loadContainer(url, layIn.id);
}

Util.layOverString = function(header, body) {
	var layOver = Util.makeLayOver();
	var c100 = document.createElement("div");
	var cInner = document.createElement("div");

	var h3 = document.createElement("h3");
	var p = document.createElement("p");

	h3.innerHTML = header;
	p.innerHTML = body;

	c100.className = "c100 border";
	layOver.appendChild(c100);

	cInner.className = "cInner";
	c100.appendChild(cInner);

	cInner.appendChild(h3);
	cInner.appendChild(p);

	Util.initElements(layOver);
}


Util.makeLayOver = function() {

	if(!document.getElementById("layOverBg")) {
		var layOverBg = document.createElement("div");
		layOverBg.id = "layOverBg";
	}
	else {
		layOverBg = document.getElementById("layOverBg");
	}

	var layOver = document.createElement("div");
	layOver.id = "layOver";
	layOver.className = "init:center";

	var bn_close = document.createElement("a");
	bn_close.innerHTML = "Luk vindue";
	bn_close.className = "close";
	bn_close.onclick = Util.destroyLayOver;

	layOver.appendChild(bn_close);

	layOverBg.appendChild(layOver);
	body_form = document.getElementById("aspnetForm");

	//alert(document.body.getElement)
	body_form.appendChild(layOverBg);
	//document.body.appendChild(layOverBg);

	layOverBg.style.height = document.body.offsetHeight+10 + 'px';

	if(Util.explorer(6, "<=")) {
		layOverBgIframe = layOverBg.appendChild(document.createElement("iframe"));
		layOverBgIframe.id = "layOverIframe";
		layOverBgIframe.className = "init:center";
		layOverBgIframe.style.visibility = "hidden";
	}

	$("#layOverBg").fadeIn("slow");

	return layOver;

}
Util.destroyLayOver = function() {
	var layOverBg = document.getElementById("layOverBg");
	$("#layOverBg").fadeOut("slow", Util.removeLayOver);

	if(Util.explorer(6, "<=")) {
		var layOverBgIframe = document.getElementById("layOverIframe");
		layOverBgIframe.parentNode.removeChild(layOverBgIframe);

	}
}
Util.removeLayOver = function() {
	var layOverBg = document.getElementById("layOverBg");
	if(layOverBg.container_id) {
		document.getElementById(layOverBg.container_id).appendChild(document.getElementById(layOverBg.container_id+"Content"));
	}
	layOverBg.parentNode.removeChild(layOverBg);
}


Util.Objects["center"] = new function() {
	this.init = function(element) {
		element.style.position = "absolute";
		element.style.top = ((Util.explorer()) ? document.documentElement.scrollTop : window.pageYOffset)+((Util.docHeight()-element.offsetHeight)/2)+'px';
		element.style.left = ((Util.docWidth()-element.offsetWidth)/2) + 'px';
		element.style.visibility = "visible";
		if(Util.explorer(6, "<=") && element.id == "layOver") {
			Util.ie6iframe(element);
		}
	}
}

Util.ie6iframe = function(element) {
	var layOverBgIframe = document.getElementById("layOverIframe");
	layOverBgIframe.style.height = element.offsetHeight + 'px';
	layOverBgIframe.style.width = element.offsetWidth + 'px';
	layOverBgIframe.style.left = element.offsetLeft + 'px';
	layOverBgIframe.style.top = element.offsetTop + 'px';
	layOverBgIframe.style.visibility = "visible";
}

Util.IEsucks = function(element) {
	// correct border class element (by moving class to new element)
	border_elements = Util.getElementsByClassName("border", element);
	for(i = 0; border_element = border_elements[i]; i++) {
		border_element.className = border_element.className.replace(/ border|border |border/g, "");

		div = document.createElement("div");
		div.className = "border";
		while(border_element.childNodes.length) {
			div.appendChild(border_element.childNodes[0]);
		}
		border_element.appendChild(div);
	}
}
// Browser definition utilities
Util.explorer = function(version, scope) {
	if(document.all) {
		var current_version = navigator.userAgent.match(/(MSIE )(\d+.\d)/i)[2];
		if(typeof(scope) != "undefined" && !eval(current_version + scope + version)){
			return false;
		}
		else if(typeof(version) != "undefined" && current_version != version) {
			return false;
		}
		else {
			return current_version;
		}
	}
	else {
		return false;
	}
}
// Get absolute left position
Util.absoluteLeft = function(element) {
	if(Util.safari() && element.nodeName == "TR") {
		return element.getElementsByTagName("TD")[0].offsetLeft + Util.absoluteLeft(Util.getParentTag("TABLE", element));
	}
	else if(element.offsetParent) {
		return element.offsetLeft + Util.absoluteLeft(element.offsetParent);
	}
	return element.offsetLeft;
} 
// Get absolute top position
Util.absoluteTop = function(element) {
	if(Util.safari() && element.nodeName == "TR") {
		return element.getElementsByTagName("TD")[0].offsetTop + Util.absoluteTop(Util.getParentTag("TABLE", element));
	}
	else if(element.offsetParent) {
		return element.offsetTop + Util.absoluteTop(element.offsetParent);
	}
	return element.offsetTop;
}
// Get document viewable width (inside browser)
Util.docWidth = function() {
	var width;
	if(self.innerHeight) {
		width = self.innerWidth;
	}
	else if(document.documentElement && document.documentElement.clientHeight) {
		width = document.documentElement.clientWidth;
	}
	else if(document.body) {
		width = document.body.clientWidth;
	}
	return width;
}
// Get document viewable height (inside browser)
Util.docHeight = function() {
	var height;
	if(self.innerHeight) {
		height = self.innerHeight;
	}
	else if(document.documentElement && document.documentElement.clientHeight) {
		height = document.documentElement.clientHeight;
	}
	else if(document.body) {
		height = document.body.clientHeight;
	}
	return height;
}
// Get elements in optional content with classname (default content is contentWrap)
Util.getElementsByClassName = function(classname, content) {
	var element, i, elements, regexp, return_array;
	return_array = new Array();
	elements = content ? (typeof(content) == "string" ? document.getElementById(content).getElementsByTagName("*") : content.getElementsByTagName("*")) : document.getElementById("contentWrap").getElementsByTagName("*");
	// IE < 6 needs a bit of help getting elements
	elements = elements.length ? elements : (Util.explorer() ? document.all : elements);
	regexp = new RegExp("(^|\\s)" + classname + "(\\s|$|\:)");
	for(i = 0; element = elements[i]; i++) {
		if(regexp.test(element.className)) {
			return_array[return_array.length] = element;
		}
	}
	return return_array;
}
// Check for type definition of element. Defined by identifier:type
Util.getTypeDefinitionByClassName = function(identifier, element) {
	var regexp = new RegExp(identifier+":[?=\\w/\\#~:.?+=?&%@!\\-]*");
	if(element.className.match(regexp)) {
		return element.className.match(regexp)[0].replace(identifier+":", "");
	}
	return false;
}
// Add classname to element
Util.addClassName = function(element, classname) {
	var regexp = new RegExp("(^|\\s)" + classname + "(\\s|$|\:)");
	if(!regexp.test(element.className)) {
		element.className += element.className ? " "+classname : classname;
	}
}
// Remove classname from element
Util.removeClassName = function(element, classname) {
	var regexp = new RegExp(classname+" | "+classname+"|"+classname);
	element.className = element.className.replace(regexp, "");
}
// kills click (to prevent click from invoking other events)
Util.nonClick = function(event) {
	event = event ? event : window.event;
	if(event.preventDefault) {event.preventDefault();}
	if(event.stopPropagation) {event.stopPropagation();}
	event.returnValue = false;
	event.cancelBubble = true;
}
// trim whitespace and crlf
String.prototype.trim = function(string) {
	return this.replace(/^\s+|\s+$/g, "");
}

// Debug function
Util.debugWindow = false;
Util.openDebugger = function() {
	Util.debugWindow = window.open("", "debugWindow", "width=600, height=400, scrollbars=yes, resizable=yes");
}
Util.debug = function(output) {
	var element, br;
	if(location.href.indexOf("mkn") != -1) {
		if(Util.debugWindow) {
			element = Util.debugWindow.document.createTextNode(output);
			br = Util.debugWindow.document.createElement('br');
			Util.debugWindow.document.body.appendChild(element);
			Util.debugWindow.document.body.appendChild(br);
			Util.debugWindow.scrollBy(0,1000);
		}
		else {
			Util.openDebugger();
			if(!Util.debugWindow) {
				alert("Disable popup blocker!");
			}
			else {
				Util.debug(output);
			}
		}
	}
}


Util.Ajax = new Object();

// container to hold the requests
Util.Ajax.requests = new Array();

// Send request to url, calls the specified notify function on object on response
Util.Ajax.send = function(url, notify, object, parameters, async, type) {
	// set request id
	var id = this.requests.length;
	this.requests[id] = new Object();
	// save request parameters
	this.requests[id].url = url;
	this.requests[id].notifier = notify;
	this.requests[id].object = (typeof(object) != "undefined" ? object : window);
	this.requests[id].parameters = (typeof(parameters) != "undefined" ? parameters : "");
	this.requests[id].async = (typeof(async) != "undefined" ? async : true);
	this.requests[id].type = (typeof(type) == "string" ? type : "POST");

	// get request object, and verify it
	this.requests[id].xmlHttp = this.createRequestObject();
	if(!this.requests[id].xmlHttp || typeof(this.requests[id].xmlHttp.send) == 'undefined') {
		this.responder(id, false);
		return;
	}

	this.requests[id].xmlHttp.open(this.requests[id].type, this.requests[id].url, this.requests[id].async);
	this.requests[id].xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

	try {
		this.requests[id].xmlHttp.send(parameters);
	}
	catch(e) {
		this.responder(id, false);
		return;
	}

	// If async initiate onreadystatechange
	if(this.requests[id].async) {
		this.requests[id].xmlHttp.onreadystatechange = function() {
			if(Util.Ajax.requests[id].xmlHttp.readyState == 4) {
				Util.Ajax.responder(id, true);
			}
		}
	}
	else {
		Util.Ajax.responder(id, true);
	}
	return;
}

// Create xmlhttprequest object 
Util.Ajax.createRequestObject = function() {
	var request_object = false;
	if(typeof(window.ActiveXObject) == "function") {
		try {
			request_object = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(e) {
			return false;
		}
	}
	else if(window.XMLHttpRequest) {
		try {
			request_object = new XMLHttpRequest();
		}
		catch(e) {
			return false;
		}
	}
	return request_object;
}

// XML load responder, calls notifier function specified in notify
Util.Ajax.responder = function(id, state) {
	var response_object, response;
	// get respond-to object and free the ressource
	response_object = this.requests[id].object;
	response_object.exe = this.requests[id].notifier;
	this.requests[id].object = null;
	this.requests[id].notifier = null;
	// if request could not be executed
	if(!state) {
		response_object.exe(false);
	}
	else {
		try {
			// xmlHttp.status will throw an exception under certain conditions, this was the only way I found to catch it
			this.requests[id].xmlHttp.status;
			if(this.requests[id].xmlHttp.status == 200) {

				this.requests[id].status = this.requests[id].xmlHttp.status;
				this.requests[id].statusText = this.requests[id].xmlHttp.statusText;
				this.requests[id].result = this.requests[id].xmlHttp.responseXML;

				Util.debug("responseText:"+this.requests[id].xmlHttp.responseText.trim());
				Util.debug("###");

				this.requests[id].resultText = this.requests[id].xmlHttp.responseText.trim();
				this.requests[id].xmlHttp = null;
				// relocate request to response
				response = this.requests[id];
				response_object.exe(response);
			}
			else {
				response_object.exe(false);
			}
		}
		catch(e) {
			if(this.requests[id]) {
				response_object.exe(false);
			}
		}
	}
	// reset request
	Util.Ajax.requests[id] = null;
}

// Load new container into predefined target
Util.Ajax.loadContainer = function(url, target_id, parameters) {
	var target = document.getElementById(target_id);
	parameters = (typeof(parameters) != "undefined" ? parameters + "&" : "");
	this.send(url, this.replaceElement, target, parameters);
}
// Replace element child with request response
// (function can be attached to child.parentNode, used with this.replaceElement)
Util.Ajax.replaceElementChild = function(response, child) {
	var component;
	if(response) {
		component = Util.Ajax.validateResult(response.resultText);

		// did we get a response container?
		if(typeof(component) == "object") {
			this.replaceChild(component, child);

			// initialize component
			Util.initElements(component.parentNode);
			return true;
		}
		// otherwise return default error (not implemented yet)
		else {
			Util.debug("Something is all wrong with the response!!!");
			Util.debug("Response:"+response.resultText);
			Util.debug("###")
			return false;
		}
	}
	else {
		Util.debug("No response!!!");
		return false;
	}
}
// Replace element with request response element (function is attached to element)
// commonly used as response handler
Util.Ajax.replaceElement = function(response) {
	this.parentNode.replaceElementChild = Util.Ajax.replaceElementChild;
	this.parentNode.replaceElementChild(response, this);
}

// Simple validation of response
// automatically executes script elements
// returns content element
Util.Ajax.validateResult = function(result){
	var valid, content_element, script_elements, child, i;

	this.validateElement = typeof(this.validateElement) == "object" ? this.validateElement : document.createElement("div");
	// IE ignores script-tags in the begining of result, unless an extra &nbsp; is added
	if(Util.explorer()) {
		this.validateElement.innerHTML = "&nbsp;"+result;
	}
	else {
		this.validateElement.innerHTML = result;
	}
	content_element = this.validateElement.getElementsByTagName("div").length ? this.validateElement.getElementsByTagName("div")[0] : false;

	script_elements = new Array();
	// only use root level script tags
	for(i = 0; child = this.validateElement.childNodes[i]; i++) {
		if(child.nodeName.toLowerCase() == "script") {
			script_elements = script_elements.unshiftElement(child);
		}
	}

	// execute script elements
	this.executeScript(script_elements);
	// return content element
	return content_element;
}
// Execute script response
Util.Ajax.executeScript = function(script_elements) {
	var script, script_i;
	if(script_elements.length) {
		for(i = script_elements.length-1; i >= 0; i--) {
			// W3C
			if(script_elements[i].firstChild && script_elements[i].firstChild.nodeValue) {
				eval(script_elements[i].firstChild.nodeValue);
			}
			// IE
			else if(Util.explorer() && script_elements[i].text) {
				eval(script_elements[i].text);
			}
		}
	}
}

// Check the returned value (for debugging purposes)
Util.Ajax.check = function(response) {
	if(response) {
		Util.debug(response.status+","+response.resultText+","+response.result);
	}
	else {
		alert("failed");
	}
}