jQuery.noConflict();

var WS={version:'1.6.3',browser:{IE:/msie/i.test(navigator.userAgent),IE6:/msie 6/i.test(navigator.userAgent),IE7:/msie 7/i.test(navigator.userAgent),Gecko:/gecko/i.test(navigator.userAgent),Webkit:/webkit/i.test(navigator.userAgent)},$:function(el){return(typeof el=='string')?document.getElementById(el):el;},hide:function(el){el=$(el);el.style.display='none';return el;},show:function(el){el=$(el);el.style.display='';return el;},toggle:function(el){el=$(el);el.style.display==''?this.hide(el):this.show(el);},addClass:function(el,cls){el=$(el);if(!this.hasClass(el,cls)){el.className+=(' '+cls);}},removeClass:function(el,cls){el=$(el);if(this.hasClass(el,cls)){var regex=new RegExp('(\\s|^)'+cls+'(\\s|$)');el.className=el.className.replace(regex,' ');}},toggleClass:function(el,cls){if(this.hasClass(el,cls)){this.removeClass(el,cls);}else{this.addClass(el,cls);}},hasClass:function(el,cls,greedy){el=$(el);if(!el.className){return false;}else if(greedy){var regex=new RegExp(cls);return regex.test(el.className);}else{return el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));}},getOpacity:function(el){el=$(el);if(WS.browser.IE){return el.style.filter?(parseFloat(el.style.filter.replace('alpha(opacity=',''))/100):1.0;}return el.style.opacity||1.0;},setOpacity:function(el,op){el=$(el);if(WS.browser.IE){var ieOp=(op*100);if(ieOp<100){el.style.filter='alpha(opacity='+ieOp+')';}else{el.style.filter='';}}else{el.style.opacity=op;}},setText:function(el,text){el=$(el);el.innerHTML=text;}};if(typeof $=='undefined'){var $=WS.$;}else{var get=WS.$;}if(!window.console){window.console={log:function(){}};}
WS.DOM={ready:function(fn){if(document.addEventListener){document.addEventListener('DOMContentLoaded',function(){fn.call();},false);}else if(document.all&&!window.opera){document.write("<s"+'cript id="dom-loaded" defer="defer" src="/'+'/:"></s'+"cript>");$('dom-loaded').onreadystatechange=function(){if(this.readyState=='complete'){fn.call();}};}},getElementsByClass:function(searchClass,node,tag){var classElements=[];if(node==null){node=document;}if(tag==null){tag='*';}var els=node.getElementsByTagName(tag);var elsLen=els.length;var pattern=new RegExp("(^|\\s)"+searchClass+"(\\s|$)");for(i=0,j=0;i<elsLen;i++){if(pattern.test(els[i].className)){classElements[j]=els[i];j++;}}return classElements;},getParent:function(el,offset){offset=offset||1;var parent=$(el).parentNode;for(var i=1;i<offset;i++){parent=parent.parentNode;}return parent;},getChild:function(el,depth){var child=$(el).childNodes[depth-1];while(child.nodeType!=1){child=child.nextSibling;}return child;},getChildren:function(el){var arr=[];var children=$(el).childNodes;for(var i=0;i<children.length;i++){if(children[i].nodeType==1){arr.push(children[i]);}}return arr;},next:function(el){var next=el.nextSibling;while(next.nodeType!=1){next=next.nextSibling;}return next;},insertAfter:function(node,referenceNode){referenceNode.parentNode.insertBefore(node,referenceNode.nextSibling);}};
WS.Util={createToggle:function(id){var t=$(id+'-toggle');var c=$(id+'-container');WS.hide(c);WS.Event.addEvent(t,'click',function(e){WS.Event.stopEvent(e);WS.toggle(c);});},fixPngBackground:function(img,sizingMethod){sizingMethod=sizingMethod||'scale';if(WS.browser.IE6){img=$(img);var src=img.currentStyle.backgroundImage.replace(/url\("(.*)"\)/,'$1');img.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+src+'\', sizingMethod=\''+sizingMethod+'\')';img.style.background='none';}},parseJSON:function(json){try{if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)){var j=eval('('+json+')');return j;}}catch(e){}throw new SyntaxError('Can\'t parse JSON string');},number_format:function(a,b,c,d){a=Math.round(a*Math.pow(10,b))/Math.pow(10,b);e=a+'';f=e.split('.');if(!f[0]){f[0]='0';}if(!f[1]){f[1]='';}if(f[1].length<b){g=f[1];for(i=f[1].length+1;i<=b;i++){g+='0';}f[1]=g;}if(d!=''&&f[0].length>3){h=f[0];f[0]='';for(j=3;j<h.length;j+=3){i=h.slice(h.length-j,h.length-j+3);f[0]=d+i+f[0]+'';}j=h.substr(0,(h.length%3===0)?3:(h.length%3));f[0]=j+f[0];}c=(b<=0)?'':c;return f[0]+c+f[1];},collectionToArray:function(c){var a=[];for(var i=0;i<c.length;i++){a.push(c.item(i));}return a;},secondsToMinutes:function(sec){var minutes=Math.floor(sec/60);var seconds=sec%60;if(seconds<10){seconds='0'+seconds;}return minutes+':'+seconds;}};
WS.Event={addEvent:function(el,type,listener,useCapture){el=$(el);useCapture=useCapture||false;if(WS.browser.Gecko){el.addEventListener(type,listener,useCapture);}else if(WS.browser.IE){var r=el.attachEvent('on'+type,function(){listener.call(el,window.event);});return r;}},removeEvent:function(el,type,listener,useCapture){useCapture=useCapture||false;if(WS.browser.Gecko){el.removeEventListener(type,listener,useCapture);}else if(WS.browser.IE){var r=el.detachEvent('on'+type,listener);}},stopEvent:function(e){e=e||window.event;if(WS.browser.Gecko){e.preventDefault();}else{e.returnValue=false;}},getTarget:function(e){if(e.target){return e.target;}else if(e.srcElement){return e.srcElement;}else{return false;}}};
WS.Ajax={getXMLHttpObject:function(){return window.ActiveXObject?new ActiveXObject('Microsoft.XMLHTTP'):new XMLHttpRequest();},stateChanged:function(xhr,fn){if(xhr.readyState==4){fn(xhr.responseText);}},request:function(url,fn){var self=this;var post=arguments[2]||'';var xhr=this.getXMLHttpObject();if(xhr){xhr.onreadystatechange=function(){self.stateChanged(xhr,fn);};if(post){xhr.open('POST',url,true);xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');xhr.setRequestHeader('Content-length',post.length);xhr.setRequestHeader('Connection','close');xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');}else{xhr.open('GET',url,true);}xhr.send(post);}}};
WS.Validation=function(form,options){var form=$(form),formElements=[],errorClass='wsv-error';var validations={required:{errorMessage:'Dit veld is verplicht',regex:/\S+/},email:{errorMessage:'U dient een geldig e-mailadres in te vullen',regex:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/},zip:{errorMessage:'U dient een geldige postcode in te vullen (1234AB)',regex:/^[0-9]{4}[\ ]?[a-zA-Z]{2}$/},numeric:{errorMessage:'Dit veld mag alleen numerieke tekens bevatten',regex:/^[0-9]*$/},phone:{errorMessage:'U dient een geldig telefoonnummer in te vullen',regex:/^[0-9 +-]{10,16}$/}};return{initialize:function(){if(!form){return false;}if(typeof options!='undefined'){for(prop in options){this[prop]=options[prop];}}for(var i=0;i<form.elements.length;i++){if(WS.hasClass(form.elements[i],'wsv-',true)){formElements.push(form.elements[i]);}}if(WS.browser.Webkit){var fieldsets=form.getElementsByTagName('fieldset');for(var i=0;i<fieldsets.length;i++){if(WS.hasClass(fieldsets[i],'wsv-',true)){formElements.push(fieldsets[i]);}}}this.initEvents();},initEvents:function(){var self=this;form.onsubmit=function(){var valid=self.validateForm();if(typeof self.onFail=='function' && !valid){self.onFail();}return valid;};},enableElement:function(el){el=$(el);el.disabled=false;},disableElement:function(el){el=$(el);el.disabled=true;},addValidation:function(name,properties){if(!validations[name]){validations[name]=properties;}},validateElement:function(el){var valid=true;var vArr=el.className.match(/wsv-\w+/g);for(var i=0;i<vArr.length;i++){if(vArr[i]!=errorClass){if(el.nodeName=='INPUT'){if(el.type=='text'||el.type=='password'){if(vArr[i]=='wsv-required'||el.value!==''){valid=validations[vArr[i].split('wsv-')[1]].regex.test(el.value);}}else if(el.type=='checkbox'){valid=el.checked;}else if(el.type=='radio'){var nextElement=formElements[formElements.indexOf(el)+1];do{if(!el.checked){valid=false;}nextElement=formElements[formElements.indexOf(nextElement)+1];}while(nextElement.type=='radio'&&nextElement.name==el.name);}}else if(el.nodeName=='SELECT'){valid=el.value!=-1;}else if(el.nodeName=='TEXTAREA'){valid=el.value;}else if(el.nodeName=='FIELDSET'){valid=0;var inputs=el.getElementsByTagName('input');for(var i=0;i<inputs.length;i++){valid+=inputs[i].checked;}}}if(!valid){WS.addClass(el,errorClass);}else if(valid&&WS.hasClass(el,errorClass)){WS.removeClass(el,errorClass);}}return valid;},validateForm:function(){var submit=true;for(var i=0;i<formElements.length;i++){if(!this.validateElement(formElements[i])){submit=false;}}return submit;}};};
Function.prototype.bind=function(){var handler=this,args=[].slice.call(arguments,0),obj=args.shift();return function(){return handler.apply(obj,args.concat([].slice.call(arguments,0)));};};
if(!Array.forEach){Array.prototype.forEach=function(fun){var len=this.length>>>0;if(typeof fun!='function'){throw new TypeError();}var thisp=arguments[1];for(var i=0;i<len;i++){if(i in this){fun.call(thisp,this[i],i,this);}}};}
if(!Array.indexOf){Array.prototype.indexOf=function(obj){for(var i=0;i<this.length;i++){if(this[i]==obj){return i;}}return-1;};}
Array.prototype.first=function(){return this[0];};
Array.prototype.last=function(){return this[this.length-1];};

var YouTubePlayer=function(pId,options){if(typeof swfobject.embedSWF=='undefined'){throw'YouTubePlayer requires SWFObject 2.0 or higher to work!';}if(!/^[A-Za-z0-9\_]+$/.test(pId)){throw'The YouTube Player ID can only contain A-Z a-z 0-9 and _ (underscores). The ID being used: '+pId;}var self=this;this.pId=pId;this.player=false;this.state=-1;if(typeof options!='undefined'){for(prop in options){this[prop]=options[prop];}}this.playerReady=function(playerId){if(self.pId==playerId){self.player=document.getElementById(playerId);self.addEventListener('onStateChange',self.pId+'onStateChange');if(self.onReady){self.onReady(self.player);}if(self.videoId&&self.autoPlay){self.loadVideoById(self.videoId);}else if(self.videoId){self.cueVideoById(self.videoId);}if(self.muted){self.mute();}else{self.unMute();self.setVolume(100);}}};this.stateChange=function(state){self.state=state;if(state===0&&self.onEnd){self.onEnd(self.player);}else if(state===1&&self.onPlay){self.onPlay(self.player);}else if(state===2&&self.onPause){self.onPause(self.player);}else if(state===3&&self.onBuffering){self.onBuffering(self.player);}else if(state===5&&self.onCue){self.onCue(self.player);}};this.error=function(error){if(error===100&&self.onNotFoundError){self.onNotFoundError(self.player);}else if((error===101||error===150)&&self.onNoEmbedError){self.onNoEmbedError(self.player);}};var oldOnYouTubePlayerReady=window.onYouTubePlayerReady||false;if(typeof oldOnYouTubePlayerReady=='function'){window.onYouTubePlayerReady=function(playerId){oldOnYouTubePlayerReady(playerId);self.playerReady(playerId);};}else{window.onYouTubePlayerReady=this.playerReady;}window[this.pId+'onStateChange']=this.stateChange;window[this.pId+'onError']=this.error;swfobject.embedSWF('http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid='+pId,pId,(this.width||320),(this.height||240),'8',null,null,{allowScriptAccess:'always',bgcolor:'#000000',wmode:'transparent'},{id:pId});};YouTubePlayer.prototype={cueVideoById:function(videoId,startSeconds,suggestedQuality){this.player.cueVideoById(videoId,startSeconds,suggestedQuality);},loadVideoById:function(videoId,startSeconds,suggestedQuality){this.player.loadVideoById(videoId,startSeconds,suggestedQuality);},playVideo:function(){this.player.playVideo();},pauseVideo:function(){this.player.pauseVideo();},togglePlay:function(){this.getPlayerState()===1?this.pauseVideo():this.playVideo();},stopVideo:function(){this.player.stopVideo();},seekTo:function(seconds,allowSeekAhead){this.player.seekTo(seconds,allowSeekAhead);},clearVideo:function(){this.player.clearVideo();},mute:function(){this.player.mute();},unMute:function(){this.player.unMute();},isMuted:function(){return this.player.isMuted();},toggleMute:function(){this.isMuted()?this.unMute():this.mute();},setVolume:function(v){this.player.setVolume(v);},getVolume:function(){return this.player.getVolume();},setSize:function(width,height){this.player.setSize(width,height);},getVideoBytesLoaded:function(){return this.player.getVideoBytesLoaded();},getVideoBytesTotal:function(){return this.player.getVideoBytesTotal();},getVideoStartBytes:function(){return this.player.getVideoStartBytes();},getPlayerState:function(){return this.player.getPlayerState();},getCurrentTime:function(){return this.player.getCurrentTime();},getDuration:function(){return this.player.getDuration();},getVideoUrl:function(){return this.player.getVideoUrl();},getVideoEmbedCode:function(){return this.player.getVideoEmbedCode();},addEventListener:function(event,listener){this.player.addEventListener(event,listener);}};
var Tabs=function(id,selectedCls){var tabs,activeTab,tabContent,selectedCls=selectedCls||'selected';return{initialize:function(){if($(id)){tabs=$(id).getElementsByTagName('li');tabContent=WS.DOM.next($(id));}else{return;}this.initEvents();},initEvents:function(){for(var i=0;i<tabs.length;i++){var self=this;var tab=tabs[i];var tabLink=tab.getElementsByTagName('a')[0];tab.container=$(tabLink.href.split('#')[1]);if(WS.hasClass(tab,selectedCls)){activeTab=tab;}else{WS.hide(tab.container);}WS.Event.addEvent(tab,'click',function(e){WS.Event.stopEvent(e);self.showTabContent(this);});}},showTabContent:function(el){if(el==activeTab){return;}WS.hide(activeTab.container);WS.removeClass(activeTab,selectedCls);WS.show(el.container);WS.addClass(el,selectedCls);activeTab=el;}};};
var RowClick=function(){var tables,anchor;return{initialize:function(){tables=document.getElementsByTagName('table');this.initEvents();},initEvents:function(){for(var i=0;i<tables.length;i++){if(WS.hasClass(tables[i],'wsclick')){var rows=tables[i].rows;for(var j=0;j<rows.length;j++){if(rows[j].getElementsByTagName('a').length){var anchor=rows[j].getElementsByTagName('a')[0];rows[j].title=anchor.title;this.bindHREF(rows[j],anchor);}}}}},bindHREF:function(el,anchor){WS.Event.addEvent(el,'click',function(){if(/external/i.test(anchor.rel)) {window.open(anchor.href);}else{window.location.href=anchor.href;}});WS.Event.addEvent(anchor,'click',function(e){WS.Event.stopEvent(e);});}}}();WS.Event.addEvent(window,'load',function(){RowClick.initialize();});
var RowHover=function(){var tables,hoverCls;return{initialize:function(cls){hoverCls=cls||'hover';tables=document.getElementsByTagName('table');this.initEvents();},initEvents:function(){for(var i=0;i<tables.length;i++){if(WS.hasClass(tables[i],'wshover')){var rows=tables[i].rows;for(var j=0;j<rows.length;j++){if(rows[j].parentNode.nodeName=='TBODY'&&rows[j].getElementsByTagName('th').length<=1){WS.Event.addEvent(rows[j],'mouseover',function(){WS.addClass(this,hoverCls);});WS.Event.addEvent(rows[j],'mouseout',function(){WS.removeClass(this,hoverCls);});}}}}}}}();WS.Event.addEvent(window,'load',function(){RowHover.initialize();});
var QuantityField=function(id,options){this.minValue=0;this.maxValue=99;this.step=1;if(typeof options!='undefined'){for(prop in options){this[prop]=options[prop];}}if($(id)){this.input=$(id);}else{throw'Element with ID '+id+' does not exist!';}if($(id+'-increment')){this.incrBtn=$(id+'-increment');}if($(id+'-decrement')){this.decrBtn=$(id+'-decrement');}var self=this;WS.Event.addEvent(this.incrBtn,'click',function(e){WS.Event.stopEvent(e);self.increment();});WS.Event.addEvent(this.decrBtn,'click',function(e){WS.Event.stopEvent(e);self.decrement();});if(this.onUpdate){WS.Event.addEvent(this.incrBtn,'click',function(){self.onUpdate(self.input);});WS.Event.addEvent(this.decrBtn,'click',function(){self.onUpdate(self.input);});WS.Event.addEvent(this.input,'keyup',function(){self.onUpdate(self.input);});}};QuantityField.prototype={increment:function(){var intValue=parseInt(this.input.value);if((intValue+this.step)<=this.maxValue){this.input.value=intValue+this.step;}},decrement:function(){if((this.input.value-this.step)>=this.minValue){this.input.value-=this.step;}}};
var Menu=function(tId,teId){var toggler;var toggleEl;var active;var initEvents=function(){WS.Event.addEvent(toggler,'click',function(e){WS.Event.stopEvent(e);WS.show(toggleEl);WS.addClass(toggler,'active');active=true;});WS.Event.addEvent(document,'mousedown',function(e){if(active){var target=WS.Event.getTarget(e);while(target){if(target==toggleEl){return false;}target=target.parentNode;}WS.hide(toggleEl);WS.removeClass(toggler,'active');active=false;}});};var initialize=function(){try{toggler=$(tId);toggleEl=$(teId);}catch(e){throw'Element width ID \''+tId+'\' or \''+teId+'\' not found!';}active=false;WS.hide(toggleEl);initEvents();}();return{show:function(){WS.show(toggleEl);WS.addClass(toggler,'active');active=true;},hide:function(){WS.hide(toggleEl);WS.removeClass(toggler,'active');active=false;}};};
var Ticker=function(id,to){var interval;var element=$(id);return{start:function(){var self=this;this.countTo();interval=setInterval(function(){self.countTo();},1000);},countTo:function(){var now=new Date();if(now<to){var totalSecs=Math.floor((to-now)/1000);var totalHrs=Math.floor(totalSecs/3600);var days=Math.floor(totalHrs/24);var hrs=Math.floor(totalHrs%24);var mins=Math.floor(totalSecs/60%60);var secs=Math.floor(totalSecs%60);var s=this.zeroPad(days,3)+' '+this.zeroPad(hrs,2)+' '+this.zeroPad(mins,2)+' '+this.zeroPad(secs,2);element.innerHTML=s;}else{element.innerHTML='000 00 00 00';this.stop();}},zeroPad:function(number,count){var pad=count-(number+'').length;for(var i=0;i<pad;i++){number='0'+number;}return number;},stop:function(){clearInterval(interval);}}};
var Toggler=function(t,te,options){this.togglerId=t;this.toggleElId=te;this.options=options;this.toggler;this.toggleEl;this.visible;this.startVisible;this.parentOffset;this.followLink;this.onBeforeToggle;this.onAfterToggle;this.initialize();};Toggler.prototype={initialize:function(){try{this.toggler=$(this.togglerId);this.toggleEl=$(this.toggleElId);}catch(e){throw'Element with ID \''+this.togglerId+'\' or \''+this.toggleElId+'\' not found!';}this.startVisible=false;this.parentOffset=false;this.followLink=false;this.onBeforeToggle=null;this.onAfterToggle=null;if(typeof this.options!='undefined'){for(prop in this.options){this[prop]=this.options[prop];}}this.startVisible?this.show():this.hide();var self=this;WS.Event.addEvent(this.toggler,'click',function(e){if(!self.followLink){WS.Event.stopEvent(e);}self.toggle();});},isVisible:function(){return this.visible;},show:function(){WS.show(this.toggleEl);if(this.parentOffset){WS.addClass(WS.DOM.getParent(this.toggler,this.parentOffset),'selected')}else{WS.addClass(this.toggler,'selected');}this.visible=true;},hide:function(){WS.hide(this.toggleEl);if(this.parentOffset){WS.removeClass(WS.DOM.getParent(this.toggler,this.parentOffset),'selected')}else{WS.removeClass(this.toggler,'selected');}this.visible=false;},toggle:function(){if(this.onBeforeToggle){this.onBeforeToggle(this.toggler);}this.isVisible()?this.hide():this.show();if(this.onAfterToggle){this.onAfterToggle(this.toggler);}}};
var RoomFilterForm=function(formId,tableId){this.formId=formId;this.tableId=tableId;this.form=null;this.table=null;};RoomFilterForm.prototype={initialize:function(){this.form=$(this.formId);this.table=$(this.tableId);var self=this;if(this.form){WS.Event.addEvent(this.form,'submit',function(e){WS.Event.stopEvent(e);self.sendRequest();});}else{return false;}},sendRequest:function(){var personMin=$('person-min').value;var personMax=$('person-max').value;var areaMin=$('area-min').value;var areaMax=$('area-max').value;var emplacements=this.getEmplacements();var postBody='personmin='+personMin+'&personmax='+personMax+'&areamin='+areaMin+'&areamax='+areaMax+'&emplacements='+emplacements;WS.Ajax.request(extra_url + '/rooms/filter',function(response){$('rooms-table-wrap').innerHTML=response;RowClick.initialize();RowHover.initialize();},postBody);},getEmplacements:function(){var inputs=$('emplacement-filter-menu').getElementsByTagName('input');var values=[];for(var i=0;i<inputs.length;i++){if(inputs[i].checked){values.push(inputs[i].value);}}return values;}};


/**
 * YouTubeCarousel.js - YouTubePlayer and jCarousel combined
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
function YouTubeCarousel(carouselId, options) {
	this.carouselId = carouselId;
	this.carousel = null;
	this.players = {};
	this.options = options;
	this.playerIntervals = {};
	this.playerPoller = null;
	this.init();
};

YouTubeCarousel.prototype = {
	init: function() {
		var self = this;
		
		if(typeof this.options != 'undefined') {
			for(prop in this.options) {
				this[prop] = this.options[prop];
			}
		}
		
		jQuery('#' + this.carouselId).jcarousel({
			scroll: 1,
			animation: 'slow',
			auto: 7,
			wrap: 'both',
			initCallback: function(carousel) {
				self.carouselInitCallback(carousel);
			},
			itemVisibleInCallback: function(carousel, slide, index, state) {
				self.carouselItemVisibleInCallback(carousel, slide, index, state);
			},
			itemVisibleOutCallback: function(carousel, slide, index, state) {
				self.carouselItemVisibleOutCallback(carousel, slide, index, state);
			}
		});
	},
	carouselInitCallback: function(carousel) {
		var self = this;
		this.carousel = carousel;
		
		this.carousel.clip.hover(
			function() {
				self.carousel.stopAuto();
			},
			function() {
				if(!self.isPlayerPlaying()) {
					self.carousel.startAuto();
				}
			}
		);
		
		if(this.controlsId) {
			jQuery('#' + this.controlsId + ' a').click(function(e){
				e.preventDefault();
				
				for(playerId in self.players) {
					if(self.players[playerId].player && self.players[playerId].getPlayerState() === 1) {
						self.players[playerId].pauseVideo();
					}
				}
				
				self.carousel.stopAuto();
				var index = jQuery('#' + self.controlsId + ' a').index(this);
				self.carousel.scroll(index + 1);
				self.carousel.startAuto();
			});
		}
	},
	carouselItemVisibleInCallback: function(carousel, slide, index, state) {
		var self = this;
		
		if(this.controlsId) {
			jQuery('#' + this.controlsId + ' li:nth-child(' + index + ')').addClass('selected');
		}
		
		var player = jQuery(slide).find('.player-wrapper object')[0];
		
		this.playerPoller = setInterval(function() {
			if((player && self.players[player.id].state != -1)) {
				player.playVideo();
				clearInterval(self.playerPoller);
			}
			else {
				player = jQuery(slide).find('.player-wrapper object')[0];
			}
		}, 10);
	},
	carouselItemVisibleOutCallback: function(carousel, slide, index, state) {
		if(this.controlsId) {
			jQuery('#' + this.controlsId + ' li:nth-child(' + index + ')').removeClass('selected');
		}
	},
	addPlayer: function(playerId, videoId) {
		var self = this;
		
		this.players[playerId] = new YouTubePlayer(playerId, {
			videoId: videoId,
			width: this.videoWidth || 500,
			height: this.videoHeight || 280,
			onBuffering: function(p) {
				self.carousel.stopAuto();
			},
			onPlay: function(p) {
				self.carousel.stopAuto();
				if(!self.playerIntervals[playerId]) {
					self.playerIntervals[playerId] = setInterval(function() {
						jQuery('#' + playerId + '-elapsed').css('width', Math.round((100 * p.getCurrentTime()) / p.getDuration()) + '%');
					}, 1000);
				}
				jQuery('#' + playerId + '-wrapper').addClass('playing');
			},
			onPause: function(p) {
				jQuery('#' + playerId + '-wrapper').removeClass('playing');
				self.clearPlayerInterval(playerId);
			},
			onEnd: function(p) {
				jQuery('#' + playerId + '-wrapper').removeClass('playing');
				jQuery('#' + playerId + '-elapsed').css('width', '100%');
				self.clearPlayerInterval(playerId);
				self.carousel.startAuto();
			}
		});
		
		jQuery('#' + playerId + '-play').click(function(e) {
			e.preventDefault();
			self.players[playerId].togglePlay();
		});
		
		jQuery('#' + playerId + '-mute').click(function(e) {
			e.preventDefault();
			self.players[playerId].toggleMute();
			jQuery('#' + playerId + '-wrapper').toggleClass('muted');
		});
	},
	clearPlayerInterval: function(playerId) {
		clearInterval(this.playerIntervals[playerId]);
		this.playerIntervals[playerId] = null;
	},
	isPlayerPlaying: function() {
		return jQuery('#' + this.carouselId + ' .playing').length > 0;
	}
};


/**
 * Google Maps map scroller
 * 
 * @param {Object} map The Google Maps map object
 * @param {Array} markers An array containing the marker objects
 * @param {Array} listItems An array containing the list item objects
 * @param {Object} defaultIcon The default marker image
 * @param {Object} defaultHoverIcon The default hover marker image
 */
var MapScroller = function(map, markers, listItems, defaultIcon, defaultHoverIcon) {
	this.map = map;
	this.markers = markers;
	this.listItems = listItems;
	this.defaultIcon = defaultIcon;
	this.defaultHoverIcon = defaultHoverIcon;
	this.timeout = null;
	
	this.ACTIVE_CLASS = 'active';
	
	this.initialize();
};

MapScroller.prototype = {
	initialize: function() {
		this.addMarkerEventListeners();
		this.addListItemEventListeners();
	},
	addMarkerEventListeners: function() {
		var self = this;
		
		for(var i = 0; i < this.markers.length; i++) {
			google.maps.event.addListener(this.markers[i], 'mouseover', function() {
				var index = self.markers.indexOf(this);
				self.highlight(this, self.listItems[index], function() {
					jQuery('#hotels-list').animate({ scrollTop: self.listItems[index].offsetTop });
				});
			});
			google.maps.event.addListener(this.markers[i], 'mouseout', function() {
				var index = self.markers.indexOf(this);
				self.dim(this, self.listItems[index]);
			});
			/*google.maps.event.addListener(this.markers[i], 'click', function() {
				window.location.href = this.href;
			});*/
		}
	},
	addListItemEventListeners: function() {
		var self = this;
		
		/*var mouseOverEvent = WS.browser.IE ? 'mouseenter' : 'mouseover';
		var mouseOutEvent = WS.browser.IE ? 'mouseleave' : 'mouseout';
		
		for(var i = 0; i < this.listItems.length; i++) {
			WS.Event.addEvent(this.listItems[i], mouseOverEvent, function(e) {
				var index = self.listItems.indexOf(this);
				self.highlight(self.markers[index], this, function() {
					self.map.panTo(self.markers[index].getPosition());
				});
			});
			
			WS.Event.addEvent(this.listItems[i], mouseOutEvent, function(e) {
				if(mouseOutEvent == 'mouseout') {
					var relatedTarget = (e.relatedTarget) ? e.relatedTarget : e.toElement;
					
					while(relatedTarget != target && relatedTarget.nodeName != 'BODY') {
						relatedTarget = relatedTarget.parentNode;
					}
					
					if(relatedTarget == target) {
						return;
					}
				}
				
				var index = self.listItems.indexOf(this);
				self.dim(self.markers[index], this);
			});
		}*/
		
		for(var i = 0; i < this.listItems.length; i++) {
			WS.Event.addEvent(this.listItems[i], 'mouseover', function(e) {
				var index = self.listItems.indexOf(this);
				self.highlight(self.markers[index], this, function() {
					self.map.panTo(self.markers[index].getPosition());
				});
			});
			
			WS.Event.addEvent(this.listItems[i], 'mouseout', function(e) {
				var index = self.listItems.indexOf(this);
				self.dim(self.markers[index], this);
			});
		}
	},
	highlight: function(marker, listItem, callback) {
		var self = this;
		
		this.timeout = setTimeout(function() {
			WS.addClass(listItem, self.ACTIVE_CLASS);
			marker.setIcon(self.defaultHoverIcon);
			if(typeof callback == 'function') {
				callback.call();
			}
		}, 100);
	},
	dim: function(marker, listItem) {
		if(this.timeout) {
			clearTimeout(this.timeout);
		}

		WS.removeClass(listItem, this.ACTIVE_CLASS);
		marker.setIcon(this.defaultIcon);
	}
};


/**
 * Webshop cart
 * 
 * @param {String} el The cart container
 */
var Cart = function(el) {
	this.cart = $(el);
	this.overlay = $('cart-actions-overlay');
	this.initialize();
};

Cart.prototype = {
	initialize: function() {
		if(!this.cart) {
			return;
		}
		
		WS.hide(this.overlay);
		
		this.ajaxify();
		this.initQuantityFields();
	},
	initQuantityFields: function() {
		var self = this;
		var quantityFields = WS.DOM.getElementsByClass('quantity-field', this.cart);
		
		for(var i = 0; i < quantityFields.length; i++) {
			var ticketFieldTimeout;
			new QuantityField(quantityFields[i].id, {
				onUpdate: function(el) {
					if(/^[0-9]+$/.test(el.value)) {
						if(ticketFieldTimeout) {
							clearTimeout(ticketFieldTimeout);
						}
						ticketFieldTimeout = setTimeout(function() {
							self.update($(el.id + '-id').value, el.value);
						}, 500);
					}
					else {
						el.value = 1;
					}
				}
			});
		}
	},
	ajaxify: function(node) {
		var self = this;
		var links = WS.DOM.getElementsByClass('cart-link', node || document, 'a');
		
		links.forEach(function(el) {
			var id = self.getProductId(el.href);
			
			if(/\/cart\/add/i.test(el.href)) {
				WS.Event.addEvent(el, 'click', function(e) {
					WS.Event.stopEvent(e);
					self.add(id);
				});
			}
			else if(/\/cart\/delete/i.test(el.href)) {
				WS.Event.addEvent(el, 'click', function(e) {
					WS.Event.stopEvent(e);
					self.del(id);
				});
			}
		});
	},
	getProductId: function(href) {
		var segments = href.split('/');
		
		if(segments.last() == '') {
			return segments[segments.length - 2];
		}
		else {
			return segments.last();
		}
	},
	add: function(id) {
		WS.show(this.overlay);
		
		var self = this;
		
		WS.Ajax.request(extra_url + '/cart/add', function(response) {
			self.cart.innerHTML = response;
			self.ajaxify(self.cart);
			self.initQuantityFields();
			WS.hide(self.overlay);
		}, 'id=' + id);
	},
	update: function(id, quantity) {
		WS.show(this.overlay);
		
		var self = this;
		var postBody = 'id=' + id + '&quantity=' + quantity;
		
		WS.Ajax.request(extra_url + '/cart/update', function(response) {
			$('grand-total').innerHTML = response;
			WS.hide(self.overlay);
		}, postBody);
	},
	del: function(id) {
		WS.show(this.overlay);
		
		var self = this;
		
		WS.Ajax.request(extra_url + '/cart/delete', function(response) {
			self.cart.innerHTML = response;
			self.ajaxify(self.cart);
			self.initQuantityFields();
			WS.hide(self.overlay);
		}, 'id=' + id);
	}
};


/**
 * Event ticket order form
 * 
 * @param {Mixed} form The ID of or reference to the event ticket order form
 */
function EventTicketForm(form) {
	this.form = $(form);
	this.url = '';
	this.init();
};

EventTicketForm.prototype = {
	init: function() {
		//this.form = $(this.formId);

		if(this.form) {
			this.url = this.form.action;
			
			var quantityContainers = WS.DOM.getElementsByClass('quantity-container', this.form);
			for(var i = 0; i < quantityContainers.length; i++) {
				if(!WS.hasClass(quantityContainers[i], 'expanded')) {
					WS.hide(quantityContainers[i]);
					WS.DOM.getElementsByClass('quantity-field', quantityContainers[i])[0].disabled = true;
				}
			}
			
			this.addQuantityEventHandlers();
			this.addOptionEventHandlers();
		}
	},
	addQuantityEventHandlers: function() {
		var self = this;
		var quantityInputs = WS.DOM.getElementsByClass('quantity-field', this.form);
		
		for(var i = 0; i < quantityInputs.length; i++) {
			new QuantityField(quantityInputs[i].id, {
				onUpdate: function(el) {
					if(/^[0-9]+$/.test(el.value)) {
						self.update();
					}
					else {
						el.value = 1;
					}
				}
			});
		}
	},
	addOptionEventHandlers: function() {
		var self = this;
		
		var optionInputs = WS.DOM.getElementsByClass('option-control', this.form);
		
		for(var i = 0; i < optionInputs.length; i++) {
			WS.Event.addEvent(optionInputs[i], 'click', function() {
				self.toggleOptionQuantity(this);
				self.update();
			});
		}
	},
	update: function() {
		var self = this;
		
		WS.Ajax.request(this.url, function(response) {
			self.setData(response);
		}, this.getQueryString());
	},
	toggleOptionQuantity:function(input) {
		var toggleEl = $(input.name + '-quantity-container');
		
		if(toggleEl) {
			var value = parseInt(input.value);
			
			if(value === 1) {
				WS.show(toggleEl);
				$(input.name + '-quantity').disabled = false;
			}
			else if(value === 0) {
				WS.hide(toggleEl);
				$(input.name + '-quantity').disabled = true;
			}
		}
	},
	getQueryString: function() {
		var queryStringArr = [];
		var el;
		var value;
		
		for(var i = 0; i < this.form.elements.length; i++) {
			el = this.form.elements[i];
			
			if(el.name && !el.disabled) {
				value = '';
				
				switch(el.tagName) {
					case 'INPUT':
						if((el.type == 'checkbox' || el.type == 'radio') && !el.checked) {
							break;
						}
					case 'TEXTAREA':
					case 'SELECT':
						value = el.value;
						break;
				}
				
				if(!((el.type == 'checkbox' || el.type == 'radio') && !el.checked)) {
					queryStringArr.push(el.name + '=' + encodeURIComponent(value));
				}
			}
		}
		
		return queryStringArr.join('&');
	},
	setData: function(json) {
		var data = WS.Util.parseJSON(json);
		
		var ticketSumEls = WS.DOM.getElementsByClass('ticket-sum', this.form);
		jQuery(ticketSumEls).each(function(el) {
			WS.setText(el, data.ticketSum);
		});

		if ($('option-list')) {
			WS.setText('option-list', data.optionList);
		}
		if ($('ticket-total')) {
			WS.setText('ticket-total', data.ticketTotal);
		}
		if ($('option-costs')) {
			WS.setText('option-costs', data.optionCosts);
		}
		if ($('service-costs')) {
			WS.setText('service-costs', data.serviceCosts);
		}
		if ($('grand-total')) {
			WS.setText('grand-total', data.grandTotal);
		}
	}
};


/**
 * Exhibition ticket order form
 * 
 * @param {Mixed} form The ID of or reference to the exhibition ticket order form
 */
function ExhibitionTicketForm(form) {
	this.form = $(form);
	this.personTable = null;
	this.personQuantityField = null;
	this.personCount = 1;
	this.totalCount = 1;
	this.init();
};

ExhibitionTicketForm.prototype = {
	init: function() {
		if(this.form) {
			this.personTable = $('tickets-person-table');
			
			if($('person-quantity')) {
				this.personCount = this.totalCount = parseInt($('person-quantity').value);  
				
				this.addPersonQuantityEventHandler();
				this.addDeleteRowEventHandlers();
			}
		}
	},
	addPersonQuantityEventHandler: function() {
		var self = this;
		
		this.personQuantityField = new QuantityField('person-quantity', {
			minValue: 1,
			onUpdate: function(el) {
				if(!/^[0-9]+$/.test(el.value) || el.value <= 0) {
					el.value = 1;
				}
				self.update(el.value);
			}
		});
	},
	addDeleteRowEventHandlers: function() {
		var self = this;
		var links = WS.DOM.getElementsByClass('person-delete');
		
		links.forEach(function(el) {
			//console.log(WS.DOM.getParent(el, 2));
			
			WS.Event.addEvent(el, 'click', function() {
				self.removePersonRow(WS.DOM.getParent(el, 2).rowIndex);
				self.personQuantityField.decrement();
			});
		});
	},
	update: function(quantity) {
		var delta = quantity - this.personCount;
		
		if(delta !== 0) {
			var absoluteDelta = Math.abs(delta);
			
			for(var i = 0; i < absoluteDelta; i++) {
				if(delta > 0) {
					this.addPersonRow();
				}
				else if(delta < 0) {
					this.removePersonRow();
				}
			}
		}
	},
	addPersonRow: function() {
		var self = this;
		var row = this.personTable.insertRow(-1);
		
		// Initials cell
		var initialsCell = row.insertCell(-1);
		initialsCell.className = 'initials';
		initialsCell.innerHTML = '<input class="text" type="text" name="data[Person][' + this.totalCount + '][initials]">';
		
		// Last name cell
		var lastnameCell = row.insertCell(-1);
		lastnameCell.className = 'lastname';
		lastnameCell.innerHTML = '<input class="text" type="text" name="data[Person][' + this.totalCount + '][lastname]">';
		
		// Gender cell
		var genderCell = row.insertCell(-1);
		genderCell.className = 'gender';
		
		var genderCellHtml = [];
		genderCellHtml.push('<input id="gender-male-' + this.totalCount + '" type="radio" name="data[Person][' + this.totalCount + '][gender]" value="male">\n');
		genderCellHtml.push('<label for="gender-male-' + this.totalCount + '">Man</label>\n');
		genderCellHtml.push('<input id="gender-female-' + this.totalCount + '" type="radio" name="data[Person][' + this.totalCount + '][gender]" value="female">\n');
		genderCellHtml.push('<label for="gender-female-' + this.totalCount + '">Vrouw</label>\n');
		genderCell.innerHTML = genderCellHtml.join('');
		
		// E-mail cell
		var emailCell = row.insertCell(-1);
		emailCell.className = 'email';
		emailCell.innerHTML = '<input class="text" type="text" name="data[Person][' + this.totalCount + '][email]">';
		
		// Delete cell
		var deleteCell = row.insertCell(-1);
		deleteCell.className = 'delete';
		
		// Delete button
		var deleteButton = document.createElement('a');
		deleteButton.className = 'person-delete';
		deleteButton.title = 'Verwijderen';
		
		WS.Event.addEvent(deleteButton, 'click', function() {
			self.removePersonRow(row.rowIndex);
			self.personQuantityField.decrement();
		});
		
		deleteCell.appendChild(deleteButton);
		
		this.personCount++;
		this.totalCount++;
	},
	removePersonRow: function(index) {
		if(index >= 0) {
			this.personTable.deleteRow(index);
		}
		else {
			this.personTable.deleteRow(-1);
		}
		
		this.personCount--;
	}
};


/**
 * Old ticket order form
 * 
 * @param {String} id The ID of the ticket order form
 */
var TicketOrderForm = function(id) {
	this.id = id;
	this.form = null;
	this.ticketOptions = null;
	this.init();
};

TicketOrderForm.prototype = {
	init: function() {
		this.form = $(this.id);
		
		if(this.form) {
			this.ticketOptions = $('ticket-options').getElementsByTagName('input');
			this.addEventHandlers();
		}
	},
	addEventHandlers: function() {
		var self = this;
		
		WS.Event.addEvent('eventname', 'change', function() {
			self.update();
		});
		
		WS.Event.addEvent('ticket-quantity', 'change', function() {
			self.update();
		});
		
		WS.Event.addEvent('ticket-rank', 'change', function() {
			self.update();
		});

		for(var i = 0; i < this.ticketOptions.length; i++) {
			WS.Event.addEvent(this.ticketOptions[i], 'click', function() {
				self.update();
			});
		}
	},
	update: function() {
		var self = this;
		var optionValues = [];
		for(var i = 0; i < this.ticketOptions.length; i++) {
			if(this.ticketOptions[i].checked) {
				optionValues.push(this.ticketOptions[i].value);
			}
		}
		
		var postBody = 'id=' + $('eventname').value + '&quantity=' + $('ticket-quantity').value + '&rankId=' + $('ticket-rank').value + '&options=' + optionValues;
		WS.Ajax.request(extra_url + '/events/update', function(response) {
			$('ticket-properties').innerHTML = response;
			self.ticketOptions = $('ticket-options').getElementsByTagName('input');
			self.addEventHandlers();
		}, postBody);
	}
};


/**
 * Ticket order form
 * 
 * @param {String} formId The ID of the ticket order form
 */
function TicketForm(formId) {
	this.formId = formId;
	this.form = null;
	this.url = '';
	this.init();
};

TicketForm.prototype = {
	init: function() {
		this.form = $(this.formId);
		
		if(this.form) {
			this.url = this.form.action;
			
			var quantityContainers = WS.DOM.getElementsByClass('quantity-container', this.form);
			for(var i = 0; i < quantityContainers.length; i++) {
				if(!WS.hasClass(quantityContainers[i], 'expanded')) {
					WS.hide(quantityContainers[i]);
					WS.DOM.getElementsByClass('quantity-field', quantityContainers[i])[0].disabled = true;
				}
			}
			
			this.addQuantityEventHandlers();
			this.addOptionEventHandlers();
		}
	},
	addQuantityEventHandlers: function() {
		var self = this;
		var quantityInputs = WS.DOM.getElementsByClass('quantity-field', this.form);
		
		for(var i = 0; i < quantityInputs.length; i++) {
			new QuantityField(quantityInputs[i].id, {
				onUpdate: function(el) {
					if(/^[0-9]+$/.test(el.value)) {
						self.update();
					}
					else {
						el.value = 1;
					}
				}
			});
		}
	},
	addOptionEventHandlers: function() {
		var self = this;
		
		var optionInputs = WS.DOM.getElementsByClass('option-control', this.form);
		
		for(var i = 0; i < optionInputs.length; i++) {
			WS.Event.addEvent(optionInputs[i], 'click', function() {
				self.toggleOptionQuantity(this);
				self.update();
			});
		}
	},
	update: function() {
		var self = this;
		
		WS.Ajax.request(this.url, function(response) {
			self.setData(response);
		}, this.getQueryString());
	},
	toggleOptionQuantity:function(input) {
		var toggleEl = $(input.name + '-quantity-container');
		
		if(toggleEl) {
			var value = parseInt(input.value);
			
			if(value === 1) {
				WS.show(toggleEl);
				$(input.name + '-quantity').disabled = false;
			}
			else if(value === 0) {
				WS.hide(toggleEl);
				$(input.name + '-quantity').disabled = true;
			}
		}
	},
	getQueryString: function() {
		var queryStringArr = [];
		var el;
		var value;
		
		for(var i = 0; i < this.form.elements.length; i++) {
			el = this.form.elements[i];
			
			if(el.name && !el.disabled) {
				value = '';
				
				switch(el.tagName) {
					case 'INPUT':
						if((el.type == 'checkbox' || el.type == 'radio') && !el.checked) {
							break;
						}
					case 'TEXTAREA':
					case 'SELECT':
						value = el.value;
						break;
				}
				
				if(!((el.type == 'checkbox' || el.type == 'radio') && !el.checked)) {
					queryStringArr.push(el.name + '=' + encodeURIComponent(value));
				}
			}
		}
		
		return queryStringArr.join('&');
	},
	setData: function(json) {
		var data = WS.Util.parseJSON(json);
		
		var ticketSumEls = WS.DOM.getElementsByClass('ticket-sum', this.form);
		for(var i = 0; i < ticketSumEls.length; i++) {
			WS.setText(ticketSumEls[i], data.ticketSum);
		}
		/*ticketSumEls.each(function(el) {
			WS.setText(el, data.ticketSum);
		});*/
		if ($('option-list')) {
			WS.setText('option-list', data.optionList);
		}
		if ($('ticket-total')) {
			WS.setText('ticket-total', data.ticketTotal);
		}
		if ($('option-costs')) {
			WS.setText('option-costs', data.optionCosts);
		}
		if ($('service-costs')) {
			WS.setText('service-costs', data.serviceCosts);
		}
		if ($('grand-total')) {
			WS.setText('grand-total', data.grandTotal);
		}
	}
};
