var myMethods = {
	getClassParam : function(element, param) {				
		var result = null;
		$w($(element).className).each(function(c) {			
			if (c.startsWith(param + '_')) {				
				result = c.substring(param.length + 1);
			}
		});
		return result;
	}
} 
Element.addMethods(myMethods);

$RF = function(radioGroup) {
	return $$("input[type='radio'][name='" + radioGroup + "']").find(function(re) {return re.checked;} ).value;
}

Event.observe(document,'dom:loaded', function() { // Fix links on images with absolute position in IE
	$$('.positionedImageContainer').each(function(div) {		
		if (div.up('a')) {			
			div.setStyle({
				cursor:'pointer'
			});
			div.observe('click', function() {
				document.location = div.up('a').href;
			});
		}
	});
});

var GraphicalScrollbar = Class.create({
	
	initialize : function(div, options) {
		
		// INIT
		
		this.imagePath = '/images';
		
		this.div = $(div);
		['imgPrefix', 'imgExtension', 'scrollbarWidth', 'endButtonsHeight', 'scrollThumbHeight'].each(function(param) {
			this[param] = options[param];
		}.bind(this));
		
		var dim = this.div.getDimensions();
		this.width = dim.width;
		this.height = this.removePx(this.div.getStyle('height')); // IE6 giver en forkert værdi ved getHeight()
		var paddingRight = this.removePx(this.div.getStyle('paddingRight')); 
		//alert(paddingRight);
		
		var contentOverflow = this.div.getStyle('overflow');
		this.div.setStyle({
			overflow: 'hidden'
		});
		
		var curStyle = this.div.getStyle('position');
		if (curStyle != 'absolute' && curStyle != 'relative') {
			this.div.setStyle({
				position: 'relative'
			});
		}
		
		this.scrollContentContainer = new Element('div', {'class' : 'GSScrollContentContainer'});
		this.scrollContentContainer.setStyle({
			//overflow 	: contentOverflow,
			width		: Math.max(this.width - paddingRight, 10) + 'px', // IE melder fejl ved width:0 !!
			position	: 'absolute',
			left		: 0,
			top			: 0
		});
		this.scrollContentY = 0;
		
		this.scrollbarContainer = new Element('div', {'class' : 'GSScrollbarContainer'});
		this.scrollbarContainer.setStyle({
			position		: 'absolute',
			top			: 0,
			left		: this.width - this.scrollbarWidth + 'px'
		});
		
		this.scrollTrack = new Element('div', {'class' : 'GSScrollTrack'});
		this.scrollTrackHeight = this.height - this.endButtonsHeight * 2;
		this.scrollTrack.setStyle({
			position	: 'absolute',
			left		: 0,
			width		: this.scrollbarWidth + 'px',
			height		: this.scrollTrackHeight + 'px',
			top			: this.endButtonsHeight + 'px',
			background	: 'url(' + this.imagePath + '/' + this.imgPrefix + '_scrollTrack.' + this.imgExtension + ') no-repeat top left'
		});
		this.scrollThumb = new Element('div', {'class' : 'GSScrollThumb'});
		this.scrollThumb.setStyle({
			position	: 'absolute',
			top			: 0,
			left		: 0,
			cursor		: 'pointer',
			width		: this.scrollbarWidth + 'px',
			height		: this.scrollThumbHeight + 'px',
			background	: 'url(' + this.imagePath + '/' + this.imgPrefix + '_scrollThumb.' + this.imgExtension + ') no-repeat top left'
		});
		this.scrollThumbY = 0;
		
		this.scrollContentContainer.innerHTML = this.div.innerHTML;
		this.div.update('');
		this.height = this.div.getHeight();
		this.div.insert(this.scrollContentContainer);
		this.div.insert(this.scrollbarContainer);
		this.scrollbarContainer.insert(this.scrollTrack);
		this.scrollTrack.insert(this.scrollThumb);
		
		this.scrollThumbRoom = this.scrollTrackHeight - this.scrollThumbHeight;
		
		this.contentScrollStep = 30;
		this.contentPageScrollStep = Math.round(this.height * 0.9);

		this.div.addClassName('GraphicScrollbarActive');
		
		this.scrollThumb.observe('mousedown', this.scrollThumbMousedown.bindAsEventListener(this));
		this.scrollTrack.observe('mousedown', this.scrollTrackMousedown.bindAsEventListener(this))
		Event.observe(document, 'mouseup', this.mouseup.bindAsEventListener(this));
		Event.observe(document, 'mousemove', this.mousemove.bindAsEventListener(this));
		this.div.observe("mousewheel", this.wheel.bindAsEventListener(this), false);
		this.div.observe("DOMMouseScroll", this.wheel.bindAsEventListener(this), false); // Firefox
		
		Event.observe(window, 'load', this.reset.bindAsEventListener(this));
		//this.reset();
		//setTimeout(this.reset.bind(this), 20);
	},
	
	reset : function() {
		
		this.contentHeight = this.scrollContentContainer.getHeight();
		this.height = this.removePx(this.div.getStyle('height'));
		this.scrollContentRoom = this.contentHeight - this.height;
		
		this.scrollbarContainer.setStyle({
			display: this.contentHeight > this.height ? 'block' : 'none'
		});
		this.scrollThumb.setStyle({top: '0px'});
		this.scrollThumbY = 0;
		
		var dim = this.div.getDimensions();
		this.width = dim.width;
		this.scrollbarContainer.setStyle({
			position		: 'absolute',
			top			: 0,
			left		: this.width - this.scrollbarWidth + 'px'
		});
		
		this.updateContent();
	},
	
	scrollThumbMousedown : function(event) {
		event.stop();
		this.mousedownY = event.pointerY();
		this.mouseDownThumbY = this.scrollThumbY;
		this.dragMode = 'thumb';
	},
	
	scrollTrackMousedown : function(event) {
		event.stop();
		if (event.element() == this.scrollThumb) return;
		var pointerY = event.pointerY();
		var scrollThumbCumulativeY = this.scrollThumb.cumulativeOffset().top;
		if (event.pointerY() > this.scrollThumb.cumulativeOffset().top) {
			var newY = this.scrollContentY - this.contentPageScrollStep;
		} else {
			var newY = this.scrollContentY + this.contentPageScrollStep;
		}
		this.moveContent(newY);
	},
	
	mouseup : function(event) {
		this.dragMode = null;
	},
	
	mousemove : function(event) {
		if (this.dragMode) {
			event.stop();
			var delta = event.pointerY() - this.mousedownY;
			this.scrollThumbY = Math.max(0, Math.min(this.scrollTrackHeight - this.scrollThumbHeight, this.mouseDownThumbY + delta));
			this.scrollThumb.setStyle({
				top : 	this.scrollThumbY + 'px'
			});
			this.updateContent();
		}
	},
	
	wheel : function (event){
        var delta = 0;
        if (!event) event = window.event;
        if (event.wheelDelta) {
        	delta = event.wheelDelta/120;
			if (window.opera) delta = -delta;
        } else if (event.detail) { delta = -event.detail/3; }
        this.moveContent(this.scrollContentY + delta * this.contentScrollStep);
	},
	
	moveContent : function(y) {
		this.scrollContentY = Math.round(Math.min(0,Math.max(-this.scrollContentRoom, y)));
		this.scrollContentContainer.setStyle({
        	top: this.scrollContentY + 'px'
        });
        this.updateThumb();
	},
	
	updateContent : function() {
		if (this.scrollThumbY == 0) {
			this.scrollContentY = 0;
		} else if (this.scrollThumbY == this.scrollThumbRoom) {
			this.scrollContentY = - this.scrollContentRoom; 
		} else {
			this.scrollContentY = - Math.round(this.scrollContentRoom * this.scrollThumbY / this.scrollThumbRoom);
		}
		this.scrollContentContainer.setStyle({
			top	: this.scrollContentY + 'px'
		});
	},
	
	updateThumb : function() {
		if (this.scrollContentY == 0) {
			this.scrollThumbY = 0;
		} else if (this.scrollContentY == this.scrollContentRoom) {
			this.scrollThumbY = - this.scrollContentRoom; 
		} else {
			this.scrollThumbY = - Math.round(this.scrollThumbRoom * this.scrollContentY / this.scrollContentRoom);
		}
		this.scrollThumb.setStyle({
			top	: this.scrollThumbY + 'px'
		});
	},
	
	removePx : function(t) {
		if (t.substring(t.length - 2) == 'px') {
			t = t.substring(0,t.length - 2);
		} 
		return t;
	}
})


var Translate = Class.create({	
	initialize: function(table) {
		this.locale = window.locale;
		this.table = table;
	},	
	_ : function(str) {
		if (this.locale == 'en' || !this.table[this.locale] || !this.table[this.locale][str]) {
			return str;
		} else {
			return this.table[this.locale][str];
		}
	}
});


var Slideshow = Class.create({
	
	initialize : function(slideshow) {
		
		this.fadeTime = 2000;
		this.waitTime = 5000;
		if (window.adminLoggedIn) { return; }
		this.container = slideshow;
		this.id = slideshow.getClassParam('slideshow');
		this.billeder = slideshowBilleder[this.id];		
		
		this.containerA = this.container.down('.slideshowBilledContainer');
		this.containerA.setStyle({display: 'block'});
		this.containerA.id = '';
		this.containerB = this.containerA.next('.slideshowBilledContainer');
		this.containerB.setStyle({display: 'block'});
		this.containerB.id = '';
		this.currentContainer = this.containerA;
		this.currentImageIndex = -1;
		
		if (this.billeder.length < 2) {return; }
								
		this.prepareNextImage();
	},
	
	prepareNextImage : function() {
		this.currentImageIndex++;
		if (this.currentImageIndex >= this.billeder.length) {this.currentImageIndex = 0;}		
		
		this.getBackContainer().down('img').remove(); // Man kan ikke bare sætte ny src. Så f....er Safari op!!
		this.getBackContainer().insert(new Element('img'));
		this.getBackContainer().down('img').src = '/images/cms/slideshow_billeder/' + this.billeder[this.currentImageIndex]['id'] + '.jpg?salt=' + this.billeder[this.currentImageIndex]['image_salt'];
			
		this.getBackContainer().down('img').setStyle({
			top:Math.max(this.billeder[this.currentImageIndex]['image_pos_y'], 0) + 'px',
			left:Math.max(this.billeder[this.currentImageIndex]['image_pos_x'], 0) + 'px'
		})
		this.getBackContainer().down('img').setStyle({
			opacity:0
		});		
		if (this.timeout) {clearTimeout(this.timeout); }
		
		this.timeout = setTimeout(this.startFade.bind(this), this.waitTime);
		
	},
	
	startFade : function() {
		this.timeout = null;
		var container = this.getBackContainer();
		if (imgLoaded(container.down('img'))) {			
			this.fadeStartTime = new Date().getTime();
			if (this.pe) {
				this.pe.stop();
				delete this.pe;
			}			
			this.pe = new PeriodicalExecuter(this.fadeStep.bind(this), 0.05);
		} else {
			this.timeout = setTimeout(this.startFade.bind(this), 500);
		}
	},
	
	fadeStep : function() {
		var curTime = new Date().getTime();
		if (curTime - this.fadeStartTime > this.fadeTime) {
			this.getBackContainer().down('img').setStyle({
				opacity : 1
			});
			this.getFrontContainer().down('img').setStyle({
				opacity : 0
			});
			this.pe.stop();
			delete this.pe;
			this.switchFrontAndBack();
			if (this.billeder.length > 1) {
				this.prepareNextImage();
			}			
		} else {			
			this.getFrontContainer().down('img').setStyle({								
				opacity : 1 - (curTime - this.fadeStartTime) / this.fadeTime				
			});
			this.getBackContainer().down('img').setStyle({				
				opacity : (curTime - this.fadeStartTime) /this.fadeTime				
			});
		}
	},
	
	switchFrontAndBack : function() {
		this.currentContainer = this.getBackContainer();
	},
	
	getBackContainer : function() {
		return this.currentContainer == this.containerA ? this.containerB : this.containerA;
	},
	
	getFrontContainer : function() {
		return this.currentContainer == this.containerA ? this.containerA : this.containerB;
	},
	
	skiftBilleder : function(billeder) {
		this.billeder = billeder;
		this.currentImageIndex = -1;
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = null;
		}
		if (this.pe) {
			this.pe.stop();
			delete this.pe;
		}
		var waitTime = this.waitTime;
		this.waitTime = 0;
		this.prepareNextImage();
		this.waitTime = waitTime;
	}
	
	
})


var Popup = Class.create({
	
	initialize : function(aId, popupId, callbackOpen, callbackClose) {
		this.aId = aId;	
		this.popupId = popupId;
		this.callbackOpen = callbackOpen;				
		this.callbackClose = callbackClose;
		Event.observe(document, 'dom:loaded', this.modifyDom.bindAsEventListener(this));
		this.ready = false;
		this.openWhenReady = false;
		Event.observe(window, 'resize', this.resizeCurtain.bindAsEventListener(this));
	},
	
	modifyDom : function(event) {
		// Popup
		this.popup = $(this.popupId);
		if (!this.popup) {
			return;
		}
		
		// Størrelse
		this.cornerRadius = this.popup.hasClassName('popupStor') ? '23' : '8';
		
		// Bagtæppe							
		this.curtain = $('popupCurtain');		
		//this.resizeCurtain();
		
		// Skygge
		this.shadow = $('popupShadowContainer' + this.cornerRadius);
		
		// Hvis popup er bundet til et bestemt link
		if (this.aId){ 
			this.a = $(this.aId); 
			this.a.observe('click', this.aClicked.bindAsEventListener(this));
		}
		
		// Runde hjoerner
		this.makeCorners();		
		
		// Events
		if (this.popup.down('.popupLukX')) {
			this.popup.down('.popupLukX').observe('click', this.closePopup.bindAsEventListener(this));				
			this.popup.down('.popupLukX').setStyle({cursor:'pointer'});			
		}
		if (this.popup.down('.popupLukXVenstre')) {
			this.popup.down('.popupLukXVenstre').observe('click', this.closePopup.bindAsEventListener(this));				
			this.popup.down('.popupLukXVenstre').setStyle({cursor:'pointer'});			
		}
		if (this.popup.down('.popupLukImg')) {
			this.popup.down('.popupLukImg').observe('click', this.closePopup.bindAsEventListener(this));
			this.popup.down('.popupLukImg').setStyle({cursor:'pointer'});
		}
		this.curtainClickWrapperFn = this.closePopup.bindAsEventListener(this);						
		this.ready = true;
		if (this.openWhenReady) {
			this.open();
		}					
	}, 
	
	makeCorners : function() {
		this.popup.setStyle({border: '2px solid #ccc'}); // Sættes her så rammen kommer med hver gang, også efter farveskift
		if (!window.browserLteIE6) {			
			this.makeRoundCorners();
		} else {
			//this.makeRoundCorners();
			this.makeSquareCorners();
		}
	},
	
	makeRoundCorners : function() {
		var settings = {
    		tl: { radius: this.cornerRadius },
      		tr: { radius: this.cornerRadius },
      		bl: { radius: this.cornerRadius },
      		br: { radius: this.cornerRadius },
      		antiAlias: true,
      		autoPad: false
    	}
    	this.cornersObj = new curvyCorners(settings, this.popup);
		this.cornersObj.applyCornersToAll();					
	},
	
	makeSquareCorners : function() {		
		var topContainer = new Element('div', {'class' : "popupTopSquareCorners"});
		this.popup.insert(topContainer);		
		var topBorder = this.popup.getStyle('borderTop');		
		//alert(topBorder);
		topContainer.setStyle({			
			borderTop: topBorder,
			borderLeft: topBorder,
			borderRight: topBorder,
			backgroundColor: this.popup.getStyle('backgroundColor'),
			width: this.popup.getWidth() + 'px',
			height: this.cornerRadius  + 'px',
			//zIndex:2,
			position:'absolute',
			top: -(this.cornerRadius) + 'px',
			left:'-2px'
		});
		
		var bottomContainer = new Element('div', {'class' : "popupBottomSquareCorners"});
		this.popup.insert(bottomContainer);
		var bottomBorder = this.popup.getStyle('borderBottom');
		bottomContainer.setStyle({
			borderBottom: bottomBorder,
			borderLeft: bottomBorder,
			borderRight: bottomBorder,
			backgroundColor: this.popup.getStyle('backgroundColor'),
			width: this.popup.getWidth() + 'px',
			height: this.cornerRadius + 'px',
			//zIndex:2,
			position:'absolute',
			top: this.popup.getHeight() + 'px',
			left:'-2px'
		});		
	},
	
	resizeCurtain : function() {
		if (this.curtain) {
			var offsetParentCumOffset = this.curtain.getOffsetParent().cumulativeOffset(); 					
			this.curtain.setStyle({
				opacity:0,						
				left: -(offsetParentCumOffset.left) + 'px',
				top : -(offsetParentCumOffset.top) + 'px',
				height: document.viewport.getHeight() + document.viewport.getScrollOffsets().top + 'px',
				width: document.viewport.getWidth() + document.viewport.getScrollOffsets().left + 'px'
			});
		}	
	},
	
	updateShadow : function() {		
		var position = this.popup.positionedOffset();
		switch(this.cornerRadius) {
			case '23':					
				this.shadow.setStyle({
					display: 'block',			
					left: position.left - 37 + 'px',
					top:  position.top - 52 + 'px',
					width : this.popup.getWidth() + 90 + 'px',
					height: this.popup.getHeight() + 125 + 'px'
				});
				break;
			case '8':					
				this.shadow.setStyle({
					display: 'block',			
					left: position.left - 30 + 'px',
					top:  position.top - 35 + 'px',
					width : this.popup.getWidth() + 65 + 'px',
					height: this.popup.getHeight() + 90 + 'px'
				});
				break;
		}
	},
	
	aClicked : function(event) {
		event.stop();
		this.open();
				
		if (this.callback) {
			this.callback();
		}
	},
	
	open : function() {		
		if (this.ready) {
			this.popup.setStyle({
				display: 'block'
			});	
			this.resizeCurtain();	
			this.curtain.setStyle({
				display: 'block'
			});			
			this.updateShadow();
			if (this.callbackOpen) {
				this.callbackOpen();
			}
			if (window.supersleight && !this.supersleightDone) {				
				supersleight.limitTo($(this.popupId));
				supersleight.run();
				this.supersleightDone = true;
			}
		} else {
			this.openWhenReady = true;
		}	
		if (this.curtain) {	
			this.curtain.observe('click', this.curtainClickWrapperFn);
		}
	},
	
	closePopup : function(event) {
		this.popup.setStyle({
			display: 'none'
		});
		this.curtain.setStyle({
			display: 'none'
		});
		this.shadow.setStyle({
			display: 'none'
		});
		this.curtain.stopObserving('click', this.curtainClickWrapperFn);
		if (this.callbackClose) {			
			this.callbackClose();
		}
	},
	
	setBgColor : function(hex) {
		this.popup.setStyle({
			backgroundColor : '#' + hex
		});
		var divs = new Array('roundedCornersTopBar', 'roundedCornersBottomBar', 'popupTopSquareCorners', 'popupBottomSquareCorners');
		for (var i = 0; i<=3; i++) {
			if (this.popup.down('.' + divs[i])) {
				this.popup.down('.' + divs[i]).remove();
			}
		}
		this.makeCorners();
	}
	
});

var Validator = Class.create({
	
	initialize: function(data, autoInject) {		
		this.data = data;
		this.colorFields = data.colorFields;
		if (this.colorFields === null ||this.colorFields === undefined) {
			this.colorFields = true; // Default true
		}					
		this.autoInject = autoInject; // Default false	
		this.messagesTogether = this.data.alert.messagesTogether || false;
		this.messageHeader = this.data.alert.messageHeader || '';
		Event.observe(document,'dom:loaded', this.doDomWork.bindAsEventListener(this));
	},
	
	doDomWork:function() {
		if (this.data.form) {
			this.form = $(this.data.form);
		} else {
			this.form = $(this.data.rules[Object.keys(this.data.rules)[0]].id).up('form');
		}	
		if (this.form) {
			this.form.observe('submit', this.formSubmitted.bindAsEventListener(this));
		}
	},
	
	formSubmitted : function(event) {	
		if (event) { event.stop(); }
		if (this.validates()) {
			this.form.submit();
		}
	},
		
	validates : function() {
		this.messages = new Array();
		this.errorFields = new Array();
		var rules = Object.values(this.data.rules);
		for (var i = 0; i < rules.length; i++) {
			this.processRule(rules[i]);
			if (rules[i].breakChainOnFailure === true && !this.fieldValidates(rules[i])) {				
				break;
			}
		} 
		if (this.messages.length > 0) {
			if (this.colorFields) {			
				this.updateFieldBgs();	
			}					
			this.doAlert();	
			return false;		
		}
		return true;
	},
	
	updateFieldBgs : function() {
		Object.values(this.data.rules).each(function(rule) {
			var isRadio = rule.validator == 'radioSelectOne';
			var noticeId = isRadio ? rule.noticeId : rule.id;						
			if (typeof noticeId == 'string') {
				noticeId = [noticeId];
			}			
			noticeId.each(function(thisId) {					
				$(thisId).setStyle({
					backgroundColor : (this.errorFields.indexOf(rule.id) != -1 ? '#ff8' : (isRadio ? 'transparent' : '#f9f9f9'))
				});					
			}.bind(this));
			
		}.bind(this));
	},
	
	processRule : function(rule) {
		if (!this.fieldValidates(rule)) {
			this.messages.push(rule.message);
			if (Object.isArray(rule.id)) {
				this.errorFields = this.errorFields + rule.id;
			} else {
				this.errorFields.push(rule.id);	
			}			
		}		
	},
	
	fieldValidates: function(rule) {
		if (typeof rule.validator == "object") {
			var ok = true;
			rule.validator.each(function(v) {
				if (!this.validatorValidates(rule, v)) {
					ok = false;				
				}
			}.bind(this));			
			return ok;
		} else {
			return this.validatorValidates(rule, rule.validator);
		}
	},
	
	validatorValidates : function(rule, validator) {		
		if (rule.allowEmpty === true && $F(rule.id) == '') {return true; }
		switch (validator) {
			case 'radioSelectOne':
				var ok = false
				rule.id.each(function(e) {
					if ($(e).checked) { ok = true; }
				});
				return ok;
				break;
			case 'textNotEmpty':
				return $F(rule.id).strip() != '';
				break;			
			case 'notEmpty':
				return $F(rule.id).strip() != '';
				break;
			case 'email':
				return /^([a-z0-9_\-\.])+\@([a-z0-9_\-\.])+\.([a-z]{2,4})$/i.test($F(rule.id));
				break;
			case 'gentag':
				return $F(rule.id) == $F(rule.gentagFeltId);
				break;
			case 'stringLengthEquals':
				return $F(rule.id).length == rule.strLen;
				break;
			case 'stringLengthMin':
				return $F(rule.id).length >= rule.strLenMin;
				break;
			case 'stringLengthBetween':
				if ($F(rule.id).length < rule.strLenMin || $F(rule.id).length > rule.strLenMax) { alert('failure');return false; }
				return true;				
				break;			
			case 'checked':
				return $(rule.id).checked;
				break;
			case 'stringNotEquals':
				return $F(rule.id) != rule.compareTo;
				break;
			case 'stringLengthEqualsOrEmpty':
				return $F(rule.id).length == rule.strLen || $F(rule.id).length == 0;
				break;
			case 'digits':
				var value = $F(rule.id);							
				for (var i = 0; i < value.length; i++) {					
					if ('1234567890'.indexOf(value.substr(i,1)) == -1) { return false; }
				}
				return true;
				break;
			case 'digitsStringLengthEquals':
				var value = $F(rule.id);				
				if (value.length != rule.strLen) { return false; }
				for (var i = 0; i < value.length; i++) {					
					if ('1234567890'.indexOf(value.substr(i,1)) == -1) { return false; }
				}
				return true;
				break;
			case 'date':
				var value = $F(rule.id);
				//alert(value);
				if (value.length != 6) { return false; }
				var day = parseInt(value.substring(0,2), 10);	// HUSK base 10, foranstillet 0 betyder ellers octal værdi			
				var month = parseInt(value.substring(2,4), 10) - 1; // JS regner måneder fra 0 til 11
				var year = parseInt(value.substring(4,6), 10);
				year = year + (year < 15 ? 2000 : 1900);
				//alert(day + ', ' + month + ', ' + year);
				if (day < 0 || day > 31 || month < 0 || month > 11) { return false; }				
				var date = new Date();
				date.setYear(year); // Rækkefølgen er vigtig
				date.setMonth(month);
				date.setDate(day);								
				var newDay = date.getDate();
				var newMonth = date.getMonth();
				var newYear = date.getFullYear();
				//alert(newDay + ', ' + newMonth + ', ' + newYear);								
				if (day != newDay || month != newMonth || year != newYear)  { return false; }
				return true;
				break;
			case 'atLeastOneNotEmpty':
				var ok = false;
				rule.id.each(function(id) {
					if ($F(id) != '') {
						ok = true;
					}
				});
				return ok;
				break;
			case 'tlfDk':
				var value = $F(rule.id);
				if (value.length != 8) {return false; }
				for (var i = 0; i < value.length; i++) {					
					if ('1234567890'.indexOf(value.substr(i,1)) == -1) { return false; }
				}
				return true;
				break;
			case 'allEqual':
				return rule.id.all(function(v) { return $F(v) == $F(rule.id[0])});
				break;
		}
	},
	
	doAlert : function() {
		if (this.data.alert && this.data.alert.type == 'VS_Popup') {			
			if (this.messagesTogether) {
				var text = this.messageHeader + '<ul>';
				this.messages.each(function(m){text += '<li>' + m + '</li>'; });
				text += '</ul>';
			} else {
				var text = this.messageHeader + '<br />';
				text += this.messages[0];
			}
			$(this.data.alert.messageElement).update(text);
			this.data.alert.popup.open();
		} else {
			alert(this.messages[0]);	
		}		
	}
	
});

var MouseOver = Class.create({
	
	initialize : function(id) {		
		this.id = id;	
		if ($(this.id)) {
			this.doDomStuff()
		} else {
			Event.observe(document, 'dom:loaded', this.doDomStuff.bindAsEventListener(this));
		}		
	},
	
	doDomStuff : function() {	
		this.element = $(this.id);	
		if (!this.element){ return; }	
		this.useSrc = this.element.tagName.toLowerCase() == 'input' || this.element.tagName.toLowerCase() == 'img';
		this.swapImage = new Image(this.element.getWidth(), this.element.getHeight());		
		this.orgSrc = this.useSrc ? this.element.src : this.element.getStyle('backgroundImage');		
		var ext = this.getExt(this.orgSrc);			
		var filename = this.getFilename(this.orgSrc);				
		if (filename.indexOf('http://') != -1) {
			filename = filename.substring(filename.indexOf('/',8));
		}			
		//alert(filename.substr(filename.length - 10));
		if (filename.substr(filename.length - 9) == '_rollover') return;
		this.element.observe('mouseover', this.mouseOver.bindAsEventListener(this));
		this.element.observe('mouseout', this.mouseOut.bindAsEventListener(this));
		this.swapImage.src = filename + '_rollover.' + ext; 	
	},
	
	getExt : function(str) {
		var end = str.length - 1;
		while (str.substr(end, 1) == ')' || str.substr(end, 1) == '"') {
			end--;
		}		
		end++;
		var start = str.lastIndexOf('.') + 1;
		return str.substring(start, end);		
	},
	
	getFilename : function(str) {
		var start = 0;
		if (str.substring(0,4) == 'url(') {
			start = 4;
		}
		if (str.substr(start, 1) == '"') {
			start++;
		}
		var end = str.lastIndexOf('.');
		return str.substring(start, end);
	},
	
	mouseOver : function(event) {
		
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = null;	
		}				
		if (this.useSrc) {
			this.element.src = this.swapImage.src;
		} else {								
			this.element.setStyle({backgroundImage : 'url(' + this.swapImage.src + ')'});						
		}
	},
	
	mouseOut: function(event) {	
		if (!this.element.hasClassName('active')) {
			this.timeout = setTimeout(this.switchBack.bind(this), 50);
		}
	},
	
	switchBack : function() {
		if (this.useSrc) {
			this.element.src = this.orgSrc;
		} else {
			this.element.setStyle({backgroundImage: this.orgSrc});
		}
	}
	
});



var DataTable = Class.create({
	
	initialize : function(id, callback, initSelected) {
		this.id = id;
		this.callback = callback;		
		this.initSelected = initSelected;
		Event.observe(document, 'dom:loaded', this.doDomStuff.bindAsEventListener(this));
	},
	
	doDomStuff : function() {
		this.tableContainer = $(this.id).down('.genericUITableBodyContainer');
		$$('#' + this.id + ' .genericUITableBody tr').each(function(tr) {
			tr.observe('mouseover', this.trMouseover.bindAsEventListener(this));
			tr.observe('mouseout', this.trMouseout.bindAsEventListener(this));
			tr.observe('click', this.trClick.bindAsEventListener(this));
		}.bind(this));
		Event.observe(document, 'keydown', this.documentKeydown.bindAsEventListener(this));
		if (this.initSelected) {
			this.select(this.initSelected);
		}
	},
	
	documentKeydown : function(event) {			
		var key = getKeyCode(event);	
		var currentTR = $('kursusTBL_' + selectedKursus);
		switch (key) {
			case Event.KEY_UP:							
				if(currentTR.previous('tr')) {
					event.stop();
					this.select(currentTR.previous('tr').id.substring(10));								
				}			
				break;
			case Event.KEY_DOWN:
				if(currentTR.next('tr')) {
					event.stop();
					this.select(currentTR.next('tr').id.substring(10));				
				}			
				break;
		}
	},
	
	getTrFromEvent : function(event) {
		var tr = event.element();
		if (tr.tagName != 'tr') {			
			tr = tr.up('tr');
		}
		return tr;
	},
	
	trMouseover : function(event) {
		var tr = this.getTrFromEvent(event);
		tr.addClassName('mouseover');		
	},
	
	trMouseout : function(event) {
		var tr = this.getTrFromEvent(event);
		tr.removeClassName('mouseover');
	},
	
	trClick : function(event) {
		var tr = this.getTrFromEvent(event);
		this.select(tr.id.substring(this.id.length + 1), event);
		
	},
	
	select : function(id, event) {
		if (this.selectedId) {
			$(this.id + '_' + this.selectedId).removeClassName('selected');
		}		
		this.selectedId = id;
		var tr = $(this.id + '_' + this.selectedId); 
		tr.addClassName('selected');	
		this.scrollIfNecessary();				
		if (typeof this.callback == 'function') {			
			this.callback(this.selectedId, event);
		}
	},
	
	scrollIfNecessary : function() {
		var tr = $(this.id + '_' + this.selectedId); 		
		var offsetY = tr.cumulativeOffset().top - this.tableContainer.cumulativeOffset().top
		//alert(offsetY); 
		if (offsetY < 0) {			
			this.tableContainer.scrollToElement(tr);
		}
		if (offsetY + tr.getHeight() > this.tableContainer.getHeight()) {			
			this.tableContainer.scrollToPosition(0,tr.positionedOffset().top + tr.getHeight() - this.tableContainer.getHeight());
		}
	}
	
});


var Datadispenser = Class.create({
	
	initialize : function(data, fields) {
		
		this.data = data;
		this.fields = fields;
	},
	
	update : function(id) {
		this.fields.each(function(field) {
			$$('.variable_' + field).each(function(e) {
				if (e.hasClassName('flexcrollactive')) {
					e = e.down('.contentwrapper');
				}				
				e.update(this.data[id][field]);
			}.bind(this))
		}.bind(this))
	}
	
});

var DatoTidUpdater = Class.create({
	
	initialize : function(id) {
		this.id = id;
		Event.observe(document, 'dom:loaded', this.doDomStuff.bindAsEventListener(this));
	},
	
	doDomStuff : function() {
		this.e = $(this.id);
		if (this.e) {
			new PeriodicalExecuter(this.doUpdate.bind(this), 1);
		}
	},
	
	doUpdate : function() {
		var date = new Date();
		var ugedage = ['SØNDAG', 'MANDAG','TIRSDAG', 'ONSDAG', 'TORSDAG', 'FREDAG', 'LØRDAG'];
		var str = ugedage[date.getDay()] + ', ' + stringPadLeft(date.getDate(),2,'0') + '.' + stringPadLeft(date.getMonth() + 1 ,2,'0') + '.' + stringPadLeft(date.getFullYear() - 2000, 2, '0');
		str += '&nbsp;&nbsp;KL. ';
		str += stringPadLeft(date.getHours(),2,'0') + ':' + stringPadLeft(date.getMinutes(),2,'0') + ':' + stringPadLeft(date.getSeconds(),2,'0');	
		this.e.update(str);
	}	
});

function imgLoaded(img) {	
	if (!img.complete) { // IE
		return false;
	}	
	if (typeof img.naturalWidth	!= 'undefined' && img.naturalWidth == 0) { // Gecko
		return false;
	}	
	return true;
}


function getPopupWindowCoords(winWidth, winHeight) {
	var coords = new Object();
	if (window.screenLeft || window.screenLeft === 0) {	// IE			
		var left = window.screenLeft + Math.round((document.viewport.getWidth() - winWidth  )   / 2);
		var top  = window.screenTop + 20;	
	} else if (window.screenX || window.screenX === 0) {		
		var topChrome = 1; // Titlebar
		topChrome += window.directories.visible ? 1 : 0;
		topChrome += window.locationbar.visible ? 1 : 0;
		topChrome += window.menubar.visible ? 1 : 0;
		topChrome += window.personalbar.visible ? 1 : 0;
		topChrome += window.toolbar.visible ? 1 : 0;		
		var left = window.screenX +                  Math.round((document.viewport.getWidth()  - winWidth)  / 2);
		var top =  window.screenY + topChrome * 32 + 20;
	}
	coords.left = left;
	coords.top = top;
	return coords;
}

function flexcrollUpdate(id, value) {
	if ($(id).hasClassName('flexcrollactive')) {
		$(id + '_contentwrapper').update(value);
	} else {
		$(id).update(value);
	}
}


Rot13 = {
    map: null,

    convert: function(a) {
        Rot13.init();

        var s = "";
        for (i=0; i < a.length; i++) {
            var b = a.charAt(i);
            s += ((b>='A' && b<='Z') || (b>='a' && b<='z') ? Rot13.map[b] : b);
        }
        return s;
    },

    init: function() {
        if (Rot13.map != null)
            return;
              
        var map = new Array();
        var s   = "abcdefghijklmnopqrstuvwxyz";

        for (i=0; i<s.length; i++)
            map[s.charAt(i)] = s.charAt((i+13)%26);
        for (i=0; i<s.length; i++)
            map[s.charAt(i).toUpperCase()] = s.charAt((i+13)%26).toUpperCase();

        Rot13.map = map;
    },

    write: function(a) {
        document.write(Rot13.convert(a));
    }
}

function stringPadLeft(str, width, pad) {
	str = str.toString();
	while (str.length < width) {
		str = pad + str;
	}
	return str;
}

function ucfirst(str) {
	return str.substring(0,1).toUpperCase() + str.substring(1);
}

function getKeyCode(e) {
	var iKeyCode;
	if (!e) {
		var e = window.event;
	}
	if (e.keyCode) {
		iKeyCode = e.keyCode;
	} else {
		if (e.which) {
			iKeyCode = e.which;
		}
	}
	return iKeyCode;
}

function formatNumber(num,dec,thou,pnt,curr1,curr2,n1,n2) {
	if (curr1 	=== undefined) { curr1 	= ''; }
	if (curr2 	=== undefined) { curr2 	= ''; }
	if (n1 		=== undefined) { n1 	= ''; }
	if (n2 		=== undefined) { n2 	= ''; }
	var x = Math.round(num * Math.pow(10,dec));
	if (x >= 0) n1=n2='';
	var y = (''+Math.abs(x)).split('');
	var z = y.length - dec; 
	if (z<0) z--; 
	for(var i = z; i < 0; i++) y.unshift('0');
	y.splice(z, 0, pnt); 
	if(y[0] == pnt) y.unshift('0'); 
	while (z > 3) {
		z-=3; 
		y.splice(z,0,thou);
	}
	var r = curr1+n1+y.join('')+n2+curr2;
	return r;
}