/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * Autors	: Ron Kok & Jeroen Mulder
 * Project  : Webapplication & AJAX
 * Date     : 18-05-2006	
 *
 */
 
//
//  Afhandelen XMLHTTPRequest, thnx Pavel Simakov
//  
function MakeXMLHTTPRequest () {	
	var status = null;
	var url = null;	
	var req = null;
	var msgCount = 0;	
	var inProgress = false;
	var isComplete = false;
		
	var oThis = this;
	
	// Controle op hoeveelheid berichten in log
	var internalCanMsg = function(){
		msgCount++;
		return msgCount < 100;
	}
  	
	// Voeg bericht toe aan log
	var internalOnLog = function(msg){
		if(oThis.onLog && internalCanMsg()) {
			oThis.onLog(msg);
		}
	}
  	
	// Voeg bericht toe aan interne error afhandelaar
	var internalOnError = function(msg){
		if(oThis.onError && internalCanMsg()) {
			oThis.onError(msg);
		}
	}
  	
	// Controleer of er gewacht wordt op een antwoord van een ander request
	var internalIsBusy = function(){
		return inProgress && !isComplete;
	}
  	
	// Callback functie (intern)
	var internalRequestComplete = function() {
		var STATE_COMPLETED = 4;
		var STATUS_200 = 200;
				
		if (!internalIsBusy()) {
			internalOnError("internalRequestComplete: error - no request submitted");
		}
		
		internalOnLog("internalRequestComplete: readyState " + req.readyState);
		
		if (req.readyState == STATE_COMPLETED) {
			status = req.status;
			inProgress = false;
			isComplete = true;

			internalOnLog("internalRequestComplete: status " + status);
			
			if (status == STATUS_200) {
				internalOnLog("internalRequestComplete: calling callback on content with length " + req.responseText.length + " chars");			
				if(oThis.onComplete) {
					oThis.onComplete(req.responseText, req.responseXML);
				}				 
				internalOnLog("internalRequestComplete: complete on " + new Date());
			} else {
				internalOnError("internalRequestComplete: error - bad status while fetching " + url);
			}
		} else {}
	}	
	
	// Controle op browser
	this.isSupported = function(){
		var nonEI = window.XMLHttpRequest;
		var onIE = window.ActiveXObject;
		
		if (onIE) {	    		
			onIE = new ActiveXObject("Microsoft.XMLHTTP") != null;
		}
		
		return window.XMLHttpRequest || onIE;
	}
	
	// Controle op mogelijkheid meerdere calls
	this.isBusy = function(){
		return internalIsBusy();
	}		

	//  Starten van nieuw XMLHTTPRequest
	this.submit = function(_url){	
		if (internalIsBusy()) {
			internalOnError("submit: error - busy processing another request " + _url);			
		}	
		
		msgCount = 0;
		internalOnLog("submit: started on " + new Date() + " for " + _url);
				
		url = _url;	
		status = null;
		inProgress = true;
		isComplete = false;
		
	    if (window.XMLHttpRequest) {
	    
	    	// native XMLHttpRequest object
			internalOnLog("submit: using XMLHttpRequest()");
	    
	        req = new XMLHttpRequest();
	        req.onreadystatechange = internalRequestComplete;
	        req.open("GET", url, true);
	                
        	req.send(null);	
	        	    
	    } else { 
	    	    	
	    	// IE/Windows ActiveX version
	    	if (window.ActiveXObject) {	    		
		        req = new ActiveXObject("Microsoft.XMLHTTP");
		        if (req) {
		        
					internalOnLog("submit: using Microsoft.XMLHTTP");
		        
		            req.onreadystatechange = internalRequestComplete;
		            req.open("GET", url, true);
			    	req.setrequestheader("Pragma","no-cache");
		   	    	req.setrequestheader("Cache-control","no-cache");
		           
		        	req.send();	
		        } else {
					internalOnError("submit: error - unable to create Microsoft.XMLHTTP");
		        }
		    } else {
				internalOnError("submit: error - browser does not support XML HTTP Request");
		    }
	    }
		
		internalOnLog("submit: complete");
	}
	
	// Stoppen van XMLHTTPRequest
	this.abort = function(){
		internalOnLog("abort: " + url);
		
		if (!internalIsBusy()) {
			internalOnError("abort: error - no request submitted");			
		}
	
		onComplete = null;		
		req.abort();
	}	

	// Opvragen url
	this.getUrl = function(){
		return url;
	}
	
	// Opvragen HTTP status code na completed-response
	this.getStatus = function(){
		return status;
	}	
	
	// Fatale error functie
	this.onError = function(msg){	
	} 
	
	// Log bericht functie
	this.onLog = function(msg) {
	}	
	
	// Foutloze response functie
	this.onComplete = function(responseText, responseXML){
	}
}
// ---------------------
// History management - history.js
// ---------------------
// $Id: history.js 90 2006-06-07 15:37:37Z jmulder-svn $

// ------------------
// Jeroen Mulder - http://www.jeroenmulder.com/
// ------------------
function HistoryManager (defaultHash)
{
	// Default values
	this.uri = 'window.location.href';
	this.seperator = '#';
	this.defaultHash = defaultHash;
	
	// Timer for listening
	this.timer = new Timer(this);
	this.listen(this.defaultHash);
}

HistoryManager.prototype.getHash = HistoryManagerGetHash;
HistoryManager.prototype.getHref = HistoryManagerGetHref;
HistoryManager.prototype.listen = HistoryManagerListen;
HistoryManager.prototype.goto = HistoryManagerGoto;
HistoryManager.prototype.getUri = HistoryManagerGetUri;

function HistoryManagerGetHash ()
{
	var uri = this.getUri();
	if (uri.indexOf(this.seperator) > -1)
	{
		var chunks = uri.split(this.seperator);
		return chunks[chunks.length - 1];
	} 
	else 
	{
		return this.defaultHash;
	}
}

function HistoryManagerGetHref ()
{
	return this.getUri().split(this.seperator)[0];	
}

function HistoryManagerListen (location)
{
	// Did the fragment identifier change?
	if (this.getHash() != location)
		loadStep(this.getHash());

	// Set timeout
	this.timer.setTimeout('listen', 200, this.getHash());
}

function HistoryManagerGoto (hash)
{
	window.location.href = this.getHref() + '#' + hash;	
}

function HistoryManagerGetUri ()
{
	return eval(this.uri);
}


/**
 * Session object
 */
function Session ()
{
	this.currentStep = 0;	
	this.data = new Object();
}

Session.prototype.store = SessionStore;
Session.prototype.destroy = SessionDestroy;
Session.prototype.setStep = SessionSetStep;

function SessionStore (key, value)
{
	this.data[key] = value;
}

function SessionDestroy (key)
{
	this.data[key] = new Array();	
}

function SessionSetStep (step)
{
	this.currentStep = step;	
}


// -------------------
// Algorithm's Timer Class -- http://www.codingforums.com/showthread.php?t=10531
// -------------------
// The constructor should be called with
// the parent object (optional, defaults to window).

function Timer(){
    this.obj = (arguments.length)?arguments[0]:window;
    return this;
}

// The set functions should be called with:
// - The name of the object method (as a string) (required)
// - The millisecond delay (required)
// - Any number of extra arguments, which will all be
//   passed to the method when it is evaluated.

Timer.prototype.setInterval = function(func, msec){
    var i = Timer.getNew();
    var t = Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setInterval(t,msec);
    return i;
}

Timer.prototype.setTimeout = function(func, msec){
    var i = Timer.getNew();
    Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setTimeout("Timer.callOnce("+i+");",msec);
    return i;
}

// The clear functions should be called with
// the return value from the equivalent set function.

Timer.prototype.clearInterval = function(i){
    if(!Timer.set[i]) return;
    window.clearInterval(Timer.set[i].timer);
    Timer.set[i] = null;
}

Timer.prototype.clearTimeout = function(i){
    if(!Timer.set[i]) return;
    window.clearTimeout(Timer.set[i].timer);
    Timer.set[i] = null;
}

// Private data
Timer.set = new Array();

Timer.buildCall = function(obj, i, args){
    var t = "";
    Timer.set[i] = new Array();
    if(obj != window){
        Timer.set[i].obj = obj;
        t = "Timer.set["+i+"].obj.";
    }
    t += args[0]+"(";
    if(args.length > 2){
        Timer.set[i][0] = args[2];
        t += "Timer.set["+i+"][0]";
        for(var j=1; (j+2)<args.length; j++){
            Timer.set[i][j] = args[j+2];
            t += ", Timer.set["+i+"]["+j+"]";
    }}
    t += ");";
    Timer.set[i].call = t;
    return t;
}

Timer.callOnce = function(i){
    if(!Timer.set[i]) return;
    eval(Timer.set[i].call);
    Timer.set[i] = null;
}

Timer.getNew = function(){
    var i = 0;
    while(Timer.set[i]) i++;
    return i;
}/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * $Id: globalfunctions.js 124 2006-06-17 20:44:58Z jmulder-svn $
 */

// ------------------
// Steps: Not a very nice solution...
// ------------------
var steps = ['vind', 'kies', 'gegevens', 'plan', 'bevestig'];
var STEP_DEFAULT = steps[0];

// Vars
var hm = null;
var session = null;

// Storage for effects to be executed
var fxElements = new Array;

// Immediately insert dynamic CSS to show loading
createStyleRule('body', 'visibility: hidden');
createStyleRule('html', 'background: url("/images/uba_loading.gif") no-repeat 50% 50%');
createStyleRule('#search', 'display: none');

// ------------------
// UBA
// ------------------
function initialize ()
{
	// Start new session
	session = new Session();
	
	// Start history manager with default step
	hm = new HistoryManager(STEP_DEFAULT);
	
	// Initialize default step, else wait for the history manager
	if (hm.getHash() == STEP_DEFAULT)
		initializeStep();
		
	// Display application
	setTimeout('displayUba()', 1500);
}

// Uitvoeren van een stap
function initializeStep () 
{
	// Check whether the browser supports some basic methods
	if (!document.getElementById || !document.getElementsByTagName) return;

	// ------------------
	// All Steps
	// ------------------
	
	// Assign next step handler
	assignNextStep();
	
	// Set finished steps
	setFinishedSteps();
	
	// Fix links for the history manager
	assignHistoryLinks();

	// ------------------
	// Step 1: Vind
	// ------------------
	if (steps[session.currentStep] == 'vind')
	{
		initializeStepOne();
	}
	// ------------------
	// Step 2: Kies
	// ------------------
	else if (steps[session.currentStep] == 'kies')
	{
		initializeStepTwo();
	}
	// ------------------
	// Step 3: Persoonlijke gegevens
	// ------------------
	else if (steps[session.currentStep] == 'gegevens')
	{
		initializeStepThree();
	}
	// ------------------
	// Step 4: Plannen
	// ------------------
	else if (steps[session.currentStep] == 'plan')
	{
		// Cancel fx
		cancelFx();
		
		// Wegens tijdgebrek, deze stap overslaan
		loadNextStep();
	}
	// ------------------
	// Step 5: Bevestigen
	// ------------------
	else if (steps[session.currentStep] == 'bevestig')
	{
		initializeStepFive();
	}
	
	executeFx();
}


// --------------------
// Utopia functies
// --------------------

/**
 * Assign next step functionality
 *
 * Calls a generic validation function, which
 * forwards it depending on the current step.
 */
function assignNextStep ()
{	
	if ($('next-step'))
	{
		$('next-step').onclick = function (oEvent) 
		{		
			var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
			preventDefaultEventBehavior(oEvent);
			
			// Validate data
			validateData();
		};
	
		// Assign fallback for keyboard navigation
		var form = document.getElementsByTagName('form')[0];
		
		if (form)
			form.onsubmit = $('next-step').onclick;
	}
}

/**
 * Load next step
 *
 * This function relies on a functioning
 * listener in the HistoryManager to notice URI changes.
 */
function loadNextStep ()
{
	// Requirements:
	// -------------------
	// - Define per step the required validation
	// - Define the step order
	// - Get next step and load it in the content
	// - Implement bookmarking and history state management
	
	// Set next step
	var nextStep = session.currentStep + 1;
	
	if (!steps[nextStep])
		nextStep = currentStep;
	
	// Set next step in session
	session.setStep(nextStep);
	
	// Point window to new anchor
	hm.goto(steps[nextStep]);
}

/**
 * Load step by name
 * 
 * @param string stepName
 */
function loadStep (stepName)
{
	var stepNumber = 0;
	
	// Find step number
	for (var i = 0; i < steps.length; i++)
	{
		if (steps[i] == stepName)
		{
			stepNumber = i;
			break;
		}
	}

	// This evaluates to true mostly when someone reloads the page.
	// Right now we're not storing any session data on the server or in a cookie
	// for it to load on a new pageload. Question remains whether that's desirable for
	// this type of application...
	if (stepNumber > session.currentStep)
	{
		/*
		stepNumber = 0;
		
		if (!hm) hm = new HistoryManager(steps[1]);
		if (!session) session = new Session();
		
		fxElements = new Array;
		
		session.setStep(stepNumber);
		hm.goto(STEP_DEFAULT);
		return;
		*/
		
		window.location.href = '/';
	}
	else
	{
		// Required in case we insert content afterwards
		var fxFuncOnComplete = function () { $('content').style.height = 'auto'; };
		
		// Combine height and opacity fading in
		var fxEle = new fx.Combo($('content'), {height : true, opacity : true, duration: 250, onComplete : fxFuncOnComplete});
		
		fxEle.hide();
		fxElements.push(fxEle);
		
		// Set step in session
		session.setStep(stepNumber);
	}
	
	// Load page and call initializeStep on complete
	loadPage(steps[stepNumber], $('content'), insertTemplate, [initializeStep]);
}

/**
 * Set finished steps
 * 
 * Executed on each step load
 */
function setFinishedSteps ()
{
	var steppingElements = $('stepping-line').getElementsByTagName('li');
	
	for (var i = 0; i < steppingElements.length; i++)
	{
		var steppingElement = steppingElements[i];
		
		var links = steppingElement.getElementsByTagName('a');
		
		if (i <= session.currentStep)
		{
			if (!hasClass(steppingElement, 'finished-step'))
				addClass(steppingElement, 'finished-step');
				
			// Insert a link for navigation, if needed
			if (!links.length)
			{
				var anchor = createAnchor('#' + steps[i], steppingElement.innerHTML, 'uba');
				steppingElement.replaceChild(anchor, steppingElement.childNodes[0]);
			}
		}
		else
		{
			if (hasClass(steppingElement, 'finished-step'))
				removeClass(steppingElement, 'finished-step');
				
			// Remove navigation, if needed
			if (links.length)
			{
				steppingElement.innerHTML = links[0].childNodes[0].nodeValue;
			}
		}
	}
}

/**
 * Fix UBA links
 *
 * Fetch all UBA links from document and modify
 * the href to contain a hash for the HistoryManager
 */
function assignHistoryLinks ()
{
	var historyLinks = getElementsByClassName(document, 'a', 'uba');
	
	for (var i = 0; i < historyLinks.length; i++)
	{
		var link = historyLinks[i];
		
		// Check whether there's already a fragment identifier
		if (link.getAttribute('href').indexOf('#') == -1)
		{
			// Split attribute
			var fragments = link.getAttribute('href').split('/');
			
			// Remove empty elements from the beginning and end
			if (!fragments[0])
				fragments.shift();
				
			if (!fragments[fragments.length - 1])
				fragments.pop();
				
			// Get fragment identifier
			var fragmentId = '#' + fragments[fragments.length -1];
			
			// Set new link
			link.setAttribute('href', fragmentId);
		}
	}
}


/**
 * Validate data
 *
 * TODO: Implement error messaging
 */
function validateData ()
{
	// ------------------
	// All Steps
	// ------------------
	
	// ------------------
	// Step 1: Vind
	// ------------------
	if (steps[session.currentStep] == 'vind')
	{
		validateStepOne();
	}
	// ------------------
	// Step 2: Kies
	// ------------------
	else if (steps[session.currentStep] == 'kies')
	{
		validateStepTwo();
	}
	// ------------------
	// Step 3: Gegevens
	// ------------------
	else if (steps[session.currentStep] == 'gegevens')
	{
		validateStepThree();
	}
}


// --------------------
// Standaard functies
// --------------------

function addLoadEvent(func) 
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function') 
		window.onload = func;
	else 
		window.onload = function() { oldonload(); func(); }
}

// Controle of een waarde een numeriek is
function IsNumeric(sText){
  var ValidChars = "0123456789";
  var IsNumber=true;
  var Char;
  for (i = 0; i < sText.length && IsNumber == true; i++){ 
    Char = sText.charAt(i); 
    if (ValidChars.indexOf(Char) == -1){
      IsNumber = false;
    }
  }
  return IsNumber;
}

// Verwijderen spaties links
function LTrim(value){
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
}

// Verwijderen spaties rechts
function RTrim(value){	
	var re = /((\s*\S+)*)\s*/;
  	return value.replace(re, "$1");
}

// Verwijder spaties links en rechts
function trim(value){	
	return LTrim(RTrim(value));
}

// --------------------
// Robert Nyman - http://www.robertnyman.com/
// --------------------
function preventDefaultEventBehavior (oEvent){
	if(oEvent){
		oEvent.returnValue = false;
    		
		if (oEvent.preventDefault)
			oEvent.preventDefault();
	}
}

// Bepaal of een object een bepaalde class bevat
function hasClass(obj,cName) {
	return new RegExp('\\b'+cName+'\\b').test(obj.className); 
}

// Voeg een class toe
function addClass(obj,cName) { 
	if (!hasClass(obj,cName)) { 
		obj.className+=obj.className?' '+cName:cName; 
	} 
	return true; 
} 

// Verwijder een class
function removeClass(obj,cName) { 
	if (!hasClass(obj,cName)) 
	return false; 
	var rep=obj.className.match(' '+cName)?' '+cName:cName; 
	obj.className=obj.className.replace(rep,''); 
	return true; 
}

/**
 * Toggle display value of element(s) recursively
 * 
 * @param mixed ele			Element or list of elements to toggle
 */
function toggle (ele)
{
	if (ele.length) // Hack?
	{
		for (var i = 0; i < ele.length; i++)
			toggle(ele[i]);
	}
	else
	{
		if (ele.style.display != 'none')
			ele.style.display = 'none';
		else
			ele.style.display = '';
	}
}

/**
 * Load template into application
 *
 * Get the template from disk and load it into the specified
 * target element. On completion, execute the specified function. 
 *
 * Setting <code>replaceElement</code> to true allows you to replace
 * the target element, instead of inserting the template into it.
 * 
 * @param string name 							Template name
 * @param object target							Target to load template in
 * @param function executeFuncOnComplete		Execute function when finished retrieving template
 * @param bool replaceElement					Replace target element, instead of inserting into
 */
function makeRequestForContent (name, target, executeFuncOnComplete, funcArguments)
{
	var provider = new MakeXMLHTTPRequest();
	
	provider.onComplete = function (responseText, responseXML)
	{		
		// Build arguments list
		var argumentsStr = '';
		
		if (typeof funcArguments != 'undefined')
		{
			for (var i = 0; i < funcArguments.length; i++)
				argumentsStr += ', ' + funcArguments[i];
		}
		
		// Execute function
		eval('executeFuncOnComplete(target, responseText' + argumentsStr + ')');
	};
	
	return provider;
}

// Default behaviour for inserting a template
function insertTemplate (target, responseText, executeFuncOnComplete, replaceElement, hideElement)
{
	replaceElement = (typeof replaceElement != 'undefined') ? replaceElement : false;
	hideElement = (typeof replaceElement != 'undefined') ? hideElement : false;	
	
	if (replaceElement)
	{
		// Replace element
		// TODO: Copy the properties of the target
		var ele = document.createElement('div');
		ele.innerHTML = responseText;
		
		if (hideElement)
		{
			// Only hide the childs, not the actual container
			var child = firstElement(ele);
			while (child)
			{
				child.style.visibility = 'hidden';
				child = nextElement(child);
			}
		}
		
		var parent = target.parentNode;
		parent.replaceChild(ele, target);
	}
	else
	{
		// Replace contents
		target.innerHTML = responseText;
	}
	
	if (typeof executeFuncOnComplete == 'function')
		executeFuncOnComplete();	
}

// Load page as a plain template
function loadTemplate (name, target, executeFuncOnComplete, funcArguments)
{
	var provider = makeRequestForContent(name, target, executeFuncOnComplete, funcArguments);	
	
	provider.submit('/lib/request.php?type=getTemplate&tpl=' + name);
}

// Load page as a processed template
function loadPage (name, target, executeFuncOnComplete, funcArguments)
{
	var provider = makeRequestForContent(name, target, executeFuncOnComplete, funcArguments);	
	
	provider.submit('/lib/request.php?type=getPage&page=' + name);
}

// Get template from disk
function getTemplate (name, executeFuncOnComplete)
{
	var provider = new MakeXMLHTTPRequest();
	
	provider.onComplete = function (responseText, responseXML)
	{		
		if (typeof executeFuncOnComplete == 'function')
			executeFuncOnComplete(responseText, responseXML);
	};
	
	provider.submit('/lib/request.php?type=getTemplate&tpl=' + name);	
}

/**
 * Display the application
 */
function displayUba ()
{
	// Remove loading background
	document.getElementsByTagName('html')[0].style.background = 'none';
	
	// Display application
	//document.body.style.visibility = 'visible';
	
	var fxEle = new fx.Opacity(document.body, {duration : 250});
	
	fxEle.hide();
	fxEle.toggle();
}

/**
 * Execute moofx effects
 */
function executeFx ()
{
	if (fxElements)
	{
		for (var i = 0; i < fxElements.length; i++)
		{
			fxElements[i].toggle();	
		}
		fxElements = new Array;
	}
}

/**
 * Cancel moofx effects
 */
function cancelFx ()
{
	if (fxElements)
	{
		for (var i = 0; i < fxElements.length; i++)
		{
			fxElements[i].clearTimer();	
		}
		fxElements = new Array;
	}
}

// Prototype dollar function
function $ ()
{
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}

// Push method for MSIE5.x
if (typeof Array.prototype.push != 'function')
{
	Array.prototype.push = ArrayPush;
	function ArrayPush (value) {
		this[this.length] = value;
	}
}

/**
 * Mark a correct or incorrect field
 */
function markField(field, mode){
	if(mode == 'correct'){
		removeClass(field,'incorrect');
	}
	else{
		addClass(field,'incorrect');
	}
}


/**
 *	Select a row and deselect all other available rows
 */ 
function selectRow(){
	var tableBody = this.parentNode;
	var rows = tableBody.getElementsByTagName('tr');
	for(i=0;i<rows.length;i++){
		var row = rows[i];
		removeClass(row,'selected');
	}
	addClass(this,'selected');
	var radio = this.getElementsByTagName('input')[0];
	radio.checked = 'checked';
}

/**
 * Create radio button
 *
 * @param string name
 * @param string value
 * @param bool isChecked
 * @return object
 */
function createRadioButton (name, value, isChecked)
{
	var radio = document.createElement('input');
	
	radio.type = 'radio';
	radio.name = name;
	radio.value = value;
	
	if (isChecked)
		radio.checked = 'checked';
		
	return radio;
}

/**
 * Create anchor
 *
 * @param string href
 * @param string str
 * @param string class
 * @param string id
 * @return object
 */
function createAnchor (strHref, strText, strClassName, strId)
{
	var anchor = document.createElement('a');
	
	if (strHref) anchor.href = strHref;
	if (strText) anchor.innerHTML = strText;
	if (strClassName) anchor.className = strClassName;
	if (strId) anchor.id = strId;
	
	return anchor;
}

/**
 * Display settings functionality
 *
 * Displays the preferences selected in the previous steps.
 *  
 */
function displaySettings ()
{
	// Get preferences from the session for other steps
	if (session.data.preferences)
		preferences = session.data.preferences;

	var targets = $('current-booking-data').getElementsByTagName('dd');
	var currentStep = steps[session.currentStep];
	
	var dateField = targets[0];
	var accommodationField = targets[1];
	var priceField = targets[2];
	
	// Datum voorbereiding
	var tempMonthYear = preferences.Month.split('-');
	var startDate = preferences.Day + '-'+tempMonthYear[0];
	var endDate = parseInt(preferences.Day)+parseInt(preferences.DuranceStay) + '-' + tempMonthYear[0] + ' 20' + tempMonthYear[1];
	var date = startDate + ' <em>t/m</em> ' + endDate + ' (' + preferences.DuranceStay + ' nachten)';

	dateField.innerHTML = date;
	accommodationField.innerHTML = preferences.AccommodationTypeFull +' voor ' + preferences.AccommodationSizeFull;
	priceField.innerHTML = '&euro; ' + preferences.AccommodationPriceFrom;
	
	if(currentStep != 'vind' && currentStep != 'kies'){
		var locationField = targets[3];
		var zone = preferences.AccommodationZone.split('-');
		var zoneNumber = zone[1];
		
		locationField.innerHTML = preferences.AccommodationZoneDescription.replace('-', '') + ' (zone ' + zoneNumber + ')';
	}	
}

// --------------------
// Jeroen Mulder - http://www.jeroenmulder.com/
// --------------------
function previousElement (obj)
{
	var previousElement = obj.previousSibling;
	
	while (previousElement && previousElement.nodeType != '1')
	{
		previousElement = previousElement.previousSibling;
	}
	
	return previousElement;
}

function nextElement (obj)
{
	var nextElement = obj.nextSibling;
	
	while (nextElement && nextElement.nodeType != '1')
	{
		nextElement = nextElement.nextSibling;
	}
	
	return nextElement;
}

function firstElement (obj)
{
	var firstElement = obj.firstChild;
	
	while (firstElement && firstElement.nodeType != '1')
	{
		firstElement = nextElement(firstElement);
	}
	
	return firstElement;	
}

function lastElement (obj)
{
	var lastElement = obj.lastChild;
	
	while (lastElement && lastElement.nodeType != '1')
	{
		lastElement = previousElement(lastElement);
	}
	
	return lastElement;	
}


function removeChilds (obj)
{
	while (obj.firstChild)
		obj.removeChild(obj.firstChild);
	return obj;
}

/*
    Written by Jonathan Snook, http://www.snook.ca/jonathan
    Add-ons by Robert Nyman, http://www.robertnyman.com
*/

function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }   
    }
    return (arrReturnElements)
}

/*	dynamicCSS.js v1.0 <http://www.bobbyvandersluis.com/articles/dynamicCSS.php>
	Copyright 2005 Bobby van der Sluis
	This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
function createStyleRule(selector, declaration) {
    if (!document.getElementsByTagName ||
      !(document.createElement || document.createElementNS)) return;
    var agt = navigator.userAgent.toLowerCase();
    var is_ie = ((agt.indexOf("msie") != -1) &&  (agt.indexOf("opera") == -1));
    var is_iewin = (is_ie &&  (agt.indexOf("win") != -1));
    var is_iemac = (is_ie &&  (agt.indexOf("mac") != -1));
    if (is_iemac) return; // script doesn't work properly in IE/Mac
    var head = document.getElementsByTagName("head")[0]; 
    var style = (typeof document.createElementNS != "undefined") ?
      document.createElementNS("http://www.w3.org/1999/xhtml", "style") :
      document.createElement("style");
    if (!is_iewin) {
        var styleRule = document.createTextNode(selector + " {" + declaration + "}");
	    style.appendChild(styleRule); // bugs in IE/Win
    }
	style.setAttribute("type", "text/css");
    style.setAttribute("media", "screen");
    head.appendChild(style);
    if (is_iewin &&  document.styleSheets &&  document.styleSheets.length > 0) {
        var lastStyle = document.styleSheets[document.styleSheets.length - 1];
        if (typeof lastStyle.addRule == "object") {
            lastStyle.addRule(selector, declaration);
        }
    }
}

/*
 * Form Field Falidation
*/  


/**
 * Add Form Field Validatoin
 *
 * Add onblur event handlers to inputfields.
 *  
 */
function addFormFieldValidation(){
	var formFields = document.getElementsByTagName('input');
	for (var i = 0; i < formFields.length; i++) {
		if(formFields[i].id != 'submit-person'){
			formFields[i].onblur = validateField;
		}
	}
}

/**
 * Validate Field
 *
 * Validate the value of the used inputfield.
 *  
 */
function validateField(){
	var fieldId = this.id;
	var fieldValue = this.value;

	// Ophalen openstaande foutmeldingen
	var errorMessages = getElementsByClassName(document, 'div', 'error');
	
	// Openstaande foutmeldingen wissen
	if(errorMessages.length != 0){
		
		for(var i = 0; i < errorMessages.length; i++){
			
			errorBox = errorMessages[i];
			errorBoxParrent = errorBox.parentNode;
			errorBoxParrent.removeChild(errorBox);

		}
	
	}
	
	var url = "/lib/request.php?type=validateField&fieldId=" + fieldId +"&fieldValue=" + fieldValue;
	
	var provider = new MakeXMLHTTPRequest();
		provider.onComplete = processValidation;
		provider.submit(url);

}

/**
 * Process Validation
 *
 * Process the validation result from the server.
 *  
 */
function processValidation(responseText, responseXML){
	var result = responseXML.getElementsByTagName('result')[0].firstChild.nodeValue;
	if(result == 'failed'){
		var reason = responseXML.getElementsByTagName('reason')[0].firstChild.nodeValue;
		var fieldId = responseXML.getElementsByTagName('fieldid')[0].firstChild.nodeValue;
		displayError(fieldId, reason);
	}
	else if(result == 'passed'){
		var fieldId = responseXML.getElementsByTagName('fieldid')[0].firstChild.nodeValue;
		clearError(fieldId);
	}
	
}

 

/**
 * Display Error
 *
 * Display an errormessage.
 *  
 */
function displayError(fieldId, reason){
	var inputField = document.getElementById(fieldId);
	addClass(inputField, 'error-field');
	var daddy = inputField.parentNode;
	
	var y = document.createElement('div');
	y.className = 'error';
	y.id = 'error-' + fieldId;
	y.innerHTML = '<p>' + reason + '</p>';
	var q = document.createElement('div');
	q.className = 'pointer';
	
	// Pijltje aanpassen op speciale velden, dit moet anders...
	if(fieldId == 'streetnumber'){
		q.style.left = '415px';
	}
	else if(fieldId == 'dob-day'){
		q.style.left = '125px';
	}
	else if(fieldId == 'dob-year'){
		q.style.left = '263px';
	}

	y.appendChild(q);
	daddy.appendChild(y);
	//inputField.focus();
}

/**
 * Clear Error
 *
 * Remove an error mark.
 *  
 */
function clearError(fieldId){
	
	var inputField = document.getElementById(fieldId);
	removeClass(inputField, 'error-field');
}

// AddLoadEvents initialiseren
addLoadEvent(initialize);
/*  Prototype JavaScript framework
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
/*--------------------------------------------------------------------------*/

//note: modified & stripped down version of prototype, to be used with moo.fx by mad4milk (http://moofx.mad4milk.net).

var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
}

Object.extend = function(destination, source) {
	for (property in source) destination[property] = source[property];
	return destination;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

Function.prototype.bindAsEventListener = function(object) {
var __method = this;
	return function(event) {
		__method.call(object, event || window.event);
	}
}

if (!window.Element) var Element = new Object();

Object.extend(Element, {
	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
	},

	hasClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var hasClass = false;
		element.className.split(' ').each(function(cn){
			if (cn == className) hasClass = true;
		});
		return hasClass;
	},

	addClassName: function(element, className) {
		element = $(element);
		Element.removeClassName(element, className);
		element.className += ' ' + className;
	},
  
	removeClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var newClassName = '';
		element.className.split(' ').each(function(cn, i){
			if (cn != className){
				if (i > 0) newClassName += ' ';
				newClassName += cn;
			}
		});
		element.className = newClassName;
	},

	cleanWhitespace: function(element) {
		element = $(element);
		$c(element.childNodes).each(function(node){
			if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node);
		});
	},

	find: function(element, what) {
		element = $(element)[what];
		while (element.nodeType != 1) element = element[what];
		return element;
	}
});

var Position = {
	cumulativeOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return [valueL, valueT];
	}
};

//useful array functions
Array.prototype.iterate = function(func){
	for(var i=0;i<this.length;i++) func(this[i], i);
}
if (!Array.prototype.each) Array.prototype.each = Array.prototype.iterate;

function $c(array){
	var nArray = [];
	for (var i=0;i<array.length;i++) nArray.push(array[i]);
	return nArray;
}

/*
moo.fx, simple effects library built with prototype.js (http://prototype.conio.net).
by Valerio Proietti (http://mad4milk.net) MIT-style LICENSE.
for more info (http://moofx.mad4milk.net).
Sunday, March 05, 2006
v 1.2.3
*/

var fx = new Object();
//base
fx.Base = function(){};
fx.Base.prototype = {
	setOptions: function(options) {
	this.options = {
		duration: 500,
		onComplete: '',
		transition: fx.sinoidal
	}
	Object.extend(this.options, options || {});
	},

	step: function() {
		var time  = (new Date).getTime();
		if (time >= this.options.duration+this.startTime) {
			this.now = this.to;
			clearInterval (this.timer);
			this.timer = null;
			if (this.options.onComplete) setTimeout(this.options.onComplete.bind(this), 10);
		}
		else {
			var Tpos = (time - this.startTime) / (this.options.duration);
			this.now = this.options.transition(Tpos) * (this.to-this.from) + this.from;
		}
		this.increase();
	},

	custom: function(from, to) {
		if (this.timer != null) return;
		this.from = from;
		this.to = to;
		this.startTime = (new Date).getTime();
		this.timer = setInterval (this.step.bind(this), 13);
	},

	hide: function() {
		this.now = 0;
		this.increase();
	},

	clearTimer: function() {
		clearInterval(this.timer);
		this.timer = null;
	}
}

//stretchers
fx.Layout = Class.create();
fx.Layout.prototype = Object.extend(new fx.Base(), {
	initialize: function(el, options) {
		this.el = el;
		this.el.style.overflow = "hidden";
		this.iniWidth = this.el.offsetWidth;
		this.iniHeight = this.el.offsetHeight;
		this.setOptions(options);
	}
});

fx.Height = Class.create();
Object.extend(Object.extend(fx.Height.prototype, fx.Layout.prototype), {	
	increase: function() {
		this.el.style.height = this.now + "px";
	},

	toggle: function() {
		if (this.el.offsetHeight > 0) this.custom(this.el.offsetHeight, 0);
		else this.custom(0, this.el.scrollHeight);
	}
});

fx.Width = Class.create();
Object.extend(Object.extend(fx.Width.prototype, fx.Layout.prototype), {	
	increase: function() {
		this.el.style.width = this.now + "px";
	},

	toggle: function(){
		if (this.el.offsetWidth > 0) this.custom(this.el.offsetWidth, 0);
		else this.custom(0, this.iniWidth);
	}
});

//fader
fx.Opacity = Class.create();
fx.Opacity.prototype = Object.extend(new fx.Base(), {
	initialize: function(el, options) {
		this.el = el;
		this.now = 1;
		this.increase();
		this.setOptions(options);
	},

	increase: function() {
		if (this.now == 1 && (/Firefox/.test(navigator.userAgent))) this.now = 0.9999;
		this.setOpacity(this.now);
	},
	
	setOpacity: function(opacity) {
		if (opacity == 0 && this.el.style.visibility != "hidden") this.el.style.visibility = "hidden";
		else if (this.el.style.visibility != "visible") this.el.style.visibility = "visible";
		if (window.ActiveXObject) this.el.style.filter = "alpha(opacity=" + opacity*100 + ")";
		this.el.style.opacity = opacity;
	},

	toggle: function() {
		if (this.now > 0) this.custom(1, 0);
		else this.custom(0, 1);
	}
});

//composition effect: widht/height/opacity
fx.Combo = Class.create();
fx.Combo.prototype = {
	setOptions: function(options) {
		this.options = {
			opacity: true,
			height: true,
			width: false
		}
		Object.extend(this.options, options || {});
	},

	initialize: function(el, options) {
		this.el = el;
		this.setOptions(options);
		if (this.options.opacity) {
			this.o = new fx.Opacity(el, options);
			options.onComplete = null;
		}
		if (this.options.height) {
			this.h = new fx.Height(el, options);
			options.onComplete = null;
		}
		if (this.options.width) this.w = new fx.Width(el, options);
	},
	
	toggle: function() { this.checkExec('toggle'); },

	hide: function(){ this.checkExec('hide'); },
	
	clearTimer: function(){ this.checkExec('clearTimer'); },
	
	checkExec: function(func){
		if (this.o) this.o[func]();
		if (this.h) this.h[func]();
		if (this.w) this.w[func]();
	},
	
	//only if width+height
	resizeTo: function(hto, wto) {
		if (this.h && this.w) {
			this.h.custom(this.el.offsetHeight, this.el.offsetHeight + hto);
			this.w.custom(this.el.offsetWidth, this.el.offsetWidth + wto);
		}
	},

	customSize: function(hto, wto) {
		if (this.h && this.w) {
			this.h.custom(this.el.offsetHeight, hto);
			this.w.custom(this.el.offsetWidth, wto);
		}
	}
}

//transitions
fx.sinoidal = function(pos){
	return ((-Math.cos(pos*Math.PI)/2) + 0.5);
	//this transition is from script.aculo.us
}
fx.linear = function(pos){
	return pos;
}
fx.cubic = function(pos){
	return Math.pow(pos, 3);
}
fx.circ = function(pos){
	return Math.sqrt(pos);
}/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * $Id: step1.js 124 2006-06-17 20:44:58Z jmulder-svn $
 */
 
// Preferences Object
var preferences = {	Day : null,
					Month : null,
					DuranceStay : 0,
					
					AccommodationType : null,
					AccommodationSize : null,
					AccommodationNumber : null };
					
// Initialiseer
function initializeStepOne ()
{
	$('period-day').onkeyup = dayChange;
	$('period-month').onchange = monthChange;
	$('period-duration').onchange = duranceChange;
	
	
	// Hide elements we don't need anyway
	toggle($('selection-type').getElementsByTagName('input'));
	toggle($('selection-size').getElementsByTagName('input'));
	toggle($('search'));
	
	if (!session.data.preferences)
	{
		initListOrdering();
		
		// Store default date values
		preferences.Day = $("period-day").value;
		preferences.Month = $("period-month").value;
		preferences.DuranceStay = $("period-duration").value;
	}
	else
	{
		// Set type and size criteria
		initListOrdering(session.data.preferences.AccommodationType, session.data.preferences.AccommodationSize);
		
		// Set period selection
		$('period-day').value = session.data.preferences.Day;
		$("period-month").value = session.data.preferences.Month;
		$('period-duration').value = session.data.preferences.DuranceStay;
		
		// Controleren of de resultaten tabel al is ingevoegd.
		// Zo niet, ophalen en er in kwakken.
		if (!$('results').getElementsByTagName('tbody').length)
			loadTemplate('search_results', $('results'), displayResults, [getResults]);
		else
			getResults();
	}
}

// Wanneer dagnummer aangepast wordt
function dayChange(){
  // Ophalen waarde
  var day = $("period-day").value;
  // Controleren waarde
  if(IsNumeric(day)){
  	markField($("period-day"),'correct');
    // Waarde opslaan in globale wensenlijst
    preferences.Day = day;
    // Wijzigen dagnaam
    nameDate();
    // Tonen resultaten
	if (preferences.AccommodationType || preferences.AccommodationSize)
		getResults();
  }
  else{
	// TODO: Vriendelijkere manier van foutmeldingen
    markField($("period-day"),'incorrect');
  }
}

// Wanneer maandnummer aangepast wordt
function monthChange(){
	// Ophalen waarde
	var month = $("period-month").value;
	// Waarde opslaan in globale wensenlijst
	preferences.Month = month;
	// Wijzigen dagnaam
	nameDate();
	// Tonen resultaten
	if (preferences.AccommodationType || preferences.AccommodationSize)
		getResults();
}

// Wanneer duuraantal aangepast wordt
function duranceChange(){
  // Ophalen waarde
  var duranceStay = $("period-duration").value;
  if(IsNumeric(duranceStay)){
  	markField($("period-duration"),'correct');
    // Waarde opslaan in globale wensenlijst
    preferences.DuranceStay = duranceStay;
    // Tonen resultaten
	if (preferences.AccommodationType || preferences.AccommodationSize)
    	getResults();
  }
  else{
	// TODO: Vriendelijkere manier van foutmeldingen
    markField($("period-duration"),'incorrect');
  }
}

// Functie die datum gebruikt om dagnaam te bepalen
function nameDate(){
  // URL gereedmaken
  var url = '/lib/request.php?type=getDate2Name&day='+preferences.Day+'&monthyear='+preferences.Month;
  // Aanroepen XMLHttpRequest
  var provider = new MakeXMLHTTPRequest();
  		
		provider.onComplete = processNameChange;
		provider.submit(url);
}

// Functie uitgevoerd na statechange van nameDate
function processNameChange(responseText, responseXML){
    // XML antwoord opslaan in variabele
    var response  = responseXML;
    // Resultaat uit XML antwoord halen
    var dagnaam = response.getElementsByTagName('dagnaam')[0].firstChild.nodeValue;
    // Aanpassen dagnaam
    changeDay(dagnaam);
}

// Functie die dagnaam aanpast
function changeDay(dagnaam){
  //$('period-day').innerHTML = '';
  dagnaam = trim(dagnaam);
  $('period-dayname').innerHTML = dagnaam;
}

// Links toekennen aan accommodatie lijsten
function initListOrdering (selectedType, selectedSize)
{
	// Haal alleen relevante links op
	var anchorsa = $('selection-type').getElementsByTagName('li');
	var anchorsb = $('selection-size').getElementsByTagName('li');
	
	// Doorloop de type-links
	for (var i = 0; i < anchorsa.length; i++)
	{
    	var label = firstElement(anchorsa[i]);
		
		var anchor = document.createElement('a');
		anchor.innerHTML = label.innerHTML;
		
    	anchor.onclick = function (oEvent)
		{ 
			 var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
			 preventDefaultEventBehavior(oEvent);
			 accommodationChange(this);
    	}
		
		anchor.setAttribute('href', '#');
		anchor.setAttribute('tabindex', (i+20));
		
		// Set selected value
		if (typeof selectedType != 'undefined')
		{
			var radio = anchor.getElementsByTagName('input')[0];
			
			if (selectedType && radio.value == selectedType)
				addClass(anchor, 'selected');
		}
		
		label.parentNode.replaceChild(anchor, label);
  	}
  
  	// Doorloop de size-links
	for (var i = 0; i < anchorsb.length; i++)
	{
    	var label = firstElement(anchorsb[i]);
		
		var anchor = document.createElement('a');
		anchor.innerHTML = label.innerHTML;
		
    	anchor.onclick = function (oEvent)
		{ 
			 var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
			 preventDefaultEventBehavior(oEvent);
			 accommodationChange(this);
    	}
		
		anchor.setAttribute('href', '#');
		anchor.setAttribute('tabindex', (i+30));
		
		// Set selected value
		if (typeof selectedSize != 'undefined')
		{
			var radio = anchor.getElementsByTagName('input')[0];
			
			if (selectedType && radio.value == selectedSize)
				addClass(anchor, 'selected');
		}
		
		label.parentNode.replaceChild(anchor, label);
  	}
}

// Wanneer er een accommodatie-eigenschap aangepast wordt
function accommodationChange(obj){
  // Ophalen waarde
  var value = firstElement(obj).value;
  // Bepalen status
  var status = obj.className;
  // Bepalen grootvader id
  var ubergranddad = obj.parentNode.parentNode.parentNode;
  // Bepalen acties
  if(status == 'selected'){
    // Highlight verwijderen
    removeClass(obj,'selected');
    // Verwijderen opgeslagen waarde
    value = '';
  }
  else{
    // Keuzemogelijkheden wegstrepen
    var items = ubergranddad.getElementsByTagName('a');
    for (var i=0;i<items.length;i++)
	{
      if(items[i].className != 'out')
        items[i].className='';
	}
    // Gekozen item highlighten
    addClass(obj,'selected');
  }
  // Waarde opslaan onder juiste noemer
  if(ubergranddad.id =='selection-type'){
    // Opslaan waarde
    preferences.AccommodationType = value;
  }
  else{
    preferences.AccommodationSize = value;
  }
  updateNeighbour(ubergranddad);

  // Controleren of de resultaten tabel al is ingevoegd.
  // Zo niet, ophalen en er in kwakken.
  if (!$('results').getElementsByTagName('tbody').length)
	loadTemplate('search_results', $('results'), displayResults, [getResults]);
  else
  	getResults();
}

// Functie voor het kleuren van de keuzemogelijkheden
function updateNeighbour(granddad){

  var listType = granddad.id;
  var listNeighbour;
  var itemValue;
  var links;
  var disableA;
  var disableB;
  
  if(listType == 'selection-type'){
    listNeighbour = 'selection-size';
    itemValue = preferences.AccommodationType;
    links = $(listNeighbour).getElementsByTagName('a');
    
    if (itemValue.indexOf('hotel') != -1){
      disableA = '8-16pers';
    }
    else if (itemValue.indexOf('bungalow') != -1){
      disableA = '1-2pers';
    }
    
    for (var i = 0; i < links.length; i++){
	  var label = links[i];
	  var link = firstElement(label);
	  
      if (link.value == disableA){
        
		if (label.className == 'selected'){
          preferences.AccommodationSize = '';
        }
        label.className = 'out';
        label.onclick = disableClick;
      }
      else{
        if (label.className != 'selected'){
          label.className='';
          label.onclick = function (oEvent) 
  			{
  				var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
  				preventDefaultEventBehavior(oEvent);
  				 accommodationChange(this);
  			}
        }
      } 
    }
  }
  else{
    listNeighbour = 'selection-type';
    itemValue = preferences.AccommodationSize;
    links = $(listNeighbour).getElementsByTagName('a');
    
    if (itemValue == '8-16pers'){
      disableA = 'hotel';
    }
    else if (itemValue == '1-2pers'){
      disableA = 'bungalow';
    }
    
    for (var i = 0; i < links.length; i++){
      
	  var label = links[i];
	  var link = firstElement(label);
	  
      if (link.value.indexOf(disableA) != -1){
        if(label.className == 'selected'){
          preferences.AccommodationType = '';
        }
        label.className = 'out';
        label.onclick = disableClick;
      }
      else{
        if(label.className != 'selected'){
          label.className='';
          label.onclick = function (oEvent) 
  			{
  				var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
  				preventDefaultEventBehavior(oEvent);
  				 accommodationChange(this);
  			}
        }
      }
    }
  }
}

function disableClick(oEvent){
  var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
  preventDefaultEventBehavior(oEvent);
}
function enableClick(oEvent){
  var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
  preventDefaultEventBehavior(oEvent);
  accommodationChange(this);
}

// Functie die de effecten en templates afwerkt
function displayResults (target, responseText, executeFuncOnComplete)
{	
	var onCompleteFunc = function ()	
	{
		// Insert template
		insertTemplate(target, responseText, false, true, true);

		// Set up and hide effects
		var fxResults = new fx.Opacity($('results'), {duration: 150});
		var fxFooter = new fx.Opacity($('footer'), {duration: 150});
		
		fxResults.hide();
		fxFooter.hide();
		
		// Store effects
		fxElements.push(fxResults);
		fxElements.push(fxFooter);
		
		// Get results
		executeFuncOnComplete();
	};

	var fxIllustration = new fx.Opacity($('frontpage-illustration'), {duration: 150, onComplete : onCompleteFunc });

	fxIllustration.toggle();
}

// Functie die resultaten weergeeft.
function getResults()
{
  // URL gereedmaken
  var url = '/lib/request.php?type=getAccommodations&day='+preferences.Day+'&monthyear='+preferences.Month+'&duranceStay='+preferences.DuranceStay;
  if(preferences.AccommodationType){
    url = url+'&accommodationType='+preferences.AccommodationType;
  }
  if(preferences.AccommodationSize){
    url = url+'&accommodationSize='+preferences.AccommodationSize;
  }
  var provider = new MakeXMLHTTPRequest();
		provider.onComplete = processResults;
		provider.submit(url);
}

// Functie uitgevoerd na statechange van getResults
function processResults(responseText, responseXML){
  // XML antwoord opslaan in variabele
  var response  = responseXML;
  
  // Opschonen resultaattabel
  var doel = $('results').getElementsByTagName('tbody')[0];
  
  if(doel.childNodes.length > 0){
	  while(doel.childNodes.length > 0){
	    doel.removeChild(doel.childNodes[0]);
	  }
  }
  
  // Ophalen verschillende typen accommodaties
  var typen = response.getElementsByTagName("categorie");
  
  // Doorlopen verschillende typen accommodaties
  for (var i=0;i<typen.length;i++){
    categorieNaam = typen[i].firstChild.nodeValue;

    var rowHeadTh = document.createElement("th");
    rowHeadTh.appendChild(document.createTextNode(categorieNaam));
    rowHeadTh.colSpan = "3";
    var rowHeadTr = document.createElement("tr");
    rowHeadTr.appendChild(rowHeadTh);
    doel.appendChild(rowHeadTr);
	
    //Ophalen verschillende accommodaties van het type
    var accommodaties = typen[i].getElementsByTagName('accommodatie');
  
    // Door de accommodaties heen lopen
    for (var y=0;y<accommodaties.length;y++)
	{      
		var id = accommodaties[y].getElementsByTagName("id")[0].firstChild.nodeValue;
		var size = accommodaties[y].getElementsByTagName("grootte")[0].firstChild.nodeValue;
		var price = accommodaties[y].getElementsByTagName("prijs")[0].firstChild.nodeValue;
		var available = "x";

		// Hack
		var isSelected = false;
		
		if (session.data.preferences && session.data.preferences.AccommodationNumber)
			isSelected = (session.data.preferences.AccommodationNumber == id) ? true : false;
		
		var cellSize = document.createElement("td");
		cellSize.appendChild(document.createTextNode(size));
		cellSize.className = "results-type";
	  
		var cellPrice = document.createElement("td");
		cellPrice.appendChild(document.createTextNode(price));
		cellPrice.className = "results-price";
		
		var cellX = document.createElement("td");
		cellX.className = "results-x";
		
		var radioButton = createRadioButton('results_acc', id, isSelected);
		radioButton.setAttribute('tabindex', (y+40));
		cellX.appendChild(radioButton);
		
		var row = document.createElement("tr");
		// Wanneer er op de rij geklikt wordt, deze selecteren
		row.onclick = selectRow;
		row.className = 'selectable';
	  
		// Check whether a preference for accommodation exists
		if (isSelected)
		{
			addClass(row, 'selected');
		}
	  
		row.appendChild(cellSize);
		row.appendChild(cellPrice);
		row.appendChild(cellX);
		
		doel.appendChild(row);
    }
	
	// Voeg 'last' CSS classe toe aan laatste rij
	addClass(lastElement(doel), 'last');
	
	// Omdat we in eerste instantie niet de resultaten tabel tonen, 
	// kunnen we niet 'onload' de volgende stap functionaliteit toewijzen.
	// Controleer of dat als is gedaan, zo niet, doe het dan.
	if (typeof $('next-step').onclick != 'function')
		assignNextStep();
  }
  
  // Ophalen totaal aantal gevonden accommodaties
  var resultsNr = response.getElementsByTagName("aantal")[0].firstChild.nodeValue;
  // Navigeren naar element dat aantal bevat
  var resultsTotal = $("results-total").getElementsByTagName("h3")[0].getElementsByTagName("strong")[0];
  resultsTotal.innerHTML= resultsNr;
  
  // Walk through currently available effects
  executeFx();
  
  $('results').parentNode.style.background = '';  
}

function validateStepOne ()
{
	preferences.AccommodationNumber = null;
	
	// Ophalen geselecteerde accommodatie
	var fields = $('results').getElementsByTagName('input');	

	for (var i = 0; i < fields.length ; i++)
	{
		var field = fields[i];
		
		if (field.getAttribute('name') == 'results_acc')
		{		
			if(field.checked)
				preferences.AccommodationNumber = field.value;
		}
	}
	
	// TODO: Meer controle. ALLES meesturen om te controleren
	// of de volledige combinatie juist is.
		
	// Doe the request
	if (preferences.AccommodationNumber)
	{
		var url = '/lib/request.php?type=getAccommodation&accommodationNumber='+preferences.AccommodationNumber+'&duranceStay='+preferences.DuranceStay;
		
		var provider = new MakeXMLHTTPRequest();
			provider.onComplete = processValidateStepOne;
			provider.submit(url);
	}
	else
	{
		// TODO: Foutmelding	
	}
}

function processValidateStepOne(responseText, responseXML)
{
	var response = responseXML;
	
	// Store extra accommodation information
	preferences.AccommodationTypeFull = response.getElementsByTagName('typeV')[0].firstChild.nodeValue;
	preferences.AccommodationSizeNumber = response.getElementsByTagName('grootte')[0].firstChild.nodeValue;
	preferences.AccommodationSizeFull = response.getElementsByTagName('grootteV')[0].firstChild.nodeValue;
	preferences.AccommodationPriceFrom = response.getElementsByTagName('prijs')[0].firstChild.nodeValue;	

	// Store preferences in session object
	session.store('preferences', preferences);

	// Proceed to load next step
	loadNextStep();
}

/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * $Id: step2.js 125 2006-06-17 21:18:44Z jmulder-svn $
 */
 
// Initialize
function initializeStepTwo ()
{
	// Location selection
	populateLocation();
	
	// Display current booking criteria
	displaySettings();
}

// Selecteer een rij en deselecteer mogelijk geselecteerde andere rij

/**
 * Populate location functionality
 *
 * Takes care of the onclick, onmouse, etc. for 
 * the second step. Fills the Definition Descriptions 
 * with the zonename.   
 *  
 */
function populateLocation(){

	// Locaties klikbaar maken en events toekennen
	var locations = $('selection-location').getElementsByTagName('tr');
	
	// Fetch data from session, if it exists
	var selectedAccommodationZone = (session.data.preferences.AccommodationZone) ? session.data.preferences.AccommodationZone : null;
	var tableHeader = null;
	
	for (var i=0;i<locations.length;i++) 
	{
		var location = locations[i];
		
		addClass(location, 'selectable');
		
		if (firstElement(location).nodeName == 'TD')
		{
			// Assign behaviour
			location.onclick = function () { selectZone(this) };
			
			// Hide location
			toggle(location);
			
			var radio = location.getElementsByTagName('input')[0];
			
			if (radio.value == selectedAccommodationZone)
			{
				// If it does match, simulate an onclick
				selectZone(location);
				
				// Find our previous TH and simulate its onclick
				tableHeader = location;
				while (firstElement(tableHeader) && firstElement(tableHeader).nodeName != 'TH')
				{
					tableHeader = previousElement(tableHeader);
				}
			}
		}
		else if (firstElement(location).nodeName == 'TH')
		{
			addClass(location, 'collapsed');
			location.onclick = function () { hideLocations(this) };
		}
	}
	
	// If we found a tableheader matching our previously selected zone,
	// then simulate an onclick on it.
	if (tableHeader)
		hideLocations(tableHeader);
	
	// Mappunten voorzien van juiste tooltips en events toekennen
	var mapPoints = getElementsByClassName($('map'), 'a' , 'location');
	
	for (var y = 0; y < mapPoints.length; y++)
	{
		var point = mapPoints[y];
	
		var zoneName = point.innerHTML;
		var dd = nextElement(point.parentNode);
		dd.innerHTML = '<strong>' + zoneName + '</strong> - ' + dd.innerHTML;
		
		// Functies activeren bij muisgebruik
		point.onclick = function () { selectZoneRow(this) };
		point.onmouseover = zoneOver;
		point.onmouseout = zoneOut;
		// Functies activeren bij toetsgebruik
		point.onfocus = zoneOver;
		point.onblur = zoneOut;
	}
}

/**
 * Hide locations functionality
 *
 * Hides the location-rows to start clean.
 *  
 */
function hideLocations (obj)
{
	// Set the rest of the table
	var locations = $('selection-location').getElementsByTagName('tr');
	
	for (var i = 0; i < locations.length; i++)
	{		
		var location = locations[i];
		
		if (firstElement(location).nodeName == 'TD')
		{
			location.style.display = 'none';
		}
		else if (firstElement(location).nodeName == 'TH')
		{
			removeClass(location, 'uncollapsed');
			addClass(location, 'collapsed');
		}			
	}
	
	// Set CSS class for clicked header
	removeClass(obj, 'collapsed');
	addClass(obj, 'uncollapsed');
	
	// Find rows to toggle	
	var zoneRows = new Array();
	var row = nextElement(obj);	
	
	// MSIE has issues
	if (row)
	{
		while (firstElement(row) && firstElement(row).nodeName == 'TD')
		{
			zoneRows.push(row);
			
			if (nextElement(row))
				row = nextElement(row);
			else
				break;
		}
	}
	
	toggle(zoneRows);
}



/**
 * Select zone functionality
 *
 * Selects a zone (and hides the other available zones 
 * on the Utopia map corresponding to the selected row. 
 * 
 * When the row is selected, it's deselected and all 
 * the zone's are displayed *  
 *  
 */
function selectZone (obj)
{
	var tableBody = obj.parentNode;
	var rows = $('selection-location').getElementsByTagName('tr');
	
	var radio = obj.getElementsByTagName('input')[0];
	var zones = getElementsByClassName($('map'), '*', 'location');
	var value = obj.getElementsByTagName('input')[0].value;
	
	
	// Wanneer de rij al geselecteerd is deze uitschakelen en alle zones tonen	
	if (hasClass(obj, 'selected')){
		removeClass(obj, 'selected')
		radio.checked = '';
		preferences.AccommodationZone = null;
		preferences.AccommodationZoneDescription = null; 
		
		for	(var i = 0; i < zones.length; i++){
			removeClass(zones[i], 'clicked');
		}
	}
	else{
		
		// Reeds geselecteerde rijen deselecteren
		for	(var i = 0; i < rows.length; i++){
			var row = rows[i];
			removeClass(row,'selected');
		}	
		
		// Gewenste rij selecteren & radiobutton vinken
		addClass(obj,'selected');
		var radio = obj.getElementsByTagName('input')[0];
		radio.checked = 'checked';
		preferences.AccommodationZone = value;
				
		// Doorloop de zones, toon relevante zone en verberg niet-relevante
		for (var i = 0; i < zones.length; i++){
			
			if (zones[i].id == value){
				addClass(zones[i], 'clicked');
				preferences.AccommodationZoneDescription = nextElement(zones[i].parentNode).lastChild.nodeValue;
			}
			else{
				removeClass(zones[i], 'clicked');
			}
		}
	}
}

/**
 * Select row  functionality
 *
 * Selects a row corresponding to the selected zone 
 * on the Utopia map. 
 *  
 */
function selectZoneRow(obj)
{
	var fields = $('selection-location').getElementsByTagName('input');
	var theGrandDaddy = '';
	
	var selectedZone = getElementsByClassName($('map'), 'a', 'clicked');
	if(selectedZone.length != 0){
		removeClass(selectedZone[0], 'clicked');
	}
	addClass(obj, 'clicked');
	
	// Rijen doorlopen, relevante rij selecteren en niet-relevante rijen deselecteren
	for( var i = 0; i < fields.length ; i++){
		var grandDaddy = fields[i].parentNode.parentNode;
		
		if (fields[i].value == obj.id){
			fields[i].checked = 'checked';
			addClass(grandDaddy, 'selected');
			preferences.AccommodationZone = obj.id;
			preferences.AccommodationZoneDescription = nextElement(obj.parentNode).lastChild.nodeValue;
			theGrandDaddy = grandDaddy;
		}
		else{
			removeClass(grandDaddy, 'selected');
			
		}
		
		grandDaddy.style.display = 'none';
	}
	
	// TH opsporen
	var zoneRows = new Array();
	var row = previousElement(theGrandDaddy);
	while(firstElement(row).nodeName != 'TH'){
		if(previousElement(row)){
			row = previousElement(row);
		}
		else{
			break;
		}
	}
	
	// Zones van TH vullen
	testRow = nextElement(row)
	var zoneRows = new Array();	
	
	while (firstElement(testRow).nodeName == 'TD'){
		zoneRows.push(testRow);
  		if (nextElement(testRow)){
		  testRow = nextElement(testRow);
		}
		else{
			break;
		}
	}
	toggle(zoneRows);
}

/**
 * Show map tooltip functionality
 *
 * Puts a tooltip in sight for viewing, with 
 * information about the selected zone. 
 *  
 */
var tooltip;
function zoneOver(){
	// Offset van de tooltip
	var offsetX= 15;
	var offsetY= 15;
	
	// Bepalen DD
	var objid = nextElement(this.parentNode);
	
	// Tooltip aanmaken zodat deze bereikbaar is voor de andere functies
	tooltip = objid;
	
	// Dimensies ophalen van de kaart
	var mapWidth  = objid.parentNode.offsetWidth;
	var mapHeight = objid.parentNode.offsetHeight;
	
	// Dimensies ophalen van tooltip
	var toopTipWidth = this.offsetWidth;
	var toopTipHeight = this.offsetHeight;
	
	// Bepalen coördinaten tooltip
	var newX = this.offsetLeft + offsetX;
	var newY = this.offsetTop + offsetY;
	
	// Controleren of tooltip op kaart past qua breedte
	if ((newX + toopTipWidth) > mapWidth) {
		objid.style.left = newX-toopTipWidth-24 + 'px';
	} else {
		objid.style.left = newX + 'px';
	};
	
	// Controleren of tooltip op kaart past qua hoogte
	if ((newY + toopTipHeight) > mapHeight) {
		objid.style.top = newY-toopTipHeight-14 + 'px';
	} else {
			objid.style.top = newY + 'px';
	}
}

/**
 * Hide map tooltip functionality
 *
 * Puts the current tooltip out of sight, but 
 * keeps it available for screenreaders, etc.
 *  
 */
function zoneOut(){
	// Tooltip uit zicht plaatsen, maar wel beschikbaar voor screenreaders!
	tooltip.style.left = '-9999px';
}

// Validate step two
function validateStepTwo ()
{
	// Check if required data was entered
	
	// Save data
	session.store('preferences', preferences);

	// Load next step
	loadNextStep();	
}
/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * $Id: step3.js 125 2006-06-17 21:18:44Z jmulder-svn $
 */

// Main data
var primaryPerson = null;
var persons = new Array;

// Cache templates
var tplPrimaryPerson = null;
var tplPrimaryPersonForm = null;
var tplOtherPerson = null;
var tplOtherPersonForm = null;

// Hack
var currentPersonId = null;

// Initialize
function initializeStepThree ()
{
	// Display current criteria
	displaySettings();
	
	// Ron?
	// Ja?
	addFormFieldValidation();
	
	// Initial mode is adding a primary person
	setButton('add', 'primary');
	
	// Initialize from session?
	if (session.data.primaryPerson)
	{
		primaryPerson = session.data.primaryPerson;
		
		if (session.data.persons)
			persons = session.data.persons;
			
		// Load overview
		displayOverview();
		
		// Refresh current persons lists
		displayPersonsList();
	}
	else
	{
		// Clear just in case
		primaryPerson = null;
		persons = new Array;
	}
}

// Add person to the list
function addPerson (person)
{
	if (!primaryPerson)
	{
		// If no persons exist, consider this the primary booker
		primaryPerson = person;
	}
	else
	{
		// Set ID's only for regular persons
		person.id = persons.length;

		// Else it's a regular person
		persons.push(person);
	}
	
	// Save person
	selectedPerson = person;
	
	// Load overview
	displayOverview();
	
	// Refresh current persons lists
	displayPersonsList();
}

// Save person after editing
function savePerson (person)
{
	if (person)
	{		
		// Check whether we're editing a primary		
		if (person.isPrimary)
			primaryPerson = person;
		else
			persons[person.id] = person;
		
		// Save selected person
		selectedPerson = person;
		
		// Refresh overview
		displayOverview();
		
		// Refresh lists
		displayPersonsList();

		// Display blank form
		displayBlankForm();		
	}
}


function getPerson (type)
{
	var person = new Person();
	
	// Get person information
	if (type == 'primary')
	{
		// Consider this our primary booker
		person.street = $('street').value;
		person.streetNumber = $('streetnumber').value;
		person.postalCode = $('postal-code').value;
		person.town = $('town').value;
		person.email = $('email').value;
		person.telephone = $('telephone').value;
		
		person.isPrimary = true;
	}
	
	// Get special data
	person.aanhef = ($('aanhef-mevr').checked) ? $('aanhef-mevr').value : $('aanhef-heer').value;
	
	// Get all other data
	person.surname = $('surname').value;
	person.surnamePre = $('surname-pre').value;
	person.initials = $('initials').value;
	
	person.dobDay = $('dob-day').value;
	person.dobMonth = $('dob-month').value;
	person.dobYear = $('dob-year').value;

	return person;
}

// Build list of persons
function displayOverview ()
{
	if (primaryPerson)
	{
		// Load main overview template
		if (!tplPrimaryPersonForm)
		{
			getTemplate('persons_overview', insertOverviewTpl);
		}		
		// Cache if the primary person was added
		else if (!tplPrimaryPerson)
		{
			getTemplate('persons_overview_primary', cachePrimaryPersonTpl);
		}
		// Only cache if a person was added besides the primary booker
		else if (primaryPerson && !tplOtherPerson)
		{
			getTemplate('persons_overview_others', cacheOtherPersonTpl);
		}
		else
		{
			addFormFieldValidation();
			
			// ----------------
			// Build overview list
			// ----------------
			
			// Remove all childs
			var table = $('persons-data');
			
			if (table)
			{
				var tbody = table.getElementsByTagName('tbody')[0];
				tbody = removeChilds(tbody);
				
				// Insert primary booker
				tbody.innerHTML = tplPrimaryPerson;
				
				// Insert other persons
				for (var i = 0; i < persons.length; i++)
				{
					var person = persons[i];
					tbody.innerHTML = tbody.innerHTML + tplOtherPerson;
				}
				
				// TODO: Combine this in a single loop
				// ------------------
				// Display primary person's data
				displayPrimaryPerson();
				
				// Display other people's date
				displayOtherPersons();
				
				// Open and close respective information
				toggleOverview();
			}
			
			// Display effects
			executeFx();
			
			// Display message
			var message = '';
			var secondMessage = '';
			
			// Check if we reached the maximum number of persons
			var totalPersons = (primaryPerson) ? persons.length + 1 : persons.length;
			
			if (primaryPerson && !persons.length)
			{
				// If we're adding the first primary person
				message = '<strong>Hoofdboeker toegevoegd.</strong>';
				secondMessage = ' Indien u met meerdere personen komt, kunt u deze nu toevoegen.';
			}
			else if ($('submit-person').value.indexOf('edit') != -1)
			{
				// If we just edited
				message = '<strong>Persoon gewijzigd.</strong>';
				secondMessage = ' U kunt nog een persoon toevoegen of wijzigen.';
			}			
			else
			{
				// In all other cases, we're probably adding a person
				message = '<strong>Persoon toegevoegd.</strong>';
				secondMessage = '  U kunt nog een persoon toevoegen.';
			}
			
			if (totalPersons == session.data.preferences.AccommodationSizeNumber)
			{
				// Display message
				//displayMessage($('personal-data-fields'), 'success-summary', 'U heeft het maximale aantal personen voor deze accommodatie ingevoerd. Ga verder of wijzig al ingevoerde personen.');
				message += '<br /><br />U heeft het maximale aantal personen voor deze accommodatie ingevoerd. Ga verder of wijzig al ingevoerde personen.';
		
				// Hide form
				toggle($('personal-data-fields'));
				toggle($('submit'));
			}
			else if (secondMessage.length)
			{
				message += secondMessage;
			}
		
			var ele = $('personal-data-fields');
			displayMessage(ele, 'success-summary', message, true);

			// Refresh form
			var formFields = $('personal-data-form').getElementsByTagName('input');
			
			for (var i = 0; i < formFields.length; i++)
			{				
				if(formFields[i].id != 'submit-person')
					formFields[i].value = '';				
			}
			
			// Set button mode
			setButton('add', 'default');			
		}		
	}	
}

function toggleOverview ()
{
    // Toggle primary person's data, except for the name
    var rows = $('persons-data').getElementsByTagName('tr');
    
    var toggledPersons = 0;
    for (var i = 0; i < rows.length; i++)
    {
        var row = rows[i];
        
        // Toggle if row doesn't contain a name
        if (!hasClass(row, 'person-name'))
        {
            toggle(row);
        }
        else
        {
            if (toggledPersons >= persons.length)
                break;
            else						
                toggledPersons++;					
        }
    }
}

function displayPrimaryPerson ()
{
	// Set primary booker details
	$('primary-person-name').innerHTML = '<strong>' + primaryPerson.getFullname() + '</strong>';
	$('primary-person-address').innerHTML = primaryPerson.street + ' ' + primaryPerson.streetNumber + '<br />' +
											primaryPerson.postalCode + ' ' + primaryPerson.town;
											
	$('primary-person-contact').innerHTML = primaryPerson.email + '<br />' + primaryPerson.telephone;
	$('primary-person-dob').innerHTML = primaryPerson.dobDay + ' ' + primaryPerson.dobMonth + ' ' + primaryPerson.dobYear;
	
	// Assign edit handler
	var editLink = getElementsByClassName($('primary-person-edit'), 'a', 'person-edit')[0];			
	assignEditPersonHandler(editLink, primaryPerson);
}

function displayOtherPersons ()
{
	// Set other booker details
	var rows = $('persons-data').getElementsByTagName('tr');
	
	var personId = 0;	
	for (var i = 4; i < rows.length; i++)
	{
		var row = rows[i];
		var person = persons[personId];
		
		if (hasClass(row, 'person-name'))
		{
			// Set name
			var cols = getElementsByClassName(row, 'th', 'person-name');
			cols[0].innerHTML = '<strong>' + person.getFullname() + '<strong>';
			
			// Set edit link
			var editLink = getElementsByClassName(row, 'a', 'person-edit')[0];			
			assignEditPersonHandler(editLink, person);
		}
		else
		{
			// Set date of birth
			var cols = getElementsByClassName(row, 'td', 'person-dob');
			cols[0].innerHTML = person.dobDay + ' ' + person.dobMonth + ' ' + person.dobYear;

			personId++;
		}
	}
}

// Assign editing behaviour
function assignEditPersonHandler (obj, person)
{
	if (obj)
	{
		// Store person reference
		if (person.isPrimary)
			obj.setAttribute('id', 'person-edit-primary');
		else
			obj.setAttribute('id', 'person-edit-' + person.id);
	
		// Assign event handler
		obj.onclick = function (oEvent) 
		{
			var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
			preventDefaultEventBehavior(oEvent);
			
			// Get person reference
			var idArray = this.id.split('-');
			var id = idArray[idArray.length - 1];
			
			var person = null;
			
			// Check which person
			if (id == 'primary')
				person = primaryPerson;
			else
				person = persons[id];
			
			// Go ahead if it matches a person
			if (person)
				editPerson(person);
		};
	}
}

// Load edit form
function editPerson (person)
{
	// Restore information in form
	var container = $('personal-data-fields');
	
	// Hack
	currentPersonId = person.id;
	
	// Toggle previously inserted message
	if ($('message'))
		$('message').style.display = 'none';
	
	if (person.isPrimary)
	{
		// Set template from cache
		container.parentNode.replaceChild(tplPrimaryPersonForm, container);
		
		// Set data
		$('street').value = person.street;
		$('streetnumber').value = person.streetNumber;
		$('postal-code').value = person.postalCode;
		$('town').value = person.town;
		$('email').value = person.email;
		$('telephone').value = person.telephone;
		
		// Set button
		setButton('edit', 'primary');		
	}
	else
	{
		// Set template from cache
		container.parentNode.replaceChild(tplOtherPersonForm, container);
		
		// Set button
		setButton('edit', 'default');		
	}
	
	// Set special data
	if (person.aanhef == 'mevrouw')
	{
		$('aanhef-mevr').checked = true;
		$('aanhef-heer').checked = false;
	}
	else
	{
		$('aanhef-mevr').checked = false;
		$('aanhef-heer').checked = true;
	}
	
	// Set dob month
	var dobMonthSelect = $('dob-month').options;
	for (var i = 0; i < dobMonthSelect.length; i++)
	{
		var selectOption = dobMonthSelect[i];
		if (selectOption.value == person.dobMonth)
		{
			selectOption.selected = true;
			break;
		}
	}
	
	// Set shared data
	$('surname').value = person.surname;
	$('surname-pre').value = person.surnamePre;
	$('initials').value = person.initials;
	
	$('dob-day').value = person.dobDay;
	$('dob-year').value = person.dobYear;
	
	// Always reset display of submit buttons and fields
	$('personal-data-fields').style.display = '';
	$('submit').style.display = '';
}

// Display persons in a list
function displayPersonsList ()
{
	if ($('persons'))
	{
		// Get existing listed items
		var list = $('persons').getElementsByTagName('ul')[0];
		var listItems = list.getElementsByTagName('li');
		
		// Remove all existing list items
		list = removeChilds(list);
		
		// Insert primary first
		var li = document.createElement('li');			
		li.appendChild(document.createTextNode(primaryPerson.getFullname()));			
		list.appendChild(li);		
		
		// Insert remaining persons
		for (var i = 0; i < persons.length; i++)
		{
			var person = persons[i];
			
			// Create and append child
			var li = document.createElement('li');			
			li.appendChild(document.createTextNode(person.getFullname()));				
			list.appendChild(li);
		}	
	}
}

// Display add button
function setButton (mode, value)
{
	var button = $('submit-person');
	
	if (button)
	{
		// ------------------
		// Add person
		// ------------------	
		if (mode == 'add')
		{
			// Set image and value
			button.setAttribute('src', '/images/add_person.gif');
			button.setAttribute('value', 'add-' + value);
			
			// Assign behaviour
			button.onclick = function (oEvent)
			{		
				var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
				preventDefaultEventBehavior(oEvent);
				
				// Get type and person
				var type = this.value.split('-');
				var typeStr = type[type.length - 1];
				
				var person = getPerson(typeStr);
				
				// Validate
				if(validatePerson())
				{
					addPerson(person);
				}
			};
	
			// Display cancel link
			//displayCancel();			
		}
		
		// ------------------
		// Edit person
		// ------------------	
		else if (mode == 'edit')
		{
			// Set image and value
			button.setAttribute('src', '/images/save_person.gif');
			button.setAttribute('value', 'edit-' + value);
			
			// Assign behaviour
			button.onclick = function (oEvent)
			{
				var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
				preventDefaultEventBehavior(oEvent);
				
				// Get type and person
				var type = this.value.split('-');
				var typeStr = type[type.length - 1];
				
				var person = getPerson(typeStr);
				
				// Save current person id
				person.id = currentPersonId;
				
				// Validate
				if(validatePerson())
				{
					savePerson(person);
				}
			};
	
			// Display cancel link
			//displayCancel();			
		}
	}
}

// Display cancel link
function displayCancel ()
{
	var button = $('submit-person');
	
	if (button)
	{
		// Define message
		var message = '';
		
		// Parent
		var parent = button.parentNode;
		
		// Create link
		var cancelLink = document.createElement('a');
		addClass(cancelLink, 'cancel');
		
		// Cancel behaviour
		if (button.value.indexOf('edit') != -1)
		{
			// Cancel while editing...	
			message = 'annuleer wijzigen';
			
			cancelLink.onclick = function (oEvent)
			{
				var oEvent = (typeof oEvent != 'undefined') ? oEvent : event;
				preventDefaultEventBehavior(oEvent);
				
				// Toggle form
				toggle($('personal-data-fields'));
				
				// Display add button
				setButton('add', 'default');
				
				//displayCancel();
			};		
		}
		else if (button.value.indexOf('add') != -1)
		{
			// Cancel when adding...
			message = 'toon het overzicht van personen';
		}
		
		// Remove and append
		parent = removeChilds(parent);
		
		cancelLink.appendChild(document.createTextNode(message));
		
		parent.appendChild(button);
		parent.innerHTML = parent.innerHTML + 'of ';		
		parent.appendChild(cancelLink);
	}
}

// Validate step three
function validateStepThree ()
{
	var ele = $('personal-data-fields');
	
	// Check if required data was entered
	if (!primaryPerson)
	{
		displayMessage(ele, 'error-summary', '<strong>Geen hoofdboeker.</strong> U heeft geen hoofdboeker ingevuld. Een hoofdboeker is verplicht en dient alsnog ingevuld te worden', true);
	}
	else
	{	
		// Save information
		session.store('primaryPerson', primaryPerson);
		session.store('persons', persons);
		
		// Before loading, unload all cached templates
		tplPrimaryPerson = null;
		tplPrimaryPersonForm = null;
		tplOtherPerson = null;
		tplOtherPersonForm = null;
	
		// Load next step
		loadNextStep();
	}
}


// Insert overview template
function insertOverviewTpl (responseText, responseXML)
{
	var form = $('personal-data-form');
	var primaryPersonForm = $('personal-data-fields');
	
	// Cache current forms (ugly hack)
	tplPrimaryPersonForm = primaryPersonForm;
	
	// Remove current form
	form.removeChild(primaryPersonForm);	
					   
	if(form)
		form.innerHTML = responseText + form.innerHTML;

	// Display overview
	displayOverview();
}

// Cache primary person template
function cachePrimaryPersonTpl (responseText, responseXML)
{
	// Cache template
	tplPrimaryPerson = responseText;
	
	// Display overview
	displayOverview();
}

// Cache persons template
function cacheOtherPersonTpl (responseText, responseXML)
{
	// Cache template
	tplOtherPerson = responseText;
	
	// This would be the right time to cache their form too
	tplOtherPersonForm = $('personal-data-fields');
	
	// Display overview
	displayOverview();
}


// Person object
function Person ()
{
	this.id = 0;

	this.aanhef = null;
	this.surname = null;
	this.surnamePre = null;
	this.initials = null;
	this.street = null;
	this.streetNumber = null;
	this.postalCode = null;
	this.town = null;
	this.email = null;
	this.telephone = null;
	
	this.dobDay = null;
	this.dobMonth = null;
	this.dobYear = null;
	
	this.isPrimary = false;
}

Person.prototype.getFullname = PersonGetFullName;

// Return a person's full name
function PersonGetFullName ()
{
	return this.initials + ' ' + this.surnamePre + ' ' + this.surname;	
}


/**
 * Validate Person
 *
 * Validate personal data / required fields.
 *  
 */

function validatePerson(){
	
	var form = document.getElementById("personal-data-fields"); 
	var firstFormElement = nextElement(form.firstChild);
	
	if(firstFormElement.nodeName == 'DIV'){
		form.removeChild(firstFormElement);
	}
	
	var requiredFields = getElementsByClassName($('personal-data-form'), 'input', 'required');
	var emptyFields = new Array();
	
	for(var i = 0; i < requiredFields.length; i++){
		
		var requiredField = requiredFields[i];
		
		if(requiredField.value == ''){
			emptyFields.push(requiredField);
			addClass(requiredField, 'error-field');
		}
	}
	
	if(emptyFields.length != 0 || getElementsByClassName($('personal-data-form'), 'input', 'error-field').length != 0)
	{
		var message = '';
			
		// Set message
		if (emptyFields.length > 0)
			message = '<strong>Niet alle verplichte velden zijn ingevuld</strong>, vul alsnog alle verplichte velden in.';
		else
			message = '<strong>Niet alle ingevulde waarden zijn correct</strong>, vul alleen correcte waarden in.';
			
		// Find obj to insert message after
		var ele = $('personal-data-fields');
		
		// Display message
		displayMessage(ele, 'error-summary', message);
		
		return false;
	}
	else{
		return true;
	}
}

/**
 * Display message
 *
 * @param string obj						Object to insert message before
 * @param string type						Class name for type
 * @param string message					Message
 * @param boolean forceRemoveAndCreate		Force to remove the element and create a new one
 */
function displayMessage (obj, type, message, forceRemoveAndCreate)
{
	// Check if message element exists
	var msg = $('message');
	
	forceRemoveAndCreate = (typeof forceRemoveAndCreate == 'undefined') ? false : true;
	
	if (msg && !forceRemoveAndCreate)
	{
		var fxOut = null;
		var fxEle = null;
		if (msg.className != type)
		{
			var fxFunc = function () {
				// Display new one
				fxEle = new fx.Combo(msg, {height : true, opacity : true, duration : 100 });
				fxEle.hide();
				
				// Add class
				msg.className = type;
			
				// Set message
				firstElement(msg).innerHTML = message;
				
				// Force display
				msg.style.display = 'block';
				
				fxEle.toggle();
			};
				
			// Hide old one
			fxOut = new fx.Combo(msg, {height : true, opacity : true, duration : 200, onComplete : fxFunc});
			fxOut.toggle();
		}
		else
		{		
			// Add class
			msg.className = type;
		
			// Set message
			firstElement(msg).innerHTML = message;
			
			// Force display
			msg.style.display = 'block';
		}
	}
	else
	{
		// Remove element?
		if (msg && forceRemoveAndCreate)
		{
			var removeEle = $('message');
			removeEle.parentNode.removeChild(removeEle);
		}
		
		// Create
		var ele = document.createElement('div');
		
		var fxEle = new fx.Combo(ele, {height : true, opacity : true, duration : 200 });
		fxEle.hide();
		
		// Add class and id
		ele.id = 'message';
		ele.className = type;
		ele.innerHTML = '<p></p>';
		
		// Insert after obj
		obj.parentNode.insertBefore(ele, obj);
		
		// Set message recursively
		displayMessage(obj, type, message);
		
		fxEle.toggle();
	}
}

// Hmprf?
function displayBlankForm(){
	// Display blank add form
	var container = $('personal-data-fields');
	container.parentNode.replaceChild(tplOtherPersonForm, container);

}
/* ------------------------ 
 * Javascript Information	
 * ------------------------ 
 * 
 * $Id:
 */
 
// Initialize
function initializeStepFive (){

	// Display current booking criteria
	displayBooking();
	
}

/**
 * Display booking functionality
 *
 * Displays all the data for the summary of the 
 * booking made by the user / customer    
 *  
 */
function displayBooking(){
	// Some vars who should be available in the database in the full webapp version
	var administrationPrice = '51,00';
	var touristPrice = '19,00';
	
	var tempMonthYear = preferences.Month.split('-');
	$("from-date").innerHTML = preferences.Day + '-' + tempMonthYear[0]+ '-20' +tempMonthYear[1];
	$("till-date").innerHTML = parseInt(preferences.Day) + parseInt(preferences.DuranceStay) + '-' + tempMonthYear[0] + '-20' + tempMonthYear[1];

	$("nights").innerHTML = preferences.DuranceStay;
	$("accommodation-type").innerHTML = preferences.AccommodationTypeFull;
	$("accommodation-location").innerHTML = preferences.AccommodationZoneDescription.replace('- ', '');
	var accoPrice = preferences.AccommodationPriceFrom + ',00';
	$("accommodation-price").innerHTML = '&euro; ' + accoPrice;
	$("administration-price").innerHTML = '&euro; ' + administrationPrice;
	$("tourist-price").innerHTML = '&euro; ' + touristPrice;
	
	var accoPrice = preferences.AccommodationPriceFrom + ',00';
	var totalPrice = parseInt(accoPrice) + parseInt(administrationPrice) + parseInt(touristPrice);
	$("total-price").innerHTML = '&euro; ' + totalPrice + ',00';
	
	$("main-booker").innerHTML = session.data.primaryPerson['initials'] + ' ' + session.data.primaryPerson['surnamePre'] + ' ' + session.data.primaryPerson['surname'];
	
	if(session.data.persons.length != 0){
		var persons = session.data.persons;
		var secondaryBookers = '<ul>';
				
		for(var i = 0; i < persons.length; i++){
			var person = persons[i];
			secondaryBookers = secondaryBookers + '<li>' + person['initials'] + ' ' + person['surnamePre'] + ' ' + person['surname'] + '</li>';
		}
		
		secondaryBookers = secondaryBookers + '</ul>';
		
		$("secondary-booker").innerHTML = secondaryBookers;
		
	}

}
