var AdList = {
	init: function() {
		var table = $('AdList');
		if (table)
			AdList.initTable(table);
	},
	
	initTable: function(table) {
		foreach (element.getChild(table, 'tbody').rows, function(tr) {
			var a = element.getChild(tr, 'a');
			if (a) {
				a.onclick = function() {
					//console.log(1);
					return false;
				}
			}	
			tr.onclick = function() {
				AdList.onClickRow(this);
			}
		});
	},
	
	onClickRow: function(tr) {
		var a = element.getChild(tr, 'a');
		if (a)
			window.location = a.href;
	}
}

addEvent(window, 'load', AdList.init);
var banners = {
	init: function() {
		foreach(getElementsByClassName('banner', 'a'), function(a) {
			a.onclick = function() {
				window.location = '/clickometer/?b=' + a.id.split('-')[1] + '&redir=' + escape(this.href);;
				return false;
			};
		});
	}
}

addEvent(window, 'load', banners.init);
/*
 * Funktioner för asynkrona anrop, AJAX.
 * Beroenden: form.js
 */

var ajax = {
	_ajaxReqs: {},

	/*
	 * Gör ett anrop till url. Funktionen fn anropas med svar från server i form av en sträng.
	 * Om funktionen errorFn tillhandahålls anropas den med resultat från server vid error, annars används defaultErrorHandler.
	 */	
	getString: function(url, fn, errorFn) {
		ajax._doIt(url, false, fn, errorFn, false);
	},

	/*
	 * Gör ett anrop till url. Parametersträngen postStr postas med anropet. Funktionen fn anropas med svar från server i form av en sträng.
	 * Om funktionen errorFn tillhandahålls anropas den med resultat från server vid error, annars används defaultErrorHandler.
	 */
	postString: function(url, postStr, fn, errorFn) {
		ajax._doIt(url, postStr, fn, errorFn, false);
	},

	/*
	 * Gör ett anrop till url. Funktionen fn anropas med svar från server i form av et Json-objekt.
	 * Om funktionen errorFn tillhandahålls anropas den med resultat från server vid error, annars används defaultErrorHandler.
	 */		
	getJson: function(url, fn, errorFn) {
		ajax._doIt(url, false, fn, errorFn, true);
	},	
	
	/*
	 * Gör ett anrop till url. Parametersträngen postStr postas med anropet. Funktionen fn anropas med svar från server i form av ett Json-objekt.
	 * Om funktionen errorFn tillhandahålls anropas den med resultat från server vid error, annars används defaultErrorHandler.
	 */	
	postJson: function(url, postStr, fn, errorFn) {
		ajax._doIt(url, postStr, fn, errorFn, true);
	},

	/*
	 * Avbryt samtliga anrop.
	 */
	abortAll: function() {
		for (var url in ajax._ajaxReqs) {
			ajax._ajaxReqs[url].req.onreadystatechange = function() {};
			ajax._ajaxReqs[url].req.abort();			
		}
		ajax._ajaxReqs = {};
	},
	
	_doIt: function(url, postStr, fn, errorFn, useJson) {
		var req = ajax._getRequestObj(url, fn, errorFn);
		if (req) {
			
			// Works in IE only if whole statemant is in eval()
			eval("req.onreadystatechange = function() { ajax._processReqChange('" + url + "', " + (useJson ? "true" : "false") + "); }");
			
			req.open(postStr ? 'POST' : 'GET', url, true);
			if (postStr) {
				req.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");		
				req.send(postStr);
			} else {
				req.send('');
			}
		}	
	},
	
	_getRequestObj: function(url, fn, errorFn) {
		var req;
		if (window.XMLHttpRequest) {
			try {
				req = new XMLHttpRequest();
			} catch(e) {
				req = null;
			}
		} else if (window.ActiveXObject) {
			try {
				req = new ActiveXObject('Msxml2.XMLHTTP');
			} catch(e) {
				try {
					req = new ActiveXObject('Microsoft.XMLHTTP');
				} catch(e) {
          			req = null;
        		}
			}
		}
		if (req) {
			ajax._ajaxReqs[url] = { req: req, handler: fn, errorHandler: (errorFn ? errorFn : ajax._defaultErrorHandler) };
		}
		return req;
	},	
	
	_processReqChange: function(url, returnJson) {
		var ar = ajax._ajaxReqs[url];
		if (ar && (ar.req.readyState == 4)) { // readyState 4 = "loaded".
			if (ar.req.status == 200) { // status is "OK"
				if (returnJson)
					ar.handler(eval('(' + ar.req.responseText + ')'));
				else
					ar.handler(ar.req.responseText);				
			} else {
				ar.errorHandler(ar.req.responseText);
			}
		}
	},
	
	_defaultErrorHandler: function(errText) {
		alert("Ett fel har inträffat.");
	}	
}
/*
 * Funktioner för animering av element.
 * Beroenden: element.js
 */

var animation = {

	/*
	 * Ändra bredden på elementet el till width under duration millisekunder.
	 * Efter svslut anropas runAfter, om tillhandahållen.
	 */
	width: function(el, width, duration, runAfter) {
		var startWidth = element.getWidth(el);
		var diff = width - startWidth;
		var frequency = 1 / duration;
		var startTime = new Date().getTime();
		var tmr = setInterval(function() {
			var wi = width;
			var elapsedTime = new Date().getTime() - startTime;
			if (elapsedTime < duration)
				wi = elapsedTime * frequency * diff + startWidth;
			else
				clearInterval(tmr);
			wi = Math.round(wi)
			el.style.width = wi + 'px';
			if (wi == width && runAfter)
				runAfter();	
		}, 10);
	}
}
/*
 * Funktioner för hantering av kakor.
 */

var cookies = {

	/*
	 * Skapa kaka med namn name och värde value. Om days tillhandahålls sparas kakan hos klienten i days dagar,
	 * annars endast under pågående session.
	 */
	create: function(name, value, days) {
		var expires = '';
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			expires = '; expires=' + date.toGMTString();
		}
		document.cookie = name + "=" + value + expires + '; path=/';
	},

	/*
	 * Läs värde från kaka med namn name. Om kaka saknas returneras null.
	 */
	read: function(name) {
		var nameEQ = name + '=';
		var ca = document.cookie.split(';');
		for(var i = 0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0) == ' ') c = c.substring(1, c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
		}
		return null;
	},
	
	/*
	 * Radera kaka med namn namn.
	 */
	erase: function(name) {
		cookies.create(name, '', -1);
	}
}

/*
 * Funktionen för hantering av webläsarens display.
 * Beroenden: element.js
 */

var display = {

	/*
	 * Returnerar pixelbredden på displayen eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getWidth: function() {
		if (window.innerWidth) return window.innerWidth;
		if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
		if (document.body) return document.body.clientWidth;
		return 0;		
	},

	/*
	 * Returnerar pixelhöjden på displayen eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getHeight: function() {
		if (window.innerHeight) return window.innerHeight;
		if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
		if (document.body) return document.body.clientHeight;
		return 0;	
	},
	
	/*
	 * Returnerar displayens pixelförskjutning av rullning i sidled eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getLeft: function() {
		if (window.pageXOffset) return window.pageXOffset;
		if (document.documentElement && document.documentElement.scrollLeft) return document.documentElement.scrollLeft;
		if (document.body) return document.body.scrollLeft;
		return 0;		
	},
	
	/*
	 * Returnerar displayens pixelförskjutning av rullning i höjdled eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getTop: function() {
		if (self.pageYOffset) return self.pageYOffset;
		if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop;
		if (document.body) return document.body.scrollTop;
		return 0;	
	},
	
	/*
	 * Döljer rullningslister.
	 */
	hideScrollBars: function() {
		element.getHtmlElement().style.overflow = 'hidden';
	},
	
	/*
	 * Visar rullningslister.
	 */
	showScrollBars: function() {
		element.getHtmlElement().style.overflow = 'auto';
	}	
}
/*
 * Funktioner för hantering av element
 */

var element = {
	_theBodyElement: null,
	_theHtmlElement: null,
	_uniqueID: 0,
	
	ELEMENT_NODE: 1,
	TEXT_NODE: 3,
	
	getID: function(el) {
		if (!el.id)
			el.id = '_uniqueID' + element._uniqueID++;
		return el.id;
	},
	
	/*
	 * Hämta body-elementet i nuvarande dokument.
	 */
	getBodyElement: function() {
		if (!element._theBodyElement)
			element._theBodyElement = element.getChild(document, 'body');
		return element._theBodyElement;
	},

	/*
	 * Hämta html-elementet i nuvarande dokument.
	 */
	getHtmlElement: function() {
		if (!element._theHtmlElement)
			element._theHtmlElement = element.getParent(element.getBodyElement(), 'html');
		return element._theHtmlElement;
	},

	/*
	 * Hämta elementet el:s första påträffade föräldrarelement med namnet elementName eller el själv om el har namnet elementName.
	 */
	getParent: function(el, elementName) {
		if (!el) return null;
		if (el.nodeType == element.ELEMENT_NODE && el.tagName.toLowerCase() == elementName.toLowerCase()) return el;
		return element.getParent(el.parentNode, elementName);		
	},

	isChildOf: function(el, parent) {
		if (!el || !parent) return null;
		if (!el.parentNode) return false;
		if (el.parentNode == parent) return true;
		return element.isChildOf(el.parentNode, parent);
	},
	
	/*
	 * Hämta elementet el:s n:e "äldtsta" barnelement med namnet elementName eller el själv om el har namnet elementName.
	 * Om n ej tillhandahålls sätts n till 1.
	 */
	getChild: function(el, elementName, n) {
		if (!el) return null;
		if (!n) n = 1;
		if (el.nodeType == element.ELEMENT_NODE && el.tagName.toLowerCase() == elementName.toLowerCase()) return el;
		if (el.childNodes) {
			for (var i = 0; i < el.childNodes.length; i++) {
				var e = element.getChild(el.childNodes[i], elementName);
				if (e)
					if (--n == 0) return e;
			}
		}
		return null;
	},

	/*
	 * Hämta elementet el:s n:e "yngsta" påträffade barnelement med namnet elementName eller el själv om el har namnet elementName.
	 * Om n ej tillhandahålls sätts n till 1.
	 */
	getLastChild: function(el, elementName, n) {
		if (el == null) return null;
		if (!n) n = 1;
		if (el.nodeType == element.ELEMENT_NODE && el.tagName.toLowerCase() == elementName.toLowerCase()) return el;
		if (el.childNodes) {
			for (var i = el.childNodes.length; i > 0; --i) {
				var e = element.getChild(el.childNodes[i], elementName);
				if (e)
					if (--n == 0) return e;
			}
		}
		return null;
	},	

	/*
	 * Raderar elementet el.
	 */
	remove: function (el) {
		el.parentNode.removeChild(el);
	},
	
	/*
	 * Raderar alla barnnoder till elementet el.
	 */
	removeChildren: function (el) {
		while (el.hasChildNodes())
			el.removeChild(el.lastChild);
	},
	
	/*
	 * Dölj elementet el.
	 */
	hide: function(el) {
		el.style.display = 'none';
	},
	
	/*
	 * Vis elementet el.
	 */
	show: function(el) {
		el.style.display = '';
	},	
	
	/*
	 * Hämta elementet el:s nästa syskonelement.
	 */
	getNextSibling: function(el) {
		do
			el = el.nextSibling;
		while (el && el.nodeType != element.ELEMENT_NODE);
		return el;		
	},
	
	/*
	 * Hämta elementet el:s föregående syskonelement.
	 */
	getPreviousSibling: function(el) {
		do
			el = el.previousSibling;
		while (el && el.nodeType != element.ELEMENT_NODE);
		return el;		
	},
	
	/*
	 * Kontrollera om elementet el har klassen className
	 */
	hasClass: function(el, className) {
		return el.className.match('\\b' + className + '\\b');
	},
	
	/*
	 * Förse elementet el med klassen className
	 */
	addClass: function(el, className)
	{
		if (!el.className.match('/\\b' + className + '\\b/' ))
			el.className += ' ' + className;
	},
	
	/*
	 * Befria elementet el från klassen className
	 */
	removeClass: function(el, className) {
		el.className = el.className.replace(new RegExp('\\b' + className + '\\b', 'g'), '');
	},

	/*
	 * Hämta innehållet i alla textnoder under elementet el. Om parseSubNodes = true hämtas även barn-noders textinnehåll rekursivt.
	 */
	getInnerText: function(el, parseSubNodes) {
		if (typeof el == 'string') return el;
		if (typeof el == 'undefined') return el;
		var str = '';
		for (var i = 0; i < el.childNodes.length; i++) {
			switch (el.childNodes[i].nodeType) {
				case element.ELEMENT_NODE:
					if (parseSubNodes)
						str += element.getInnerText(el.childNodes[i], true);
					break;
				case element.TEXT_NODE:
					str += el.childNodes[i].nodeValue;
					break;
			}
		}
		return str;
	},
	
	/*
	 * Ersätter alla noder under elementet el med en textnod med innehåller content.
	 */
	setInnerText: function(el, content) {
		element.removeChildren(el);
		var n = document.createTextNode(content);
		el.appendChild(n);
	},
	
	/*
	 * Hämtar elementet el:s pixelavstånd från displayens övre kant eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getTopPos: function(el) {
		var c = 0;
		if (el.offsetParent) {
			while (el.offsetParent) {
				c += el.offsetTop
				el = el.offsetParent;
			}
		} else if (el.y) {
			c += el.y;
		}
		return c;
	},
	
	/*
	 * Hämtar elementet el:s pixelavstånd från displayens vänstra kant eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getLeftPos: function(el)	{
		var c = 0;
		if (el.offsetParent) {
			while (el.offsetParent) {
				c += el.offsetLeft
				el = el.offsetParent;
			}
		} else if (el.x) {
			c += el.x;
		}
		return c;
	},

	/*
	 * Hämtar elementet el:s pixelhöjd eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getHeight: function(el) {
		var c = 0;
		if (el.offsetHeight) {
			while (el.offsetHeight) {
				c += el.offsetHeight;
				el = el.offsetHeight;
			}
		}
		else if (el.height) {
			c += el.height;
		}
		return c;
	},

	/*
	 * Hämtar elementet el:s pixelbredd eller 0 om webbläsarkompatiblitet ej kan detekteras.
	 */
	getWidth: function(el) {
		var c = 0;
		if (el.offsetWidth) {
			while (el.offsetWidth) {
				c += el.offsetWidth;
				el = el.offsetWidth;
			}
		}
		else if (el.width) {
			c += el.width;
		}
		return c;
	}
}
/*
 * Funktioner för att hantera HTML-formulär.
 */

var form = {
	
	/*
	 * Hämta formulär-värden i form av en sträng (name1=value1&name2=value2) 
	 * frm är ett form-element.
	 * Lånat från http://www.devarticles.com/c/a/XML/XML-in-the-Browser-Submitting-forms-using-AJAX/5/
	 */	
	getFormValues: function(frm) {
		var str = '';

		foreach (frm.elements, function(el) {
			if (el.name && !el.disabled) {
				str += el.name + '=';
				switch (el.type) {					
					case 'text':
					case 'hidden':
						str += encodeURIComponent(el.value);
					break;
					case 'select-one':
						str += el.options[el.selectedIndex].value;
					break;
				}
				str += '&';
			}
		});
		str = str.substr(0, (str.length - 1));

		return str;
	}
}
/*
 * Global functions
 */

/*
 * Kortvariant av document.getElementById()
 */
function $(id) {
	return document.getElementById(id);
}

/*
 * Utför funktionen fn med i tur och ordning varje värde i arrayen array som parameter.
 */
function foreach(array, fn) {
	for (var i = 0; i < array.length; i++)
		fn(array[i]);
}

/*
 * Kontrollerar om obj är en array
 */
function isArray(obj) {
	return obj.constructor == Array;
}

function addEvent(el, eventType, listener) {
	var r = false;
	if (el.addEventListener) {
		el.addEventListener(eventType, listener, false);
		r = true;
	} else if (el.attachEvent) {
		r = el.attachEvent('on' + eventType, listener);
	}
	return r;
}

/*
 * Stoppar nuvarande event
 */
function stopEvent(e) {
    e = e || window.event;
    if (e.stopPropagation) {
		e.stopPropagation();
		e.preventDefault();
	}
    return false;
}

function getElementsByClassName(className, tag, elm){
	var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
	var tag = tag || "*";
	var elm = elm || document;
	var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
	var returnElements = [];
	var current;
	var length = elements.length;
	for(var i=0; i<length; i++){
		current = elements[i];
		if(testClass.test(current.className)){
			returnElements.push(current);
		}
	}
	return returnElements;
}
/*
 * URI-funktioner
 */

var uri = {

	/*
	 * Extrahera katalog- och parameterdel från url:en s.
	 * Exempel: Katalog- och parameterdel i http://www.example.com/folder/file.html?a=1&b=2 är /folder/
	 * Om s ej tillhandahålls används QueryString från aktuell url.
	 */
	getDir: function(s) {
		s = s || window.location;
		var s = uri.getPathAndQuery(s);
		return s.substring(0, s.lastIndexOf('/')) + '/';	
	},

	/*
	 * Extrahera katalog- och parameterdel från url:en s.
	 * Exempel: Katalog- och parameterdel i http://www.example.com/folder/file.html?a=1&b=2 är /folder/file.html?a=1&b=2
	 * Om s ej tillhandahålls används QueryString från aktuell url.
	 */
	getPathAndQuery: function(s) {
		s = s || window.location;
		s = String(s).substring(8);	
		return s.substring(s.indexOf('/'));
	},

	/*
	 * Extrahera ordlista med parametrarna ur parametersträngen s.
	 * Om s ej tillhandahålls används parameterdelen från aktuell url.
	 */	
	getQuery: function(s) {
		s = s || window.location;
		var dict = new Object;
		var ss = String(s).split('?');		
		if (ss.length == 2) {
			foreach(ss[1].split('&'), function(q) {
				var qs = q.split('=');
				dict[qs[0]] = qs[1];
			});
		}
		return dict;
	}	
}
var formValidation = {
	init: function() {
		foreach (document.getElementsByTagName('form'), function(form) {
			formValidation.initForm(form);
		});
	},
	
	initForm: function(form) {
		formValidator.init(form);
		/*for (var key in formValidator.formInfos[element.getID(form)].fields) {
			var invalid = $(key + '-invalid');
			var v = element.getInnerText(invalid);
			//element.setInnerText(invalid, towork.isIE ? ' ' : '');
			eval("invalid.onmouseover = function() { toolTip.open('" + v + "'); }");
			invalid.onmouseout = toolTip.close;
		}*/	
	}
}

addEvent(window, 'load', function() {
	formValidation.init();
});/*
 * This version 2007-01-24
 *
 * LIMITATIONS:
 *  Names must be unique (<input name="[unique name]">).
 */

var formValidator = {
	formInfos: {},
	
	onChangeEvent: function() {
		if (formValidator.formInfos[this.form.id].fields[this.name].validated)
			this.onblur();
	},
	
	/*
	 * Initializes the specified form
	 */
	init: function(frm) {
		frm.onsubmit = function() {
			return formValidator.validateAll(frm);
		};
	
		var formInfo = { groups: {}, fields: {} };
		formValidator.formInfos[element.getID(frm)] = formInfo;

		foreach(frm.getElementsByTagName('select'), function(f) {
			formValidator.setupField(formInfo, f);
		});		
		foreach(frm.getElementsByTagName('input'), function(f) {
			formValidator.setupField(formInfo, f);
		});
		foreach(frm.getElementsByTagName('textarea'), function(f) {
			formValidator.setupField(formInfo, f);
		});
	},
	
	setupField: function(formInfo, f) {
		if (f.name) {
			foreach(f.className.split(' '), function(className) {
				if (className.substring(0, 9) == 'validate-') {

					f.onblur = function() { formValidator.validateField(this); };
					
					if (f.type == 'checkbox')
						f.onclick = formValidator.onChangeEvent;
					else if (f.type == 'select-one' || f.type == 'select-multiple')
						f.onclick = formValidator.onChangeEvent;
					else
						f.onkeyup = formValidator.onChangeEvent;
					
					var fieldInfo = { eventListeners: new Array(), invalidTextElement: $(f.id + '-invalid'), validated: false }
					
					var parts = className.split('-');
					for (var p	= 1; p < parts.length; p++) {
						switch (parts[p]) {
							case 'mandatory':
								fieldInfo.eventListeners.push(formValidator.validateMandatory);
							break;
							case 'mandatoryGroup':
								var groupName = parts[++p];
								if (!formInfo.groups[groupName])
									formInfo.groups[groupName] = new Array();
								formInfo.groups[groupName].push(f);
								fieldInfo.eventListeners.push(formValidator.validateMandatoryGroup);
							break;
							case 'email':
								fieldInfo.eventListeners.push(formValidator.validateEmail);
							break;
							case 'minlength':
								p++;
								fieldInfo.eventListeners.push(formValidator.validateMinLength);
							break;							
							case 'match':
								p++;
								fieldInfo.eventListeners.push(formValidator.validateMatch);
							break;
							case 'module10':
								fieldInfo.eventListeners.push(formValidator.validateModule10);
							break;
							case 'vatno':
								fieldInfo.eventListeners.push(formValidator.validateModule10); // TODO
							break;
							case 'personalno':
								fieldInfo.eventListeners.push(formValidator.validateModule10); // TODO
							break;																
						}
					}
					formInfo.fields[f.name] = fieldInfo;					
				}
			});
		}	
	},
	
	/*
	 * Validates the specified field and shows or hides the associated error text element depending on outcome.
	 */
	validateField: function(field) {
		var valid = true;
		var fi = formValidator.formInfos[field.form.id].fields[field.name];
		foreach(fi.eventListeners, function(fn) {
			if (valid) {
				if (!fn(field))
					valid = false;
			}
		});
		fi.validated = true;
		if (fi.invalidTextElement)
			fi.invalidTextElement.style.display = valid ? 'none' : 'inline';
		return valid;
	},	

	//TODO: Don't allow hyphen as first or last character in domain name part.
	validateEmail: function(field) {
		if (!field.value)
			return true;	
	
		var validCharsPostAt = 'abcdefghijklmnopqrstuvwxyz0123456789-';
		var validChars = validCharsPostAt + "!£#$%&'*+-/=?^_`{|}~";
		var foundAt = false;
		var foundDotAfterAt = false;
		var lastc = '';
		var email = field.value.toLowerCase();

		for (var i = 0; i < email.length; i++) {
			var c = email.charAt(i); // Indexer does not work in IE!
			if (c == '@') {
				if (foundAt || lastc == '.' || i == 0)
					return false;
				foundAt = true;
				validChars = validCharsPostAt
			} else if (c == '.') {
				if (lastc == '.' || lastc == '@' || i == 0 || i == field.value.length - 1)
					return false;
				foundDotAfterAt = foundAt;
			} else if (validChars.indexOf(c) < 0) {
				return false;
			}
			lastc = c;
		}
		
		if (!(foundAt && foundDotAfterAt))
			return false;
		
		return true;
	},
	
	validateMandatory: function(field) {
		var type = field.type.toLowerCase();
		if (type == 'text' || type == 'password' || type == 'textarea' || type == 'file')
			return field.value;
		if (type == 'checkbox')
			return field.checked;
		if (type == 'select-one' || type == 'select-multiple')
			return field.value;
		return true;
	},
	
	validateMandatoryGroup: function(field) {
		var groupName = formValidator.getParam(field.className, 'mandatoryGroup');
		if (groupName) {
			var v = false;
			var f = formValidator.formInfos[field.form.id];
			foreach(f.groups[groupName], function(input) {
				if (input.value) v = true;
			});
			return v;
		}
		return true;
	},
	
	validateMinLength: function(field) {
		var minLength = formValidator.getParam(field.className, 'minlength');
		var length =  field.value.length;
		return length == 0 || length >= minLength;
	},	
	
	validateMatch: function(field) {
		var match = formValidator.getParam(field.className, 'match');
		if (match) {
			var f = $(match);
			if (f)
				return field.value == f.value;
		}
		return true;
	},
		
	validateModule10: function(field) {
		var sum = 0;
		for (var i = field.value.length - 1; i >= 0; i--) {
			var val = field.value.substring(i, i + 1) * (i % 2 - 2) * -1;
			if (val > 9)
				val -= 9;
			sum += val;
		}
		return sum % 10 == 0;
	},
	
	getParam: function(className, s) {
		var r = false;
		foreach(className.split(' '), function(cn) {
			if (cn.substring(0, 8) == 'validate') {
				var parts = cn.split('-');
				for (var i = 1; i <= parts.length; i++) {
					if (parts[i] == s) {
						if (++i <= parts.length)
							r = parts[i];
					}
				}
			}
		});
		return r;
	},
	
	validateAll: function(frm) {
		var valid = true;
		for (var key in formValidator.formInfos[frm.id].fields) {
			var field = document.getElementsByName(key)[0];
			if (!formValidator.validateField(field))
				valid = false;
		}
		return valid;
	},
	
	validatePart: function(part) {
		if (!part)
			return true;
		var valid = true;
		var frm = element.getParent(part, 'form');
		if (frm) {
			var fromInfo = formValidator.formInfos[frm.id];
			if (fromInfo) {
				for (var key in fromInfo.fields) {
					var field = document.getElementsByName(key)[0];
					if (element.isChildOf(field, part))
						if (!formValidator.validateField(field))
							valid = false;
				}
			}
		}
		return valid;
	}	
}
var smartForms = {
	
	uniqueId: 0,
	
	// dropdown vars
	dropdown_dictionary: null,
	dropdown_activeIpt: null,
	
	// postcode vars
	postcode_tmpForm: null,
	
	// date vars
	datePicker: null,
	datePicker_input: null,
	datePicker_tdIdPrefix: 'datePicker_',
	datePicker_year: null,
	datePicker_month: null,

	// init functions

	init: function() {
		foreach (document.getElementsByTagName('form'), function(form) {
			smartForms.initForm(form);
		});
	},

	// Note: The element need not be a form, but can also be any element within a form
	initForm: function(form) {
		foreach (form.getElementsByTagName('input'), function(el) {
			if (element.hasClass(el, 'num'))                   smartForms.initNum(el);
			if (element.hasClass(el, 'date'))                  smartForms.initDate(el);
			//if (element.hasClass(el, 'postCode'))              smartForms.initPostCode(el);
		});
	},

	/*initPostCode: function(el) {
		el.onkeyup = smartForms.postCode_getPostArea;
	},*/

	initNum: function(el) {
		el.onkeypress = smartForms.num_supressNonNumericKeys;
	},

	initDate: function(el) {
		el.onfocus = smartForms.date_focus;
		//el.onblur = smartForms.date_blur;
	},
	
	/*postCode_getPostArea: function() {
		if (this.value.length == 5) { //TODO: '5' is hard coded for sweden
			smartForms.postcode_tmpForm = this.form;
			ajax.getJson('/ajax/getPostArea.aspx?postCode=' + this.value, function(r) {
				var arr = getElementsByClassName('postArea', 'input', smartForms.postcode_tmpForm);
				if (arr.length > 0 && r.PostArea)
					arr[0].value = r.PostArea;
				arr = getElementsByClassName('region', 'input', smartForms.postcode_tmpForm);
				if (arr.length > 0 && r.Region)
					arr[0].value = r.Region;
				smartForms.postcode_tmpForm = null;
			});
		}
	},*/
	
	// num functions

	num_supressNonNumericKeys: function(e) {
		var key;
		if (window.event) 
			key = window.event.keyCode;
		else if (e)
			key = e.which;
		else
			return true;
		
		// Always pass control keys
		if ((key == null) || (key == 0) || (key == 8) || (key == 9) || (key == 13) || (key == 27))
			return true;
		
		// Pass numbers
		var keychar = String.fromCharCode(key);
		if ((("0123456789").indexOf(keychar) >= 0))
			return true;

		// Pass minus character at first position if input has class name "negative"
		// TODO: In some languages the minus character is written last instead of first.
		if (keychar == '-' && element.hasClass(this, 'negative') && this.value.length == 0)
			return true;
			
		// Pass decmial separator if input has class name "decimal" and string does not already contain one.
		if (keychar == decimalSeparator && element.hasClass(this, 'decimal') && this.value.indexOf(decimalSeparator) < 0)
			return true;		
		
		// Supress the rest
		return false;
	},
	
	// date functions
	
	date_focus: function() {
		smartForms.datePicker_input = this;
		smartForms.date_showPicker();
	},

	/*date_blur: function() {
		if (smartForms.datePicker) {
			var v = this.value;
			if (v.length == 4) {
				var date = new Date();
				this.value = date.year + '-' + v.substring(2, 4) + '-' + v.substring(4, 6);
			} if (v.length == 6) {
				this.value = '20' + v.substring(0, 2) + '-' + v.substring(2, 4) + '-' + v.substring(4, 6);
			} else if (v.length == 8) {
				this.value = v.substring(0, 4) + '-' + v.substring(4, 6) + '-' + v.substring(6, 8);
			}
			smartForms.date_hidePicker();
		}
	},*/

	date_showPicker: function() {
		smartForms.date_hidePicker();
	
		var firstDay = new Date();
		
		//Create div
		smartForms.datePicker = document.createElement('div');
		smartForms.datePicker.id = 'datePicker';
		
		//Get selected year and month
		if (!smartForms.datePicker_year) {
			smartForms.datePicker_year = firstDay.getFullYear();
			smartForms.datePicker_month = firstDay.getMonth();
		}
		
		//Determine first day of selected month	
		firstDay.setFullYear(smartForms.datePicker_year);
		firstDay.setMonth(smartForms.datePicker_month);
		firstDay.setDate(1);

		//Calculate offset
		var fd = firstDay.getDay() - 1;
		if (fd < 0) fd  = 6;
		var startDayOffset = -(fd);

		//Create year and month switchers
		var p = document.createElement('p');
		p.appendChild(smartForms.date_getImgLink('/cssnjs/forms/arrow-left.png', 6, 9, function() {
			smartForms.datePicker_year--;
			smartForms.date_showPicker();
			return false;
		}));
		p.appendChild(document.createTextNode(firstDay.getFullYear()));
		p.appendChild(smartForms.date_getImgLink('/cssnjs/forms/arrow-right.png', 6, 9, function() {
			smartForms.datePicker_year++;
			smartForms.date_showPicker();
			return false;
		}));
		p.appendChild(smartForms.date_getImgLink('/cssnjs/forms/arrow-left.png', 6, 9, function() {
			smartForms.datePicker_month--;
			if (smartForms.datePicker_month < 0) {
				smartForms.datePicker_month = 11;
				smartForms.datePicker_year--;
			}
			smartForms.date_showPicker();
			return false;
		}));
		p.appendChild(document.createTextNode(monthNames[firstDay.getMonth()]));
		p.appendChild(smartForms.date_getImgLink('/cssnjs/forms/arrow-right.png', 6, 9, function() {
			smartForms.datePicker_month++;
			if (smartForms.datePicker_month == 12) {
				smartForms.datePicker_month = 0;
				smartForms.datePicker_year++;
			}
			smartForms.date_showPicker();
			return false;
		}));
		smartForms.datePicker.appendChild(p);
		
		//Create table and headers
		var table = document.createElement('table');
		var thead = document.createElement('thead');
		var tr = document.createElement('tr');
		foreach(weekDayNames, function(wdn) {
			var td = document.createElement('td');
			td.appendChild(document.createTextNode(wdn));
			tr.appendChild(td);
		});
		thead.appendChild(tr);
		table.appendChild(thead);
		
		//Create table body
		var tbody = document.createElement('tbody');
		var end = false;
		var row = 0;
		var emptyRow = false;
		while (!end) {
			tr = document.createElement('tr');
			row++;
			for (var col = 0; col < 7; col++) {
				td = document.createElement('td');
				var date = new Date(firstDay.getTime() + ((startDayOffset++) * 24 * 60 * 60 * 1000));
				td.appendChild(document.createTextNode(date.getDate()));
				//td.onmousedown = eval('function(){smartForms.datePicker_input.value = "' + smartForms.date_format(date) + '";}');
				td.id = smartForms.datePicker_tdIdPrefix + smartForms.date_format(date);
				td.onmousedown = smartForms.date_select;
				if (startDayOffset <= 0) {
					element.addClass(td, 'offmonth');
				} else if (row >= 4 && date.getDate() <= 7) {
					end = true;
					element.addClass(td, 'offmonth');
				}
				tr.appendChild(td);
				if (col == 0 && end) emptyRow = true;
			}
			if (!emptyRow) tbody.appendChild(tr);
		}
		table.appendChild(tbody);
		smartForms.datePicker.appendChild(table);
		
		// Display and position
		smartForms.datePicker.style.display = 'block';
		smartForms.datePicker.style.top = element.getTopPos(smartForms.datePicker_input) + element.getHeight(smartForms.datePicker_input) + 'px';
		smartForms.datePicker.style.left = element.getLeftPos(smartForms.datePicker_input) + 'px';
		element.getBodyElement().appendChild(smartForms.datePicker);
	},

	date_getImgLink: function(src, width, height, fn) {
		var img = document.createElement('img');
		img.src = src;
		if (width)
			img.width = width;
		if (height)
			img.hight = height;
		if (fn)
			img.onmousedown = function() { fn() };
		return img;
	},

	date_select: function() {
		smartForms.datePicker_input.value = this.id.substring(smartForms.datePicker_tdIdPrefix.length);
		if (smartForms.datePicker_input.onchange)
			smartForms.datePicker_input.onchange();
		smartForms.date_hidePicker();
		formValidator.validateField(smartForms.datePicker_input);
	},

	date_format: function(dat) {
		var m = dat.getMonth() + 1;
		var d = dat.getDate();
		if (m < 10) m = '0' + m;	
		if (d < 10) d = '0' + d;
		return dat.getFullYear() + '-' + m + '-' + d;
	},

	date_hidePicker: function() {
		if (smartForms.datePicker) {
			element.remove(smartForms.datePicker);
			smartForms.datePicker = null;
		}
	}
}

addEvent(window, 'load', function() {
	smartForms.init();
});
addEvent(window, 'load', function() {
	foreach(getElementsByClassName('newwin', 'a'), function(a) {
		a.onclick = function() {
			window.open(this.href);
			return false;
		};
	});
	foreach(getElementsByClassName('confirm', 'a'), function(a) {
		a.onclick = function() {
			return confirm('Verkligen?');
		};
	});
});
/*
 * Version: 2007-03-29
 * Dependencies: element, display
 */
 
var popup = {
	
	_overlay: null,
	_ds1: null,
	_prompt: null,
	_promptFn: null,

	/*
	 * Show a popup with an existing element as content.
	 */	
	showElement: function(el) {
		var container = popup._createContainer();
		var clone = el.cloneNode(true);
		container.appendChild(clone);
		clone.style.display = 'block';
		popup._showIt();
		return container;
	},

	/*
	 * Show a popup with html content.
	 */	
	showInnerHtml: function(htmlString) {
		var container = popup._createContainer();
		container.innerHTML = htmlString;
		popup._showIt();
		return container;
	},
	
	/*
	 * Positions the popup and displays it.
	 */
	_showIt: function() {
		popup._ds1.style.left = '10000px';
		popup._ds1.style.display = 'block';
		
		element.getBodyElement().appendChild(popup._overlay);
		element.getBodyElement().appendChild(popup._ds1);

		popup._ds1.style.top = ((display.getTop() + (display.getHeight() - element.getHeight(popup._ds1)) / 3)) + 'px';
		popup._ds1.style.left = ((display.getLeft() + (display.getWidth() - element.getWidth(popup._ds1)) / 2)) + 'px';

		addEvent(window, 'resize', function() {
			popup._positionBackground();
		});
	},
	
	/*
	 * Positions the background.
	 */
	_positionBackground: function() {
		if (popup._overlay) {
			popup._overlay.style.top = display.getTop() + 'px';
			popup._overlay.style.left = display.getLeft() + 'px';		
			popup._overlay.style.width = display.getWidth() + 'px';
			popup._overlay.style.height = display.getHeight() + 'px';
		}
	},	

	/*
	 * Removes the popup. Default onclick event for buttons.
	 */	
	hide: function() {
		element.getBodyElement().removeChild(popup._overlay);
		element.getBodyElement().removeChild(popup._ds1);

		display.showScrollBars();
			
		popup._overlay = null;
		return false;
	},

	/*
	 * Creates the popup and returns the element that should be populated with content.
	 */	
	_createContainer: function() {
		
		// Shade
		popup._overlay = document.createElement('div');
		popup._overlay.className = 'overlay';
		
		display.hideScrollBars();
		popup._positionBackground();
		
		// Dropshadow
		popup._ds1 = document.createElement('div');
		var ds2 = document.createElement('div');
		var ds3 = document.createElement('div');
		var ds4 = document.createElement('div');
		
		popup._ds1.className = 'ds1 popup';
		ds2.className = 'ds2';
		ds3.className = 'ds3';
		ds4.className = 'ds4';

		ds3.appendChild(ds4);
		ds2.appendChild(ds3);
		popup._ds1.appendChild(ds2);

		//popup._overlay.appendChild(popup._ds1);
		
		return ds4;
	},

	/*
	 * Creates a button for the popup from a button object.
	 */		
	_createButton: function(button) {
		if (button) {
			var a = document.createElement('a');
			if (button.imgSrc) {
				var img = document.createElement('img');
				img.src = button.imgSrc;
				if (button.text)
					img.alt = button.text;
				a.appendChild(img);
			} else if (button.text) {
				a.appendChild(document.createTextNode(button.text));
			}
			a.href = button.href ? button.href : '#';
			if (button.onclick)
				a.onclick = button.onclick;
			else if (!button.href)
				a.onclick = function() { return popup.hide() };
			return a;
		}
		return null;	
	}
}
var Search = {
	selWc: null,
	selCo: null,
	selEt: null,
	txt: null,
	adListBody: null,
	pager: null,
	timer: null,
	lastValue: '',
	
	init: function() {
		var search = $('Search');
		
		if (search) {
			var so = new SWFObject("/flash/pil.swf", "Search_txt_arrow", "30", "20", "8", "#d3d3d3");
			so.write("Search_txt_arrow");
		
			Search.pager = $('AdListPager');
			
			var selects = $('Search').getElementsByTagName('select');

			Search.selWc = selects[0];
			Search.selCo = selects[1];
			Search.selEt = selects[2];
			
			Search.txt = $('Search_txt');

			//if (Search.selWc.selectedIndex < 0) Search.selWc.value = '';
			//if (Search.selCo.selectedIndex < 0) Search.selCo.value = '';
			//if (Search.selEt.selectedIndex < 0) Search.selEt.value = '';

			Search.selWc.onchange = Search.filter;
			Search.selCo.onchange = Search.filter;
			Search.selEt.onchange = Search.filter;
			Search.txt.onkeyup = Search.txtChange;
	
			var adList = $('AdList');
			if (adList)
				Search.adListBody = element.getChild(adList, 'table').tBodies[0];
			
			Search.pager.onchange = Search.page;
		}
	},
	
	txtChange: function() {
		if (Search.timer)
			clearTimeout(Search.timer);
		var go = this.value != Search.lastValue;
		Search.lastValue = this.value;
		if (go)
			Search.timer = setTimeout('Search.filter()', 500);
	},
	
	page: function() {
		$('SearchP').value = this.value;

		var wc = Search.selWc.value;
		var co = Search.selCo.value;
		var et = Search.selEt.value;

		ajax.getJson('/ajax/GetAds.aspx?p=' + this.value + '&wc=' + wc + '&co=' + co + '&et=' + et, Search.updateAds);
		
		Search.updatePager(parseInt(element.getInnerText($('AdListCount'))));
	},
	
	updatePager: function(statCount) {
		var p = $('SearchP').value;
		if (!p)
			p = 1
		var from = (p - 1) * Constants.AdPageLength + 1;
		var to = from + Constants.AdPageLength - 1;
		if (to > statCount)
			to = statCount;
		$('AdListFrom').innerHTML = from;
		$('AdListTo').innerHTML = to;	
	},
	
	updateAds: function(ads)
	{
		element.removeChildren(Search.adListBody);
		
		foreach (ads, function(ad) {
			var tr = document.createElement('tr');
			
			var td1 = document.createElement('td');
			var td2 = document.createElement('td');
			var td3 = document.createElement('td');
			var td4 = document.createElement('td');
			
			td1.className = 'logo';
			td2.className = 'ad';
			td3.className = 'location';
			td4.className = 'date';
			
			var img = document.createElement('img');
			
			var logo = ad.Logo ? ad.Logo : ad.Logotype;
			if (logo) {
				img.src = '/logo/' + logo + '.png';
			} else {
				img.src = "/img/bluelogo90x45.png"
			}
			img.Width = 90;
			img.Height = 45;
			td1.appendChild(img);
			
			var a = document.createElement('a');
			a.href = '/' + ad.CompleteUrl;
			var strong =  document.createElement('strong');
			strong.appendChild(document.createTextNode(ad.Headline ? ad.Headline : ad.HeadLine));
			a.appendChild(strong);
			a.appendChild(document.createElement('br'));
			a.appendChild(document.createTextNode(ad.Customer ? ad.Customer : ad.CustomerName));
			td2.appendChild(a);
			
			var span = document.createElement('span');
			span.appendChild(document.createTextNode(ad.County ? ad.County : ad.CountyName));
			td3.appendChild(span);
			td3.appendChild(document.createElement('br'));
			td3.appendChild(document.createTextNode(ad.Municipalities ? ad.Municipalities : ad.MunicipalityNames));
			
			td4.appendChild(document.createTextNode(ad.ShortDate));
			
			tr.appendChild(td1);
			tr.appendChild(td2);
			tr.appendChild(td3);
			tr.appendChild(td4);
			
			tr.onclick = function() { AdList.onClickRow(this); }
			
			Search.adListBody.appendChild(tr);
		});
	},
	
	filter: function() {
		//var now = (new Date()).getTime();
		//console.log(now - Search.lastChange);
		//if (now - Search.lastChange < 500)
		//	return;
		var wc = Search.selWc.value;
		var co = Search.selCo.value;
		var et = Search.selEt.value;
		var txt = Search.txt.value;
		
		$('SearchP').value = 1;
		
		var url = '/ajax/Search.aspx?wc=' + wc + '&co=' + co + '&et=' + et + '&txt=' + txt;
		ajax.getJson(url, Search.update);
	}, 
	
	update: function(result) {
		Search.updateSel(result.WcStats, Search.selWc, Search.wcSelected);
		Search.updateSel(result.CoStats, Search.selCo, Search.coSelected);
		var statCount = Search.updateSel(result.EtStats, Search.selEt, Search.etSelected);
		
		Search.updateAds(result.Ads);

		$('AdListCount').innerHTML = statCount;
		
		Search.updatePager(statCount);		
		Search.redrawPager(statCount);	
	},
	
	updateSel: function(o, sel) {
		var selectedVal = sel.value;
		var option = new Option(sel.options[0].text, '');
		sel.length = 0;
		sel.options.add(option);
		var flag = false;
		var count = 0;
		foreach (o, function(oo) {
			var name = oo.Second + ' (' + String(oo.Third) + ')';
			var val = String(oo.First);
			var option = new Option(name, val);
			if (val == selectedVal) {
				option.selected = true;
				flag = true;
			}
			sel.options.add(option);
			count += oo.Third;
		});
		sel.options[0].className = 'first';
		if (!flag)
			sel.options[0].selected = true;
		return count;
	},
	
	redrawPager: function(count) {
		Search.pager.length = 0;
		for (var p = 1; p <= count / Constants.AdPageLength + 1; p++) {
			var option = new Option(p, p);
			Search.pager.options.add(option);
		}
	}
}

addEvent(window, 'load', Search.init);
addEvent(window, 'load', function() {
	var workMailFlash = $('workMailFlash');
	if (workMailFlash) {
		var so = new SWFObject("/flash/Puff2.swf", "workMailFlashContent", "182", "100", "8", "#ffffff");
		so.write("workMailFlash");
	}
	
	var liveItFlash = $('liveItFlash');
	if (liveItFlash) {
		var so = new SWFObject("/flash/Live-itBanner.swf", "liveItFlashContent", "185", "125", "8", "#ffffff");
		//var so = new SWFObject("/flash/Live-itBanner.swf", "liveItFlashContent", "190", "125", "8", "#ffffff");
		so.write("liveItFlash");
	}
	
	var tvpuff = $('tvpuff');
	if (tvpuff) {
		tvpuff.onclick = function() {
			window.open(this.href, 'mywindow', 'width=520, height=322');
			return false;
		};
	}
});

var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec' ];
var weekDayNames = [ 'Må', 'Ti', 'On', 'To', 'Fr', 'Lö', 'Sö' ];
var isIE = false;
var decimalSeparator = ',';
var Constants = {
	AdPageLength : 15
}
