var O = {
	init: function() {
		window.addEvent("domready", O.onDOMReady);
		/*@cc_on
		@if (@_jscript_version < 5.7)
			this.isIE6 = true;
			try {
				document.execCommand("BackgroundImageCache", false, true);
			} catch (e) {}
		@end
		@if (@_jscript_version == 5.7)
			this.isIE7 = true;
		@end @*/
		var html = document.getElementsByTagName("html")[0];
		html.className += html.className.length === 0 ? "javascript" : " javascript";
	},
	
	onDOMReady: function() {},
	
	addOnDOMReady: function(fn) {
		window.addEvent("domready", fn);
	},
	
	getClassNameValue: function(el, prefix) {
		var ret = new RegExp(".*" + prefix + "-(.*?)(?:\\s|$).*").exec(el.className);
		if (ret) {
			return ret[1];
		}
		return null;
	},
	
	getAnchoredElement: function(anchor) {
		return $$(anchor.href.replace(/.*\#(.*)/, "$1"));
	},

	getActualWidth: function(elem) {
		elem = $(elem);
		var margin = O.stripPx(elem.getStyle("margin-left")) + O.stripPx(elem.getStyle("margin-right"));
		return elem.offsetWidth + margin;
	},

	getActualHeight: function(elem) {
		elem = $(elem);
		var margin = O.stripPx(elem.getStyle("margin-bottom")) + O.stripPx(elem.getStyle("margin-top"));	
		return elem.offsetHeight + margin;
	},
	
	getPosition: function(el, el2) {
		var pos = {x: 0, y: 0};
		while (el.offsetParent && el != el2) {
			pos.x += el.offsetLeft;
			pos.y += el.offsetTop;
			el = el.offsetParent;
		}
		return pos;
	},

   scrollTo: function(elm) {
       var position = O.getPosition(elm);
       window.scrollTo(position.x, Math.max(position.y - 20, 0));
   },
   
   stripPx: function(str) {
		var value = parseInt(str.substring(0, str.length - 2));
		if (isNaN(value)) {
			return 0;
		}
		return value;
	},
	
	trim: function(str) {
		return str.replace(/^\s+|\s+$/g, "");
	},

	numericStrip: function(str) {
		return str.replace(/ |-|\/|\.|\+/gi, "");
	},

	addParameter: function(url, name, value) {
		return url + (url.indexOf("?") < 0 ? "?" : "&") + name + "=" + value;
	},

	getFirstNode: function(node) {
		return node.firstChild.nodeType == 3 ? node.childNodes[1] : node.firstChild;
	},
	
	debug: function(str) {
		if (str !== null) {
			str = str + "";
			if (!$("debug")) {
				$(document.body).grab(new Element("div", {
					id: "debug", 
					style: "position: absolute; right: 0; top: 50px; font: 11px verdana; background: white; padding: 10px; background: white; opacity: .5; z-index: 99999999;"
				}), 
				"top");
			}
			str = str.replace(">", "&gt;");
			str = str.replace("<", "&lt;");
			$("debug").innerHTML += str + "<br/>";
		}
	},
	
	readCookie: function(name) {
		var cookie = document.cookie.split(";");
		for (var i = 0, l = cookie.length; i < l; i++) {
			var c = cookie[i];
			while (c.charAt(0) == " ") c = c.substring(1, c.length);
			if (c.indexOf(name + "=") == 0) return unescape(c.substring((name + "=").length, c.length));
		}
		return null;
	},
	
	writeCookie: function(name, value, days) {
		var expires = "";
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			var expires = "; expires=" + date.toGMTString();
		}
		document.cookie = name + "=" + escape(value) + "; expires=" + expires + "; path=/";
		return value;
	},
	
	getViewPortHeight: function() {
		return window.innerHeight ? window.innerHeight : document.documentElement.clientHeight;
	},
	
	getViewPortWidth: function() {
		return window.innerWidth ? window.innerWidth : document.documentElement.clientWidth;
	}
};


/**
 * Event delegation
 */
O.eventHandler = function() {
	var events = [];
	
	var onEvent = function(e) {
		var triggerEvents = events[e.type];
		if (triggerEvents) {
			var target = e.target;
			if (e.type == "click") {
				if ((e.which && e.which != 1) || 
					(e.button && e.button !== 0)) {
					return true;
				}	
			}
			for (var i = triggerEvents.length - 1; i >= 0; i--) {
				var match = getMatch(target, triggerEvents[i].selector);
				if (match !== null) {
					if (e.type == "click" && (e.which || e.button)) {
						target.blur(); // only do blur if clicked with mouse...
					}
					var callbackValue = triggerEvents[i].fn.call(match, e);
					if (typeof callbackValue === "undefined") {
						callbackValue = false;
					}
					if (!callbackValue) {
						e.preventDefault();
						return false;
					}
				}
			}
			if (e.type == "mouseover" || 
				e.type == "mouseout") {
				return false;
			}		
		}
	};
	
	var getMatch = function(el, selector) {
		var matchingEl = null;
		var noOfElms = selector.length - 1;
		var matchedSelector = false;
		for (var i = noOfElms; i >= 0; i--) {
			matchedSelector = false;
			while (!matchedSelector && el.parentNode) {
				var match = true;
				if (selector[i].tag && selector[i].tag != el.tagName) {
					match = false;
				} else if (selector[i].id && selector[i].id != el.id) {
					match = false;
				} else if (selector[i].className && !selector[i].className.test(el.className)) {
					match = false;
				}
				if (matchingEl === null && match) {
					matchingEl = el;
				}
				matchedSelector = match;
				el = el.parentNode;
			}
		}
		if (!matchedSelector) {
			matchingEl = null;
		}
		return matchingEl;
	};
	
	var compileSelector = function(selector) {
		var compiled = [];
		var part = [];
		var key = "tag";
		var value = "";
		var ch;
		for (var i = 0, il = selector.length; i < il; i++) {
			ch = selector.charAt(i);
			if (i == selector.length - 1) {
				value += ch;
				ch = " ";
			}
			if (ch == " ") {
				part[key] = value;
				if (part.tag) {
					part.tag = part.tag.toUpperCase();
				}
				if (part.className) {
					part.className = new RegExp("(^|\\s)" + part.className + "(\\s|$)");
				}
				compiled.push(part);
				part = [];
				key = "tag";
				value = "";
			} else if (ch == "#") {
				part[key] = value;
				key = "id";
				value = "";
			} else if (ch == ".") {
				part[key] = value;
				key = "className";
				value = "";
			} else {
				value += ch;
			}
		}
		return compiled;
	};

	return {	
		register: function(trigger, selector, fn) {
			var triggerEvents = events[trigger];
			if (!triggerEvents) {
				triggerEvents = [];
				events[trigger] = triggerEvents;
				$(document).addEvent(trigger, onEvent);
			}
			triggerEvents.push({selector: compileSelector(selector), fn: fn});
		}
	};
}();


/**
 * Slider class
 * @param {Object} elem
 */
/*
O.slider = function(elem, duration, easing) {
	this.duration = duration || 500;
	this.easing = easing || O.easing.expoOut;
	this.elem = $(elem);
	this.wrapper = $(document.createElement("div"));
	this.wrapper.style.position = "relative";
	this.wrapper.style.overflow = "hidden";
	this.wrapper.style.height = "0";
	this.elem.style.display = "block";
	this.elemWidth = O.getActualWidth(this.elem);
	this.elemHeight = O.getActualHeight(this.elem);
	this.elem.parentNode.insertBefore(this.wrapper, this.elem);
	this.wrapper.appendChild(this.elem);
	this.elem.style.position = "absolute";
	this.elem.style.left = "0px";
	this.elem.style.bottom = "0px";
	this.elemWidthPadding = O.stripPx(elem.getStyle("padding-left")) + O.stripPx(elem.getStyle("padding-right"));
	this.isVisible = this.elem.hasClass("display");
	this.wrapper.style.width = (this.elemWidth) + "px";
	this.wrapper.style.height = (this.isVisible ? this.elemHeight : 0) + "px";
	this.elem.style.width = (this.elemWidth - this.elemWidthPadding) + "px";
	this.fullWidth = "auto";
	/--*@cc_on
		this.fullWidth = (this.elemWidth - this.elemWidthPadding) + "px";
	@*--/
};
O.slider.prototype.open = function(options) {
	var options = options ? options : {};
	var duration = options.duration || this.duration;
	var easing = options.easing || this.easing;
	var callback = options.callback || null;
	var force = options.force || false;

	if (!this.isInTransition || force) {
		this.isInTransition = true;
		this.elemWidth = O.getActualWidth(this.elem);
		this.elemHeight = O.getActualHeight(this.elem);
		var slider = this;
		this.wrapper.animate({ height: this.elemHeight }, { duration: duration, callback: function() { slider.isVisible = true; slider.isInTransition = false; slider.elem.style.position = "relative"; slider.elem.style.width = slider.fullWidth; this.style.height = "100%"; this.style.width = "100%"; if (callback) { callback(); } } });
	}
};
O.slider.prototype.close = function(options) {
	var options = options ? options : {};
	var duration = options.duration || this.duration;
	var easing = options.easing || this.easing;
	var callback = options.callback || null;
	var force = options.force || false;

	if (!this.isInTransition || force) {
		this.isInTransition = true;
		this.elemWidth = O.getActualWidth(this.elem);
		this.elemHeight = O.getActualHeight(this.elem);
		this.elem.style.position = "absolute";
		this.wrapper.style.width = this.elemWidth + "px";
		this.wrapper.style.height = O.getActualHeight(this.elem) + "px";
		this.elem.style.width = (this.elemWidth - this.elemWidthPadding) + "px";
		var slider = this;
		this.wrapper.animate({ height: 0 }, { duration: duration, callback: function() { slider.isVisible = false; slider.isInTransition = false; if (callback) { callback(); } } });
	}
};
O.slider.prototype.toggle = function(force, callback) {
	if (this.isVisible) {
		this.close(force, callback);
	} else {
		this.open(force, callback);
	}
};
*/


/**
 * Fix quotes for browsers that don't support css rules for changing content
 */
O.fixQuotes = function() {
	return {
		DOMReady: function() {
			$$("q").each(function(el) {
				var startQuote = document.createTextNode("\u201d");
				var endQuote = document.createTextNode("\u201d");
				el.insertBefore(startQuote, this.firstChild);
				el.appendChild(endQuote);
			});
		}
	}
}();


/**
 * Easing functions
 */
/*
O.easing = function() {
	return {
		expoOut: function(timediff, base, change, duration) {
			return (timediff == duration) ? base+change : change * (-Math.pow(2, -10 * timediff / duration) + 1) + base;
		}		
	};
}();
*/


/**
 * Form wrapper
 * @param {Object} form
 */
O.form = function() {
	var isInitialized = false;
	var init = function() {
		isInitialized = true;
		O.eventHandler.register("keyup", ".has-error", function() {
			validateField(this);
		});
	};
	var validateField = function(elm) {
		elm = $(elm);
		if (elm.hasClass("required") && (O.trim(elm.value) == "")) {
			elm.form.missing.push(elm);
			elm.form.hasErrors = true;
		} else if (elm.hasClass("accept-conditions") && !elm.checked) {
			elm.form.unaccepted.push(elm);
			elm.form.hasErrors = true;
		} else if (elm.hasClass("email") && O.trim(elm.value) != "" && elm.value.search(/(\w|\.|\-)+\@(\w|\.|\-)+\.[a-z]{2,6}$/)) {
			elm.form.erronous.push(elm);
			elm.form.hasErrors = true;
		} else if(elm.hasClass("numeric") && (/\D/).test(O.numericStrip(elm.value))) {
			elm.form.erronous.push(elm);
			elm.form.hasErrors = true;
		} else {
			elm.removeClass("has-error");
		}
	};
	var alertUser = function(form) {
		if (!form.alertBox) {
			form.alertBox = $(form).create("div", { className: "alert-box", style: DOMEffects.getOpacityRule(0) }, false);
		}
		form.alertBox.innerHTML = "<span class=\"alert-box-heading\">Vi kunde tyvärr inte skicka in formuläret</span><ul>";
		for (var e = 0, l = form.erronous.length; e<l; e++) {
			form.erronous[e].addClass("has-error");
			form.alertBox.innerHTML += "<li>Kontrollera att " + form.erronous[e].title + " är korrekt";
		}
		for (var e = 0, l = form.missing.length; e<l; e++) {
			form.missing[e].addClass("has-error");
			form.alertBox.innerHTML += "<li>Du verkar ha glömt " + form.missing[e].title;
		}
		for (var e = 0, l = form.unaccepted.length; e<l; e++) {
			form.alertBox.innerHTML += "<li>Du måste godkänna " + form.unaccepted[e].title;
		}
		form.alertBox.innerHTML += "</ul>";
		form.insertBefore(form.alertBox, form.firstChild);
		O.scrollTo(form);
		form.alertBox.show();
	}
	return {
		validate: function() {
			if (!isInitialized) {
				init();
			}
			var form = $(this);
			form.erronous = new Array();
			form.missing = new Array();
			form.unaccepted = new Array();
			form.hasErrors = false;
			
			form.cssSelect("input, textarea").each(function() {
				validateField(this);
			});
			
			if (form.hasErrors) {
				alertUser(form);
				return false;
			} else {
				return true;
			}
		}
	}
}();


/**
 * AJAX Form Class
 * @param {Object} form
 */
O.AJAXForm = function(form) {
	form = $(form);
	form.isAJAXForm = true;
	form.beforeSubmissionHandler = function () { return true; };
	form.addEvent("submit", O.AJAXForm.sendForm);
	form.setBeforeSubmissionHandler = function(fn) {
		this.beforeSubmissionHandler = fn;
	};
	form.setResponseHandler = function(fn) {
		this.responseHandler = fn;
	};
	return form;
};

O.AJAXForm.sendForm = function() {
	if (this.beforeSubmissionHandler.call(this) !== false) {
		var fields = this.elements;
		var parameters = "";
		for (var i = 0, il = fields.length, field, type, isSelect; i < il; i++) {
			field = fields[i];
			type = field.getAttribute("type");
			isSelect = /select/i.test(field.nodeName);
			if (field.getAttribute("name") && (/text|hidden|password|submit|image/i.test(type) || isSelect || (/radio|checkbox/i.test(type) && field.checked) || /textarea/i.test(field.nodeName))) {
				parameters += field.getAttribute("name") + "=" + encodeURIComponent(((isSelect)? field.options[field.selectedIndex].value : field.value)) + "&";
			}
		}
		parameters += "mode=ajax";
		new Request({
			url: this.getAttribute("action"),
			method: "post",
			data : parameters.replace(/&*$/g, ""),
			onComplete: this.responseHandler,
			headers : this.headers || {}
		}).send();
	}
	return false;
};

O.init();