/*
 * O.js
 * By Oktavilla (http://oktavilla.se)
 */
 
var O = {
	init: function() {
		DOMAssistant.DOMReady(O.onDOMReady);
		/*@cc_on
		@if (@_jscript_version < 5.7)
			try {
				document.execCommand("BackgroundImageCache", false, true);
				this.isIE6 = true;
			} catch (e) {}
		@end @*/
		var html = document.getElementsByTagName("html")[0];
		html.className += html.className.length === 0 ? "javascript" : " javascript";
	},
	
	onDOMReady: function() {},
	
	addOnDOMReady: function(fn) {
		DOMAssistant.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;
	},
	
	getActualOffset: function(elem) {
		var offsetY = 0, offsetX = 0;
		while (elem.offsetParent) {
			offsetX += elem.offsetLeft;
			offsetY += elem.offsetTop;	
			elem = elem.offsetParent;
		}
		return {x: offsetX, y: offsetY};
	},

	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;
	},
	
	isVisible: function(el) {
		while (el.parentNode) {
			if ($(el).getStyle("display") == "none" || $(el).getStyle("visibility") == "hidden") {
				return false;
			}
			el = el.parentNode;
		}
		return true;
	},
	
	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).create("div", {
						id: "debug", 
						style: "position: absolute; right: 0; top: 50px; font: 11px verdana; background: white; padding: 10px; background: white; opacity: .5; filter: alpha(opacity = 50); z-index: 99999999;"
					},
					true
				);
			}
			str = str.replace(">", "&gt;");
			str = str.replace("<", "&lt;");
			$$("debug").create("div", null, true, str);
		}
	},
	
	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;
	}
};


/**
 * Event delegation
 */
O.eventHandler = function() {
	var events = [];
	
	var onEvent = function(e) {
		e = e || event;
		var triggerEvents = events[e.type];
		if (triggerEvents) {
			var target = e.eventTarget;
			if (!target) {
				target = e.target || e.srcElement || document;
			}
			if (target != null) {
				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 (triggerEvents[i].exactMatch && e.target != match) {
							continue
						}
						if (e.type == "click" && (e.which || e.button) && target.nodeName == "A") {
							target.blur();
						}
						var callbackValue = triggerEvents[i].fn.call(match, e);
						if (typeof callbackValue === "undefined") {
							callbackValue = false;
						}
						if (!callbackValue) {
							DOMAssistant.preventDefault(e);
							return false;
						}
					}
				}
				if (e.type == "mouseover" || 
					e.type == "mouseout") {
					return false;
				}
			}
			return true;
		}
	};
	
	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 && 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) {
				break;
			}
		}
		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, exactMatch) {
			if (selector.constructor == Array) {
				for (var i = 0, ln = selector.length; i < ln; i++) {
					O.eventHandler.register(trigger, selector[i], fn);
				}
				return;
			}
			if ((trigger == "focus" || trigger == "blur") && !document.addEventListener) {
				trigger = (trigger == "focus") ? "focusin" : "focusout";
			}
			var triggerEvents = events[trigger];
			if (!triggerEvents) {
				triggerEvents = [];
				events[trigger] = triggerEvents;
				if (trigger == "focus" || trigger == "blur") {
					document.addEventListener(trigger, onEvent, true);						
				} else {
					$(document).addEvent(trigger, onEvent);
				}
			}
			triggerEvents.push({selector: compileSelector(selector), fn: fn, exactMatch: exactMatch ? true : false});
		}
	};
}();


/**
 * 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() {
				var startQuote = document.createTextNode("\u201d");
				var endQuote = document.createTextNode("\u201d");
				this.insertBefore(startQuote, this.firstChild);
				this.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) {
		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) {
		var alertText = "";
	
		if (!form.alertBox) {
			form.alertBox = $(form).create("div", { className: "alert-box", style: DOMEffects.getOpacityRule(0) }, false);
		}
		alertText = "<span class=\"alert-box-heading\">Vi kunde tyv&auml;rr inte skicka in formul&auml;ret</span><ul>";
		for (var e = 0, l = form.erronous.length; e<l; e++) {
			form.erronous[e].addClass("has-error");
			alertText += "<li>Kontrollera att " + form.erronous[e].title + " &auml;r korrekt";
		}
		for (var e = 0, l = form.missing.length; e<l; e++) {
			form.missing[e].addClass("has-error");
			alertText += "<li>Du verkar ha gl&ouml;mt " + form.missing[e].title;
		}
		for (var e = 0, l = form.unaccepted.length; e<l; e++) {
			alertText += "<li>Du m&aring;ste godk&auml;nna " + form.unaccepted[e].title;
		}
		alertText += "</ul>";
		form.alertBox.innerHTML = alertText;
		form.insertBefore(form.alertBox, form.firstChild);
		O.scrollTo(form);
		form.alertBox.show();
	}
	return {
		validate: function(form) {
			if (!isInitialized) {
				init();
			}
			if (!form || !form.tagName) {
				form = this;
			}
			form.erronous = new Array();
			form.missing = new Array();
			form.unaccepted = new Array();
			form.hasErrors = false;
			
			$(form).cssSelect("input, textarea").each(function() {
				if (O.isVisible(this)) {
					validateField(this);
				}
			});
			
			if (form.hasErrors) {
				alertUser(form);
				return false;
			} else {
				return true;
			}
		}
	}
}();


/**
 * AJAX Form Class
 * @param {Object} form
 */
O.AJAXForm = function(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 += "ajax=true";
		this.ajax({
			url : this.getAttribute("action"),
			method: "POST",
			params : parameters.replace(/&*$/g, ""),
			callback : this.responseHandler,
			headers : this.headers || {}
		});
	}
	return false;
};


O.QueryString = function() {
	var data = null;
	var exp = new RegExp("([^?=&]+)(=([^&]*))?", "g");
	var init = function() {
		data = [];
		window.location.search.replace(exp, function(v0, v1, v2, v3) {
			data[v1] = v3;
		});
	}
	return {
		get: function(key) {
			if (data == null) {
				init();
			}
			return data[key];
		}
	}
}();


O.init();
