jQuery.noConflict();

/**
 * document.getElementById fix
 *
 * document.getElementById is broken in IE7 and lower and Opera 9.2 and lower.
 * It returns elements by id AND name, which can result in unexpected behavior.
 * For example, document.getElementById('description') returns the description
 * meta tag in most cases.
 *
 * @see http://webbugtrack.blogspot.com/2007/08/bug-152-getelementbyid-returns.html
 */
if(/msie 6/i.test(navigator.userAgent) || /msie 7/i.test(navigator.userAgent)) {
	document.nativeGetElementById = document.getElementById;

	document.getElementById = function(id) {
		var el = document.nativeGetElementById(id);

		if(el) {
			if(el.id && el.id == id) {
				return el;
			}
			else {
				var els = document.all[id];

				for(var i = 1; i < els.length; i++) {
					if(els[i].id && els[i].id == id) {
						return els[i];
					}
				}
			}
		}
	};
}

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);return xhr}}};
WS.Validation=function(form){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;}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(){return self.validateForm();};},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;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){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(el,options){if(!$(el)){return;}this.tabs=WS.Util.collectionToArray($(el).getElementsByTagName('li'));this.activeTab=null;this.timeout=null;this.listener='click';this.selectedClass='selected';this.onBeforeTabChange=null;this.onAfterTabChange=null;if(typeof options!='undefined'){for(prop in options){this[prop]=options[prop];}}this.initialize();};Tabs.prototype={initialize:function(){var self=this;this.tabs.forEach(function(el){if(WS.hasClass(el,self.selectedClass)){self.activeTab=el;}else{WS.hide(self.getContainer(el));}if(self.listener=='click'){WS.Event.addEvent(el,self.listener,function(e){WS.Event.stopEvent(e);self.setActiveTab(this);});}else if(self.listener=='mouseover'){WS.Event.addEvent(el,self.listener,function(e){var el=this;self.timeout=setTimeout(function(){self.setActiveTab(el);},250);});WS.Event.addEvent(el,'mouseout',function(e){if(self.timeout){clearTimeout(self.timeout);self.timeout=null;}});}});},setActiveTab:function(tab){if(tab==this.activeTab){return;}if(typeof this.onBeforeTabChange=='function'){this.onBeforeTabChange(tab);}WS.hide(this.getContainer(this.activeTab));WS.removeClass(this.activeTab,this.selectedClass);WS.show(this.getContainer(tab));WS.addClass(tab,this.selectedClass);this.activeTab=tab;if(typeof this.onAfterTabChange=='function'){this.onAfterTabChange(tab);}},getContainer:function(tab){return $(tab.getElementsByTagName('a')[0].href.split('#')[1]);}};
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&&rows[j].parentNode.nodeName=='TBODY'&&rows[j].getElementsByTagName('th').length<=1){var anchor=rows[j].getElementsByTagName('a')[0];rows[j].title=anchor.title;this.bindHREF(rows[j],anchor.href);}}}}},bindHREF:function(el,hrf){WS.Event.addEvent(el,'click',function(){window.location.href=hrf;});}}}();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();});
function Toggler(id,options){this.id=id;this.toggler=null;this.togglerEl=null;this.visible=false;this.options=options;this.documentClick=true;this.activeClass='active';this.onBeforeShow=null;this.onBeforeHide=null;this.onAfterShow=null;this.onAfterHide=null;this.init();};Toggler.prototype={init:function(){this.toggler=$(this.id);if(this.toggler){if(typeof this.options!='undefined'){for(prop in this.options){this[prop]=this.options[prop];}}var self=this;this.togglerEl=$(this.toggler.href.split('#')[1]);this.hide();WS.Event.addEvent(this.toggler,'click',function(e){WS.Event.stopEvent(e);self.toggle();});if(this.documentClick){WS.Event.addEvent(document,'click',function(e){if(self.visible){var target=WS.Event.getTarget(e);while(target){if(target==self.togglerEl||target==self.toggler){return false;}target=target.parentNode;}self.hide();}});}}},show:function(){if(typeof this.onBeforeShow==='function'){this.onBeforeShow(this.toggler,this.togglerEl);}WS.addClass(this.toggler,this.activeClass);this.togglerEl.style.display='';this.visible=true;if(typeof this.onAfterShow==='function'){this.onAfterShow(this.toggler,this.togglerEl);}},hide:function(){if(typeof this.onBeforeHide==='function'){this.onBeforeHide(this.toggler,this.togglerEl);}WS.removeClass(this.toggler,this.activeClass);this.togglerEl.style.display='none';this.visible=false;if(typeof this.onAfterHide==='function'){this.onAfterHide(this.toggler,this.togglerEl);}},toggle:function(){this.visible?this.hide():this.show();}};


/**
 * Toggle input value
 *
 * @param {Object} input An HTMLInputObject ID or reference
 */
function toggleInputValue(input) {
	var v = input.value;

	if(v != '') {
		WS.Event.addEvent(input, 'focus', function() {
			if(this.value == v) {
				this.value = '';
			}
			WS.addClass(this, 'focus');
		});

		WS.Event.addEvent(input, 'blur', function() {
			if(this.value == '') {
				this.value = v;
				WS.removeClass(this, 'focus');
			}
		});
	}
};


/**
 * Filter form
 *
 * @param {String} id The ID of the filter form
 * @param {String} canvas The canvas where to render the filter response
 */
function FilterForm(id, canvasId, options) {
	this.id = id;
	this.form = null;
	this.canvasId = canvasId;
	this.canvas = null;
	this.options = options;
	this.onSuccess = null;
	this.url = '';
	this.overlay = null;
	this.init();
	this.request = null;
};

FilterForm.prototype = {
	init: function() {
		this.form = $(this.id);

		if(this.form) {
			if(typeof this.options != 'undefined') {
				for(prop in this.options) {
					this[prop] = this.options[prop];
				}
			}

			this.canvas = $(this.canvasId);
			this.url = this.form.action;

			this.addEventHandlers();
			this.addFilterControlEventHandlers();
			this.createOverlay();
		}
	},
	addEventHandlers: function() {
		var el;
		var eventType;
		var self = this;

		for(var i = 0; i < this.form.elements.length; i++) {
			el = this.form.elements[i];
			eventType = '';

			if(el.name) {
				switch(el.tagName) {
					case 'INPUT':
						switch(el.type) {
							case 'text':
								eventType = 'keyup';
								break;
							case 'radio':
							case 'checkbox':
								eventType = 'click';
								break;
						}
						break;
					case 'TEXTAREA':
						eventType = 'keyup';
						break;
					case 'SELECT':
						eventType = 'change';
						break;
				}
			}

			if(eventType) {
				WS.Event.addEvent(el, eventType, function() {
					self.sendRequest();
				});
			}
		}
	},
	addFilterControlEventHandlers: function(node) {
		var eventType;
		var params;
		var self = this;

		var controls = WS.DOM.getElementsByClass('filter-control', node);

		controls.forEach(function(el) {
			eventType = '';
			params = {};

			switch(el.tagName) {
				case 'A':
					eventType = 'click';
					break;
				case 'SELECT':
					eventType = 'change';
					break;
			}

			if(eventType) {
				WS.Event.addEvent(el, eventType, function(e) {
					switch(e.type) {
						case 'click':
							WS.Event.stopEvent(e);
							params = self.parseQueryString(el.href);
							break;
						case 'change':
							params = {};
							params[el.name] = el.value;
							break;
					}

					if(!WS.hasClass(el.parentNode, 'selected')) {
						self.updateForm(params);
						self.sendRequest();
					}
				});
			}
		});
	},
	updateForm: function(params) {
		for(param in params) {
			if($(param)) {
				$(param).value = params[param];
			}
		}
	},
	sendRequest: function() {
		var self = this;

		WS.show(this.overlay);
		if (this.request) {
			this.request.abort();
		}
		this.request = WS.Ajax.request(this.url, function(response) {
            if (response) {
                // var data = WS.Util.parseJSON(response);
                var data = jQuery.parseJSON(response);

                self.canvas.innerHTML = data.html;
                self.addFilterControlEventHandlers(WS.DOM.getElementsByClass('overview', $('overview-canvas'))[0]);
                self.addFilterControlEventHandlers(WS.DOM.getElementsByClass('pagination', $('overview-canvas'))[0]);

                self.toggleFilterOptions(data.allowedIds);

                if(typeof self.onSuccess == 'function') {
                    self.onSuccess(data);
                }

                WS.hide(self.overlay);
            }
		}, this.getQueryString());
	},
	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('&');
	},
	parseQueryString: function(url) {
		var params = {};
		var pair;
		var queryString = url.split('?')[1];
		var pairs = queryString.split('&');

		for(var i = 0; i < pairs.length; i++) {
			pair = pairs[i].split('=');
			params[pair[0]] = pair.length > 1 ? pair[1] : '';
		}

		return params;
	},
	toggleFilterOptions: function(ids) {
		var el = null;

		for(var i = 0; i < this.form.elements.length; i++) {
			el = this.form.elements[i];

			if(jQuery(el).parents('#product-filters').length) {
				el.disabled = (ids.indexOf(el.id) == -1);
			}
		}
	},
	createOverlay: function() {
		this.overlay = document.createElement('div');
		this.overlay.className = 'loading-overlay';
		this.overlay.style.display = 'none';
		this.canvas.parentNode.style.position = 'relative';
		WS.DOM.insertAfter(this.overlay, this.canvas);
	}
};


/**
 * Toppoint search form
 *
 * @param {String} formId The ID of the search form
 */
var SearchForm = function(formId, canvasId) {
	this.TOGGLE_CLS = 'advanced-mode';

	this.formId = formId;
	this.form = null;
	this.canvasId = canvasId;
	this.canvas = null;
	this.toggler = null;
	this.advancedCheck = null;
    this.clearForm = null;
	this.url = '';

	this.initialize();
};

SearchForm.prototype = {
	initialize: function() {
		this.form = $(this.formId);

		if(this.form) {
			var self = this;

			this.canvas = $(this.canvasId);
			this.toggler = $('advanced-toggle');
			this.advancedCheck = $('advanced-check');
            this.clearForm = $('clear-form');
			this.url = '/catalog/filters';

			// Reset in case of page refresh (eg. Firefox)
			this.advancedCheck.value = 0;

			WS.Event.addEvent(this.toggler, 'click', function(e) {
				WS.Event.stopEvent(e);
				self.toggleAdvanced();
			});

            if (this.clearForm) {
                WS.Event.addEvent(this.clearForm, 'click', function(e) {
                    WS.Event.stopEvent(e);
                    self.resetForm();
                });
            }

			this.addSelectEventHandlers();
			this.addCloseButton();
		}
	},
	isAdvanced: function() {
		return WS.hasClass(this.form, this.TOGGLE_CLS);
	},
	showAdvanced: function() {
		WS.addClass(this.form, this.TOGGLE_CLS);
		WS.setText(this.toggler, TerugNaarSnelzoeken);
		this.advancedCheck.value = 1;
	},
	hideAdvanced: function() {
		WS.removeClass(this.form, this.TOGGLE_CLS);
		WS.setText(this.toggler, UitgebreidZoeken);
		this.advancedCheck.value = 0;
	},
	toggleAdvanced: function() {
		this.isAdvanced() ? this.hideAdvanced() : this.showAdvanced();
	},
    resetForm: function() {
        jQuery('#' + this.formId).find(':input').each(function() {
            switch(this.type) {
                case 'select-multiple':
                case 'select-one':
                    jQuery(this).val(-1);
                    break;
                case 'password':
                case 'text':
                case 'textarea':
                    jQuery(this).val('');
                    break;
                case 'checkbox':
                case 'radio':
                    this.checked = false;
            }
        });

        this.sendRequest();
    },
	addSelectEventHandlers: function() {
		var el = null;
		var self = this;

		for(var i = 0; i < this.form.elements.length; i++) {
			el = this.form.elements[i];

			if(el.tagName === 'SELECT') {
				WS.Event.addEvent(el, 'change', function(e) {
					self.sendRequest();
				});
			}
		}
	},
	addCloseButton: function() {
		var button = jQuery('<span class="close"></span>');
		var self = this;

		button.click(function() {
			self.hideAdvanced();
		});

		jQuery(this.form).append(button);
	},
	sendRequest: function() {
		var self = this;

		WS.Ajax.request(this.url, function(response) {
			self.canvas.innerHTML = response;
			self.addSelectEventHandlers();
		}, this.getQueryString());
	},
	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('&');
	}
};


/**
 * Accordion, collapse/expand items
 *
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 *
 * @param {String} id The ID of the accordion element
 * @param {Object} options Optional parameters
 */
var Accordion = function(id, options) {
	this.id = id;
	this.accordion = null;
	this.hash = '';

	// Option defaults
	this.togglerCls = 'toggler';
	this.collapsedCls = 'collapsed';
	this.expandedCls = 'expanded';
	this.onBeforeExpand = null;
	this.onAfterExpand = null;
	this.onBeforeCollapse = null;
	this.onAfterCollapse = null;
	this.onBeforeToggle = null;
	this.onAfterToggle = null;

	if(typeof options != 'undefined') {
		for(prop in options) {
			this[prop] = options[prop];
		}
	}

	this.initialize();
};

Accordion.prototype = {
	initialize: function() {
		this.accordion = $(this.id);

		if(this.accordion) {
			var self = this;
			var togglers = WS.DOM.getElementsByClass(this.togglerCls, this.accordion);

			this.hash = window.location.hash.split('#')[1];

			togglers.forEach(function(el) {
				var id = el.href.split('#')[1];

				if(self.hash != '' && id == self.hash) {
					self.expand(id);
				}
				else if(!WS.hasClass(id, self.expandedCls)) {
					self.collapse(id);
				}

				WS.Event.addEvent(el, 'click', function(e) {
					WS.Event.stopEvent(e);
					self.toggle(id);
				});
			});
		}
	},
	isExpanded: function(id) {
		return WS.hasClass(id, this.expandedCls);
	},
	expand: function(id) {
		if(typeof this.onBeforeExpand == 'function') {
			this.onBeforeExpand(id);
		}

		WS.removeClass(id, this.collapsedCls);
		WS.addClass(id, this.expandedCls);

		if(typeof this.onAfterExpand == 'function') {
			this.onAfterExpand(id);
		}
	},
	collapse: function(id) {
		if(typeof this.onBeforeCollapse == 'function') {
			this.onBeforeCollapse(id);
		}

		WS.removeClass(id, this.expandedCls);
		WS.addClass(id, this.collapsedCls);

		if(typeof this.onAfterCollapse == 'function') {
			this.onAfterCollapse(id);
		}
	},
	toggle: function(id) {
		if(typeof this.onBeforeToggle == 'function') {
			this.onBeforeToggle(id);
		}

		this.isExpanded(id) ? this.collapse(id) : this.expand(id);

		if(typeof this.onAfterToggle == 'function') {
			this.onAfterToggle(id);
		}
	}
};


/**
 * Dealers
 */
var countries = {
	BE: { name: 'Belgium', lat: 50.502946, lng: 4.471436, zoomLevel: 7, postcodeFormat: '1234' },
	DK: { name: 'Denmark', lat: 56.261659, lng: 9.503173, zoomLevel: 7, postcodeFormat: '1234' },
	DE: { name: 'Germany', lat: 51.165691, lng: 10.451526, zoomLevel: 6, postcodeFormat: '12345' },
	FR: { name: 'France', lat: 46.225452, lng: 2.219238, zoomLevel: 6, postcodeFormat: '12345' },
	IT: { name: 'Italy', lat: 41.869560, lng: 12.568359, zoomLevel: 6, postcodeFormat: '12345' },
	LU: { name: 'Luxembourg', lat: 49.815273, lng: 6.129583, zoomLevel: 9, postcodeFormat: '1234' },
	MC: { name: 'Monaco', lat: 43.739724, lng: 7.423152, zoomLevel: 14, postcodeFormat: '12345' },
	NL: { name: 'The Netherlands', lat: 52.132633, lng: 5.291266, zoomLevel: 7, postcodeFormat: '1234AB' },
	AT: { name: 'Austria', lat: 47.516231, lng: 13.550072, zoomLevel: 6, postcodeFormat: '1234' },
	ES: { name: 'Spain', lat: 40.463667, lng: -3.74922, zoomLevel: 6, postcodeFormat: '12345' },
	UK: { name: 'United Kingdom', lat: 55.378051, lng: -3.435973, zoomLevel: 5, postcodeFormat: 'AA00 0AA' },
	CH: { name: 'Switzerland', lat: 46.818188, lng: 8.227512, zoomLevel: 7, postcodeFormat: '1234' }
};


/**
 * Dealers Form
 *
 * @param {Mixed} form The dealer search form ID or HTMLFormObject
 */
var DealersForm = function(form) {
	this.form = $(form);
	this.init();
};

DealersForm.prototype = {

	/**
	 * Constructor
	 */
	init: function() {
		if(this.form) {
			this.addCountrySelectHandler();
		}
	},

	/**
	 * Country select box event handler
	 */
	addCountrySelectHandler: function() {
		var self = this;

		WS.Event.addEvent('dealer-country-select', 'change', function() {
			self.setPostcodePlaceHolder(this.value.toUpperCase());
		});

		if(!WS.browser.IE) {
			WS.Event.addEvent('dealer-country-select', 'keyup', function() {
				self.setPostcodePlaceHolder(this.value.toUpperCase());
			});
		}
	},

	/**
	 * Set a postcode placeholder to a country code
	 *
	 * @param {String} countryCode A country code string (e.g. EN, UK or NL)
	 */
	setPostcodePlaceHolder: function(countryCode) {
        if (typeof countries[countryCode] != 'undefined') {
            //this.form.zip.value = countries[countryCode].postcodeFormat;
        }
	}
};


/**
 * Dealers Map
 *
 * @param {Object} map The Google Maps v3 map object
 * @param {Object} form The dealer search form object
 * @param {Object} options Optional parameters
 */
var DealersMap = function(map, form, options) {
	this.map = map;
	this.form = form;
	this.options = options;

	this.establishmentsUrl = '';
	this.requestPostcode = '';
	this.requestCountryCode = '';

	this.dealerMarkers = [];
	this.establishmentMarkers = [];

	this.markerImages = null;
	this.geocoder = null;
	this.overlay = null;

    this.infoWindow = null;

	this.init();
};

DealersMap.prototype = {

	/**
	 * Constructor
	 */
	init: function() {
		if(this.map) {
			if(typeof this.options != 'undefined') {
				for(prop in this.options) {
					this[prop] = this.options[prop];
				}
			}

			this.geocoder = new google.maps.Geocoder();

			this.markerImages = {
				toppoint: new google.maps.MarkerImage('/img/toppoint-marker.png', new google.maps.Size(45, 120), new google.maps.Point(0, 0), new google.maps.Point(15, 120)),
				regular: new google.maps.MarkerImage('/img/regular-marker.png', new google.maps.Size(30, 40), new google.maps.Point(0, 0), new google.maps.Point(10, 40)),
				near: new google.maps.MarkerImage('/img/near-marker.png', new google.maps.Size(40, 45), new google.maps.Point(0, 0), new google.maps.Point(15, 45))
			};

			this.overlay = document.createElement('div');
			this.overlay.id = 'dealer-results-overlay';
			this.overlay.className = 'loading-overlay';
			this.overlay.style.display = 'none';
			WS.DOM.insertAfter(this.overlay, $('dealer-results'));

			this.addCountrySelectHandler();
			this.addFormEventHandler();

			// Place establishment markers
			if(this.establishmentsUrl) {
				this.loadEstablishments(this.establishmentsUrl);
			}

			// Handle requests from another page
			if(this.requestPostcode != '' && this.requestCountryCode != '') {
				this.findDealers(this.requestPostcode, this.requestCountryCode);
			}

            this.infoWindow = new google.maps.InfoWindow({
                content: 'test'
            })
		}
	},

	/**
	 * Country select box event handler
	 */
	addCountrySelectHandler: function() {
		var self = this;

		WS.Event.addEvent('dealer-country-select', 'change', function() {
			self.clearDealers();
			self.setCenterByCountryCode(this.value.toUpperCase());
		});

		if(!WS.browser.IE) {
			WS.Event.addEvent('dealer-country-select', 'keyup', function() {
				self.clearDealers();
				self.setCenterByCountryCode(this.value.toUpperCase());
			});
		}
	},

	/**
	 * Dealer form event handler
	 */
	addFormEventHandler: function() {
		var self = this;

		WS.Event.addEvent(this.form, 'submit', function(e) {
			WS.Event.stopEvent(e);
			self.findDealers(this.zip.value, this.country.value);
		});
	},

	/**
	 * Center the map to a country code
	 *
	 * @param {String} countryCode A country code string (e.g. EN, UK or NL)
	 */
	setCenterByCountryCode: function(countryCode) {
        if (typeof countries[countryCode] != 'undefined') {
            this.map.setCenter(new google.maps.LatLng(countries[countryCode].lat, countries[countryCode].lng));
            this.map.setZoom(countries[countryCode].zoomLevel);
        }
	},

	/**
	 * Adds a new marker to the map
	 *
	 * @param {Object} markerData The marker's data in JSON format
	 */
	addMarker: function(markerData) {
        var self = this;

		var marker = new google.maps.Marker({
			position: new google.maps.LatLng(markerData.latitude, markerData.longitude),
			title: markerData.naamorg,
			icon: this.markerImages[markerData.type],
			map: this.map,
			zIndex: markerData.zIndex
		});

        google.maps.event.addListener(marker, 'click', function() {
            self.infoWindow.setContent(markerData.html);
            self.infoWindow.open(self.map, marker)
        });

        return marker;
	},

	/**
	 * Adds a new dealer marker to the map
	 *
	 * @param {Object} dealer Dealer data in JSON format
	 */
	addDealer: function(dealer) {
		this.dealerMarkers.push(this.addMarker(dealer));
	},

	/**
	 * Adds a new establishment marker to the map
	 *
	 * @param {Object} establishment Establishment data in JSON format
	 */
	addEstablishment: function(establishment) {
		this.establishmentMarkers.push(this.addMarker(establishment));
	},

	/**
	 * Clear all dealer markers from the map
	 */
	clearDealers: function() {
		for(var i = 0; i < this.dealerMarkers.length; i++) {
			this.dealerMarkers[i].setMap(null);
		}

		this.dealerMarkers = [];
	},

	/**
	 * Dealer form submit handler
	 *
	 * @param {String} postcode A postcode string
	 * @param {String} countryCode A country code string (e.g. EN, UK or NL)
	 */
	findDealers: function(postcode, countryCode) {
		var self = this;

		WS.show(this.overlay);

		WS.Ajax.request(this.form.action, function(response) {
			self.handleDealersResponse(response);
		}, 'zip=' + postcode + '&countryCode=' + countryCode);
	},

	/**
	 * Ajax response handler
	 *
	 * @param {String} response Ajax response as JSON string
	 */
	handleDealersResponse: function(response) {
		// var data = WS.Util.parseJSON(response);
        var data = jQuery.parseJSON(response);

		if(data.status == 'OK') {
			var dealers = data.dealers;
			var bounds = new google.maps.LatLngBounds();

			this.clearDealers();

			for(var i = 0; i < dealers.length; i++) {
				if (dealers[i].type == 'near') {
					bounds.extend(new google.maps.LatLng(dealers[i].latitude, dealers[i].longitude));
				}
				this.addDealer(dealers[i]);
			}

			$('dealer-results').innerHTML = data.html;

			this.map.fitBounds(bounds);
			this.map.setZoom(this.map.getZoom() - 2);
		}
		else if(data.statusMessage != '') {
			$('dealer-results').innerHTML = '<p>' + data.statusMessage + '</p>';
		}

		WS.hide(this.overlay);
	},

	/**
	 * Load and place all establishment markers
	 *
	 * @param {String} url The URL to load the establishments from
	 */
	loadEstablishments: function(url) {
		var self = this;

		WS.Ajax.request(url, function(response) {
			// var establishments = WS.Util.parseJSON(response);
            var establishments = jQuery.parseJSON(response);

			for(var i = 0; i < establishments.length; i++) {
				self.addEstablishment(establishments[i]);
			}
		});
	}
};


/**
 * HScrollPanel, horizontal scrollable panel
 *
 * @param {String} panelId The ID of the panel
 * @param {String} sliderId The ID of the slider
 */
var HScrollPanel = function(panelId, sliderId) {
	this.panelId = panelId;
	this.panel = null;
	this.sliderId = sliderId;
	this.slider = null;
	this.container = null;
	this.init();
};

HScrollPanel.prototype = {
	init: function() {
		this.panel = $(this.panelId);

		if(this.panel) {
			var self = this;
			this.slider = jQuery('#' + this.sliderId).slider({
				slide: function(e, ui) {
					self.setPosition(ui.value);
				}
			});
			this.container = this.panel.parentNode;
			var children = WS.DOM.getChildren(this.panel);
			if(children.length) {
				this.panel.style.width = (children[0].offsetWidth * children.length) + 'px';
			}
		}
	},
	setPosition: function(perc) {
		var cWidth = this.container.offsetWidth;
		var pWidth = parseInt(this.panel.style.width);
		var posPx = ((cWidth * (perc / 100)) - (pWidth * (perc / 100)));
		this.panel.style.left = posPx + 'px';
	},
	getSliderPosition: function() {
		return this.slider.slider('value');
	},
	setSliderPosition: function(perc) {
		if(perc < 0) {
			perc = 0;
		}
		else if(perc > 100) {
			perc = 100;
		}
		this.slider.slider('value', perc);
		this.setPosition(perc);
	}
};

