// +------------------------------------------------------------+
// | NameSpace to prevent conflicts								|
// +------------------------------------------------------------+
var neteffect = {
	timestamp : new Date().getTime(),
	gui : {}
};

neteffect.Cache = new function()
{
	var storage = {};
	var uid = 1;
	
	return {
		set : function (data,id)
		{
			var id = id || uid++;
			var data = data || {};
			storage[id] = data;
			return id;
		},
		get : function (id)
		{
			return storage[id] || null;
		},
		remove : function (id)
		{
			delete storage[id];
		},
		getElementCache : function(element)
		{
			if(!element._cacheId)
				element._cacheId = this.set({});
			return this.get(element._cacheId);
		},
		setElementCache : function(element,data)
		{
			var id = element._cacheId || uid++;
			var data = data || {};				
			this.set(data,id);
		}
	};
}();

// +------------------------------------------------------------+
// | OBSERVABLE													|
// +------------------------------------------------------------+
neteffect.Observable = Class.create({
	observe : function(evt,observer)
	{
		if(!this.__observers__)
			this.__observers__ = {};
		if(!this.__observers__[evt])
			this.__observers__[evt] = [];
		this.__observers__[evt].push(observer);
		return this;
	},
	stopObserving : function(evt,observer)
	{
		if(this.__observers__ && this.__observers__[evt])
		{
			var i = this.__observers__[evt].indexOf(observer);
			this.__observers__[evt].splice(i,1);
		};
		return this;
	},
	fire : function(evt)
	{
		if(!this.__observers__ || !this.__observers__[evt.type])
			return this;
		for(var i = 0;i<this.__observers__[evt.type].length;i++)
			this.__observers__[evt.type][i].apply(this,[evt]);
		return this;
	}
});

// +------------------------------------------------------------+
// | This shouldn't be needed but... sigh						|
// +------------------------------------------------------------+
neteffect.onDomReady = (function(){
	
	var app = new neteffect.Observable();
	var eventType = "domready";
	var fired = false;
	
	function doOnLoad()
	{
		if (!fired) {
			app.fire({type: eventType});
			fired=true;
		};
		return;
	};
	
	if(window.onload && window.onload!=doOnLoad)
	{
		var old = window.onload;
		app.observe(eventType,old);
	};
	
	window.onload = doOnLoad;
	
	function subscribe(listener)
	{
		app.observe(eventType,listener);
	};
	
	return subscribe;
})();

// +------------------------------------------------------------+
// | Flash Plugin Check											|
// | 	- neteffect.flashInfo.version //-> number				|
// | 	- neteffect.flashInfo.installed //-> boolean			|
// | 	- neteffect.flashInfo.check(versionTarget)				|
// +------------------------------------------------------------+
neteffect.flashInfo = (function()
{
	var version = installed = 0,i=20;
	if(Prototype.Browser.IE) {
		while(i--){
			try {
				var f = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i);
				version = installed = i;
				break;
			} catch(e){};
		};
	} else {
		if(navigator.plugins && navigator.plugins.length) {
			var f = navigator.plugins["Shockwave Flash"];
			if(f && f.description) {
				installed = version = parseInt(f.description.match(/[\d.]+/)[0]);
			} else if(navigator.plugins["Shockwave Flash 2.0"]) {
				version = installed = 2;
			};
		} else if (navigator.mimeTypes && navigator.mimeTypes.length) {
			var f = navigator.mimeTypes["application/x-shockwave-flash"];
			if(f && f.enabledPlugin) {
				installed = true;
			};
		};
	};
	
	return {
		version:version,
		installed:!!installed,
		check:function(ver){
			return this.installed && this.version >= ver;
		}
	};

})();

// +------------------------------------------------------------+
// | flashNav													|
// | - CUSTOM, Not reusable!									|
// +------------------------------------------------------------+
neteffect.FlashNav = {
	id : "flashNav",
	timer : null,
	flashObj : null,
	allSelects : null,
	tarSelects : [],
	setMenu : function(id) {
		var fObj = this.flashObj = $(this.getSWF(id));
		fObj.onmouseover = function() {
			fObj.SetVariable("hoverState", "1");
		};
		fObj.onmouseout = function() {
			fObj.SetVariable("hoverState", "0");
		};
		fObj.up().setStyle({overflow:"hidden"});
	},
	growParent : function() {
		clearTimeout(this.timer);
		this.flashObj.up().setStyle({height:"400px"});
		/*@cc_on
			/*@if (@_jscript_version < 5.7)
				this.hideSelects();
			/*@end
		@*/
	},
	shrinkParent : function() {
		this.timer = setTimeout("flashNav.doShrink()",500);
		/*@cc_on
			/*@if (@_jscript_version < 5.7)
				this.showSelects();
			/*@end
		@*/
	},
	doShrink : function() {
		this.flashObj.up().setStyle({height:"86px"});
		clearTimeout(this.timer);
	},
	getConflictSelects : function() {
		if(!this.allSelects)
			this.allSelects = $A(document.getElementsByTagName("select"));
		else
			return;
		var _h = this.flashObj.offsetHeight;
		var _y = $(this.flashObj).cumulativeOffset().top;
		for(var s=0;s<this.allSelects.length;s++) {
			var sY = $(this.allSelects[s]).cumulativeOffset().top;
			if(sY > _y && sY < (_y+_h)) {
				this.tarSelects.push(this.allSelects[s]);
			};
		};
	},
	hideSelects : function() {
		this.getConflictSelects();
		this.tarSelects.invoke("hide");
	},
	showSelects : function() {
		this.getConflictSelects();
		this.tarSelects.invoke("show");
	},
	getSWF: function(movieId){
		if(document.all && document.all[movieId]) {
			return document.all[movieId];
		} else if (document.embeds && document.embeds[movieId]) {
			return document.embeds[movieId];
		} else if (window.document && window.document[movieId]) {
			return window.document[movieId];
		} else if (window[movieId]) {
			return window[movieId];
		} else if (document[movieId]) {
			return document[movieId];
		}
	}
};
flashNav = neteffect.FlashNav;
flashNav.bigMenu = neteffect.FlashNav.setMenu;
flashNav.smallMenu = neteffect.FlashNav.setMenu;

// +------------------------------------------------------------+
// | HtmlFlashEmbed												|
// +------------------------------------------------------------+
neteffect.FlashMovies = {};
neteffect.HtmlFlashEmbed = function(el)
{
	var el = $(el),atts={},vars={},pars={},list,i,l,movieId,key,html,api;
	
	if(!neteffect.HtmlFlashEmbed.$guid) neteffect.HtmlFlashEmbed.$guid = 1;
	
	list = el.getElementsBySelector("input.attribute");
	for(i=0,l=list.length;i<l;i++) atts[list[i].name] = list[i].value;
	
	if(!atts.swf) return;
	
	list = el.getElementsBySelector("input.variable");
	for(i=0,l=list.length;i<l;i++) vars[list[i].name] = list[i].value;
	
	list = el.getElementsBySelector("input.parameter");
	for(i=0,l=list.length;i<l;i++) pars[list[i].name] = list[i].value;
	
	if (!atts.id) atts.id = "flashEmbed"+neteffect.HtmlFlashEmbed.$guid++;
	if (!pars.wmode) pars.wmode = "transparent";
	
	movieId = atts.id;
		
	if(atts.version)
		atts.version = new deconcept.PlayerVersion(atts.version.toString().split("."));
	else
		atts.version = new deconcept.PlayerVersion(8);
		
	var SO = new SWFObject();
	for(key in atts) SO.setAttribute(key,atts[key]);
	for(key in vars) SO.addVariable(key,vars[key]);	
	for(key in pars) SO.addParam(key,pars[key]);
	
	SO.addVariable("movieId",atts.id);
		
	html = SO.getSWFHTML();
	
	el.innerHTML = html;
	
	api = {
		movieId : movieId,
		SO : SO,
		getMovie : function(){
			return (Prototype.Browser.IE) ? window[this.movieId] : document[this.movieId];
		},
		setVariable : function(key,value){
			this.getMovie().SetVariable(key,value);
		}
	};
	
	neteffect.FlashMovies[movieId] = api;
	
	//cleanup
	list = l = i = pars = vars = atts = el = html = null;
	
	return api;
};
// +------------------------------------------------------------+
// | Flash Header												|
// +------------------------------------------------------------+
neteffect.FlashHeader = function(element)
{
	if(!movieLib || !SWFObject) // dependencies.
		return;
	
	element = $(element);
		
	var text = element.innerHTML.strip().stripTags();
		
	var h=0,w=0;
	
	var prevEl = element.previous();
	if (prevEl && prevEl.getStyle("cssFloat") == "right")
	{
		var tmpFlt = true;
		element.setStyle({
			cssFloat: "left"
		});
		w += 20;
	};
	
	h = h+element.getHeight();
	w = w+element.getWidth();
	
	if (tmpFlt) 
	{
		element.setStyle({
			cssFloat: ""
		});
	};
	
	// increment size by 2 to account for differences between Arial and VW Font.
	var fontSize = parseInt(element.getStyle("fontSize"))+2;
	var fontWeight = String(element.getStyle("fontWeight")).toLowerCase()||"normal";
	var colour = element.getStyle("color");
	
	var fontColor = "0x";
	if(/rgb/.test(colour))
		colour.split(",").each(function(n){
			fontColor += Number(n.replace(/\D/g,"")).toColorPart();
		});	
	else
		fontColor += colour.replace("#","");
		
	var ID = "FlashText"+neteffect.FlashHeader.UID++;
	
	// ensure uncached version.
	var path = movieLib.FLASHHEADER.path + "?date=" + neteffect.timestamp++;
	var movieObj = new SWFObject(path, ID, w, h, movieLib.requiredVersion, "#ffffff", true);
		movieObj.addParam("quality", "high");
		movieObj.addParam("wmode", "transparent");
		movieObj.addVariable("movieId",ID);
		movieObj.addVariable("string",text.replace("&","%26").replace("?","%3F"));
		movieObj.addVariable("fontColor",fontColor);
		movieObj.addVariable("fontMinSize",fontSize);
		movieObj.addVariable("fontWeight",fontWeight);
	
	element.innerHTML = "<span class='hidetextforflash'>"+text+"</span>"+movieObj.getSWFHTML();

};
neteffect.FlashHeader.UID = 1;

//+-------------------------------------------------------------+
//| Window Popup Object											|
//+-------------------------------------------------------------+
neteffect.PopUp = function(params)
{
	// ensure a new instance.
	if(this == neteffect)
		return new neteffect.PopUp(params);
	
	// set (default) arguments.
	var url = params.url || "#";
	var tar = params.target || null;
	var props = "";
		
	// default options
	var options = {
		"menubar" : "0",
		"location" : "0",
		"resizable" : "0",
		"scrollbars" : "0",
		"status" : "0",
		"toolbar" : "0",
		"directories" : "0",
		"width" : "200",
		"height" : "200"
	};
	
	if(params.width === "full")
		params.width = screen.width;
	
	if(params.height === "full")
		params.height = screen.height;
	
	// build parameter string.
	for(var key in options)
		props += key + "="+(params[key]||options[key])+",";
	
	var posX = params.x || (screen.width / 2) - ((params.width||options.width)/2);
	var posY = params.y || (screen.height / 2) - ((params.height||options.height)/2);
	
	// remove trailing comma.
	props = props.replace(/\,$/,"");
	
	var api = {
		open : function()
		{
			var o = window.open(url,tar,props);
			o.moveTo(posX,posY);
			return this;
		}
	};
	
	// open window.
	api.open();
	
	return api; 

};

// +------------------------------------------------------------+
// | Link Popup Window											|
// +------------------------------------------------------------+
neteffect.linkPopWindow = function(element){
	var url = element.href;
	var params = url.parseQuery();
	params.url = url;
	
	new neteffect.PopUp(params);
};

// +------------------------------------------------------------+
// | Overlay													|
// +------------------------------------------------------------+
neteffect.gui.Overlay = function(color,opacity,depth)
{
	var w,h;
	var depth = depth||9999;
	
	if(window.innerHeight > 0 && window.scrollMaxY)
	{
		w = window.innerWidth + window.scrollMaxX - 17;
		h = window.innerHeight + window.scrollMaxY;
	}
	else
	{
		w = Math.max(document.body.scrollWidth,document.body.offsetWidth);
		h = Math.max(document.body.scrollHeight,document.body.offsetHeight);
	};
	
	var overlay = document.createElement("div");
		overlay = $(document.body.appendChild(overlay));
		overlay.setStyle({
			position: "absolute",
			top: "0px",
			left: "0px",
			background : "#"+color,
			opacity : opacity,
			width : w + "px",
			height : h + "px",
			zIndex : depth
		});
	
	// api
	return {
		visible : overlay.visible(),
		width : w,
		height: h,
		show : function(){
			overlay.show();
			return this;
		},
		hide : function(){
			overlay.hide();
			return this;
		}
	};
};
//+------------------------------------------------------------+
//| DropShadow													|
//+------------------------------------------------------------+
neteffect.gui.DropShadow = function(parent,target,strength,range)
{	
	if(!target && !target.nodeName)
		return;
		
	var target		= $(target);
	var depth 		= target.getStyle("zIndex")-1||0;
	var parent 		= parent	|| document.body;
	var strength 	= strength	|| .4;
	var range 		= range		|| 4;
	var gradient	= ["#FFF","#CCC","#999","#666","#333","#000"];
	
	var styleObj = {
		position: "absolute",
		zIndex: depth,
		margin: "1px"
	};
	
	var layers = [];
	
	for(var i=0;i<range;i++)
	{
		layers[i] = $((layers[i-1]||document.body).appendChild(document.createElement("div")));
		styleObj.background = gradient[i];
		layers[i].setStyle(styleObj);
	};
	
	var shadow = $(parent.appendChild(layers[0]));
		shadow.setOpacity(strength);
	
	var api = {
		setPosition : function()
		{
			var x = target.getStyle("left")||0;
			var y = target.getStyle("top")||0;

			shadow.setStyle({
				top : parseInt(y)+range+"px",
				left : parseInt(x)+range+"px"
			});
			return api;
		},
		setDimensions : function(w,h)
		{
			var w = target.getWidth();
			var h = target.getHeight();
			for(var i=0;i<layers.length;i++)
			{
				layers[i].setStyle({
					width : w-(i*2) + "px",
					height : h-(i*2) + "px"
				});
			};
			return api.setPosition();
		},
		show : function()
		{
			shadow.show();
			return api;
		},
		hide : function()
		{
			shadow.hide();
			return api;
		}
	};
	
	return api;
	
};

//+------------------------------------------------------------+
//| PopInBox													|
//+------------------------------------------------------------+
neteffect.gui.PopInBox = function(className,content,depth,x,y,noscroll)
{
	var depth=depth||9999;
	
	var box = $(document.body.appendChild(document.createElement("div")));
		box.className = className || "popin-box";
		box.setStyle({
			position: "absolute",
			zIndex: depth
		});

	var closeButton = $(box.appendChild(document.createElement("div")));
		closeButton.className = "close";
		closeButton.innerHTML = "close";
	
	var boxContent = $(box.appendChild(document.createElement("div")));
		boxContent.className = "content";
	if ( !noscroll ) {
		boxContent.style.overflow = "auto";
	}
	
	//api
	var api = new neteffect.Observable();
	
	Object.extend(api, {
		element : box,
		setPosition : function(x,y)
		{
			var w = window.innerWidth || (document.documentElement||document.body).clientWidth;
			var h = window.innerHeight || (document.documentElement||document.body).clientHeight;
			var bh = box.getHeight();
			var bw = box.getWidth();
			var xOffset = window.pageXOffset||(document.documentElement||document.body).scrollLeft;
			var yOffset = window.pageYOffset||(document.documentElement||document.body).scrollTop;
			var x = x || (bw < w) ? (w/2) - (bw/2) + xOffset : 5;
			var y = y || (bh < h) ? (h/2) - (bh/2) + yOffset : 5;			

			box.setStyle({
				top:y+"px",
				left:x+"px"
			});
			
			api.fire({
				type : "position",
				x : x,
				y : y
			});
			
			return api;
		},
		setDimensions : function(w,h)
		{
			if(w && h)
			{
				box.setStyle({
					width : w + "px",
					height : h + "px"
				});
				boxContent.setStyle({
					width : ( w - 60 ) + "px",
					height : ( h - 60 ) + "px"
				});
			};
			return api.setPosition();
		},
		getContentDimensions: function(){
			return {
				width : box.getWidth() - 60,
				height : box.getHeight() - 60
			};
		},
		setContent : function(content)
		{
			if (typeof content == "string")
			{
				boxContent.innerHTML = content;
			}
			else if (content.nodeName)
			{
				boxContent.innerHTML = "";
				boxContent.appendChild(content.cloneNode(true));
			};
			api.setPosition();
			if (boxContent.scrollHeight>box.getHeight() && !noscroll){
				closeButton.style.right = "20px";
			}
			api.fire({type:"content"});
			return api;
		},
		hide : function()
		{
			api.fire({type:"close"});
			box.hide();
			api.hidden = true;
			return api;
		},
		show : function()
		{
			api.fire({type:"open"});
			box.show();
			api.setPosition();
			api.hidden = false;
			return api;
		}
	});
	
	closeButton.observe("click",function(e){
		api.hide();
	});
	
	var timeoutId;
	
	Event.observe(window,"resize",function(e){
		if(box.visible())
			return api.setPosition();
	});
	Event.observe(window,"scroll",function(){
		clearTimeout(timeoutId);
		timeoutId = setTimeout(api.setPosition,200);
	});

	api.setContent(content);
	
	return api;
};
//+------------------------------------------------------------+
//| VWPopInBox													|
//+------------------------------------------------------------+
neteffect.gui.LinkPopInBox = function(el)
{
	var element = $(el)
	, url = el.href
	, host = window.location.host || "file:///C:/"
	, isImg = /\.(?:gif|jpg|jpeg|png)(?:\?|#|$)/.test(url)
	, isHtml = /\.(?:html|htm|jsp|asp|php)(?:\?|#|$)/.test(url)
	, isFlash = /\.(?:swf)(?:\?|#|$)/.test(url)
	, sameDomain = url.indexOf( host ) !== -1
	, params = url.toQueryParams()
	, noscroll = params.noscroll ? true : false
	, width = params.width || 600
	, height = params.height || 400
	, autoWidth = false
	, autoHeight = false
	
	;
	
	if ( /auto/i.test( width ) ) {
		width = ( window.innerWidth || (document.documentElement||document.body).clientWidth ) - 100;
		autoWidth = true;
	}
	
	if ( /auto/i.test( height ) ) {
		height = ( window.innerHeight || (document.documentElement||document.body).clientHeight ) - 100;
		autoHeight = true;
	}
	
	function openBox(e)
	{
		if(e)
			e.stop();
		
		url = el.href;
		noscroll = params.noscroll ? true : false;
		
		var cache = neteffect.Cache.getElementCache(el);
		
		if (!cache.LinkPopInBox) {
			
			var overlay = new neteffect.gui.Overlay("FFF",.9,2000)
			, box = new neteffect.gui.PopInBox(null,"Loading...",2002,null,null,noscroll)
			, shadow = new neteffect.gui.DropShadow(null,box.element)
			;
			
			box.setDimensions( width , height );
			shadow.setDimensions( width , height );
			
			function updateBoxForAuto(){
				if ( autoWidth ) {
					width = ( window.innerWidth || (document.documentElement||document.body).clientWidth ) - 100;
				}
				if ( autoHeight ) {
					height = ( window.innerHeight || (document.documentElement||document.body).clientHeight ) - 100;
				}
				box.setDimensions( width , height );
				shadow.setDimensions( width , height );
			}
			
			if ( autoWidth || autoHeight ) {
				
				var autoResizeID;
				Event.observe(window,"resize",function(e){
					if ( box.hidden )
						return;
					clearTimeout( autoResizeID );
					autoResizeID = setTimeout( updateBoxForAuto ,200);
				});
				
				box.observe("open", updateBoxForAuto );
				
			}
			
			box.observe("close",overlay.hide);
			box.observe("close",shadow.hide);
			box.observe("open",overlay.show);
			box.observe("open",shadow.show);
			box.observe("content",shadow.setDimensions);
			box.observe("position",shadow.setPosition);
			
			if( isHtml && sameDomain ) {
				
				new Ajax.Request(url,{
					method:"get",
					parameters:{ajaxCall:true},
					onSuccess : function(transport) {
						var html = transport.responseText
							, tmp = $(document.createElement("tmp"))
							, node
						;
						
						tmp.innerHTML = html;
						node = tmp.getElementsBySelector("div[class^=main-content]")[0];
						
						if ( node ) {
							tmp = document.createElement("tmp");
							tmp.appendChild(node);
							html = tmp.innerHTML;
						}
						
						node = tmp.getElementsByTagName("body")[0];
						
						if ( node ) {
							html = node.innerHTML;
						}
						
						box.setContent(html.stripScripts());
						html.evalScripts();
						
						/*
						var contentNode = $(tmp).getElementsBySelector("div[class^=main-content]")[0] || $(tmp).getElementsByTagName("body")[0] || html;
						
						if(contentNode) {
							box.setContent(contentNode);
						} else {
							var re = /\<script[\s\S]*\/layer\>/im;
							var content = (transport.responseText).replace(re,"");
							box.setContent(content);
						}
						*/
						
						tmp = node = null;
					},
					onFailure : function() {
						box.setContent("<p>De pagina kan niet worden geladen of bestaat niet :<br />"+url+"</p>");
					},
					onException : function(a,b) {
						box.setContent("<p>De pagina valt niet onder het huidige domein en verleent dus geen toegang tot de content :<br />"+url+"</p>");
					}
				});
			} else if ( isHtml ) {
				
				var iframe = $(document.createElement("iframe"));
				iframe.setAttribute("src",url);
				iframe.setAttribute("frameBorder","0");
				iframe.setAttribute("scrolling","no");
				iframe.setAttribute("marginheight",0);
				iframe.setAttribute("marginwidth",0);
				iframe.setAttribute("height",box.getContentDimensions().height)
				box.setContent(iframe);
				iframe = null;
				
			} else if( isImg ) {
				var img = document.createElement("img");
					img.src = url;
				box.setContent(img);
			} else if ( isFlash && SWFObject ) {
				var so = new SWFObject( url , url , "100%" , "100%", movieLib.requiredVersion, "#FFFFFF");
				so.addParam("wmode", "transparent");
				so.addParam("menu", "false");
				box.setContent( so.getSWFHTML() );
			}
			cache.LinkPopInBox = box;
		}
		
		cache.LinkPopInBox.show();
	}
	
	el.observe("click",openBox);
	openBox();
};

// +------------------------------------------------------------+
// | Car Texture Configurator									|
// | - CUSTOM, Not reusable!									|
// +------------------------------------------------------------+
neteffect.CarTextureConfigurator = function(el)
{
	var element = $(el);
	
	if(!el) return;
	
	var previewImage = element.down("div.preview>img"),
		previewTitle = element.down("h3.preview-name"),
		previewPrice = element.down("p.preview-price");
	
	function swapImage(el)
	{
		var bits = el.alt.split(", ");
		previewTitle.update(bits[0]||"");
		previewPrice.update(bits[1]||"");
		previewImage.src = el.getAttribute("longdesc");
		previewImage.alt = bits[0]||"";
	};
	
	function handleClick(e)
	{
		var el = $(e.target);
		if(/img/i.test(el.tagName) && el.up(".thumbnails"))
		{
			var li = el.up("li");
			if(li.hasClassName("current"))
				return false;
				
			var current = element.down("li.current");
			if(current)
				current.removeClassName("current");
			li.addClassName("current");
			swapImage(el);
		};
	};
	
	el.observe("click",handleClick);
};
// +------------------------------------------------------------+
// | VW SimpleSlideShow											|
// | - CUSTOM, Not reusable!									|
// +------------------------------------------------------------+
neteffect.SimpleSlideShow = Class.create({
	initialize : function(list)
	{
		// if list has already been turned into a slideshow
		// update it instead.
		var cache = neteffect.Cache.getElementCache(list);
		if(cache.slideshow)
			return cache.slideshow.update();
		cache.slideshow = this;
		
		this.list = $(list);
		this.totalHeight = 0;
		this.buttonPosition = 0;
		this.children = [];

		this.update();
		
		list.setStyle({
			height : this.totalHeight+"px"
		});

	},
	togglePanel : function(panel,button)
	{
		this.currentButton.removeClassName("active");
		this.currentPanel.addClassName("closed");
		button.addClassName("active");
		panel.removeClassName("closed");
		this.currentPanel = panel;
		this.currentButton = button;
		button.blur();
	},
	update : function()
	{
		this.list.childElements().each(function(element,index){
			
			this.totalHeight = Math.max(this.totalHeight,element.getHeight());

			element.setStyle({
				position : "absolute",
				top: "0px",
				left: "0px"
			});
			
			var panel = element.down("div.panel");
			var button = element.down("div.button");
			var bp = this.buttonPosition;
			
			if(!panel || !button)
				return;
			
			button.setStyle({
				position: "absolute",
				top: bp+"px",
				right: 0,
				zIndex : 1
			});
			
			this.buttonPosition += button.getHeight()+2;
			
			if(index == 0)
			{
				this.currentPanel = panel;
				this.currentButton = button;
				button.addClassName("active");
			}
			else
			{
				panel.addClassName("closed");
			};

			button.observe("click",this.togglePanel.bind(this,panel,button));
			
			button.observe("mouseover",function(e){
				if (!this.hasClassName("active")) {
					this.addClassName("hover");
				};
			});
			
			button.observe("mouseout",function(e){
				this.removeClassName("hover");
			});
			
			this.children.push(element);
			
		}.bind(this));
	}
});

// +------------------------------------------------------------+
// | TABS														|
// | - CUSTOM, Not reusable!									|
// +------------------------------------------------------------+
neteffect.Tabs = function(element)
{
	var labelPattern = ".tab-label";
	var contentPattern = ".tab-content";
	
	var active = null;
	var oHeight = 100;
	//var mWidth = $(element).getWidth()-2;
	
	var Tab = function(el,first)
	{
		var tab = $(el);
		var label = tab.down(labelPattern);
		var content = tab.down(contentPattern);
		
		//content.style.width = mWidth+"px";
		
		this.open = function()
		{
			if(!content || ! label)
				return;
			content.show();
			label.addClassName("active");
			if(active && active !== this)
				active.close();
			active = this;
		};
		
		this.close = function()
		{
			if(!content || ! label)
				return;
			content.hide();
			label.removeClassName("active");
		};
		
		if (first) 
		{
			label.addClassName("active");
			this.open();
		}
		else 
		{
			content.hide();
		};
		
		label.observe("click",this.open.bind(this));
		tab.removeClassName("make-tab");
		tab.addClassName("tab");
	};
	
	element.getElementsBySelector("div.make-tab").each(function(el,i){
		oHeight = Math.max(el.getHeight(),oHeight);
		new Tab(el,(!i ? true : false));
	});
	
	element.setStyle({
		"backgroundPosition": "0 1px"
	});
	
	if (!element.hasClassName("tab-module-boxed")) {
		element.setStyle({
			"height": (oHeight + 40) + "px"
		});
	};
};
// +------------------------------------------------------------+
// | MoreInfo													|
// | - CUSTOM, Not reusable!									|
// +------------------------------------------------------------+
neteffect.MoreInfo = function(element)
{
	// following elements are required:
	var icol = element.down("div.js-info-column"),
		list = element.getElementsBySelector("td.more-info"),
		current;
	if(!icol || list.length <= 0)
	{
		return;
	};
	
	function MoreInfo(el)
	{
		var box = el.down("div.more-info");
		if(!box)
		{
			return;
		};
		var clone = box.cloneNode(true);
		el.removeChild(box);
		
		clone = icol.insertBefore(clone,icol.firstChild);
		clone.hide();
		
		el.observe("click",function(e){
			if(current && current !== this)
			{
				current.hide();
			};
			this.show();
			current = this;
		}.bind(this));
		
		this.hide = function()
		{
			clone.hide();
		};
		
		var morph;
		
		this.show = function()
		{
			clone.show();
		};
	};
	
	for(var i=0;i<list.length;i++)
	{
		new MoreInfo(list[i]);
	};
};
// +------------------------------------------------------------+
// | TABS Main Banners
// | - Tabs for manage the main banners
// +------------------------------------------------------------+
neteffect.MainBannersTabs = function(element) {
	var container = $(element);

	var tabDisabled = container.down(".tabDisabled");
	var tabSelected = container.down(".tabSelected");
	
	tabDisabled.observe("click",changeTabs);
	tabSelected.observe("click",changeTabs);
	
	function changeTabs(e) {
		if (e.target.parentElement.parentElement.className=="tabDisabled") {

			var contentDisabled = container.down(".tabDisabled");
			var previousContentSelected = container.down(".tabSelected");

			previousContentSelected.removeClassName("tabSelected");
			previousContentSelected.addClassName("tabDisabled");
			contentDisabled.removeClassName("tabDisabled");
			contentDisabled.addClassName("tabSelected");
		}	
	}

};
// +------------------------------------------------------------+
// | ACCORDION													|
// +------------------------------------------------------------+
neteffect.Accordion = Class.create({
	initialize : function(container) {
		
		this.panels = [];
		this.current = null;
		
		$$("div.panel").each(function(element,index){
			
			var data = {
				panel : element,
				bar : element.down(".bar"),
				content : element.down(".content")
			};
			
			data.bar.setStyle({cursor:"pointer"});
			
			if (index) 
				data.content.hide();
			else {
				this.current = data;
				data.bar.addClassName("active");
			};
			
			data.content.down("p").innerHTML = data.content.down("p").innerHTML.truncate(255);
			
			this.panels.push(data);
			
			data.bar.observe("click",this.toggle.bindAsEventListener(this,data));
			
		}.bind(this));
		
	},
	toggle : function(e,param) {
		if(this.current && param.content === this.current.content)
			return;
		if (this.current) {
			this.current.bar.removeClassName("active");
			this.current.content.hide();
		};
		
		param.content.show();
		param.bar.addClassName("active");
		param.bar.focus();
		
		this.current = param;
		
	}
});

// +------------------------------------------------------------+
// | TABLE ACCORDION											|
// +------------------------------------------------------------+
neteffect.TableAccordion = function(table)
{
	var el,row,panel;
	var panels = [];
	var nrOpen = 0;
	
	// private Class
	function Panel(button,rows)
	{
		
		this.rows = rows;
		this.open = false;
		this.toggle = function(op)
		{
			this.rows.invoke("toggle");
			this.open = !this.open;
			this.open ? this.button.addClassName("open") : this.button.removeClassName("open");
			this.fire({type:"toggle",target:this});
			this.button.blur();
		};
		this.rows.invoke("hide");
		this.button = button.observe("click",this.toggle.bind(this));
	};
	
	Object.extend(Panel.prototype,new neteffect.Observable());
	
	// private method
	function adjustNrOpen(e)
	{
		return nrOpen += e.target.open ? 1 : -1;
	};
	
	var list = table.getElementsByTagName("tbody"),i=0,l=list.length;
	for(i;i<l;i++)
	{
		el = list[i];
		rows = $(el).getElementsBySelector("tr");
		panel = new Panel(rows.shift(),rows);
		panel.observe("toggle",adjustNrOpen);
		panels.push(panel);
	};
	nrPanels = l > 0 ? l : 0;
	
	function toggleAll(e)
	{
		var close = nrPanels == nrOpen;
		close ? e.target.removeClassName("open") : e.target.addClassName("open");
		panels.each(function(p){
			if(!close && !p.open)
				return p.toggle();
			if(close && p.open)
				return p.toggle();
		});
		e.target.blur();
	};
	
	table.getElementsBySelector("*.toggle-all").invoke("observe","click",toggleAll);
	
	// clean up.
	el = rows = list = i = l = Panel = panel = null;
	// keep references to self,nrOpen,panels,nrPanels and adjustNrOpen
};

// +--------------------------------------------------------+
// | Form Validator Class									|
// +--------------------------------------------------------+
neteffect.FormValidator = Class.create(neteffect.Observable,{
	initialize : function(formElement,params){
		var params = params || {};
		
		this.submitOnValid = (params.submitOnValid !== undefined) ? params.submitOnValid : true;
		this.formObj = $(formElement);
		this.prefix = params.prefix || "js-validate";
		this.observers = {};
		
		this.formFields = this.formObj.getElements().select(function(element){
			return element.className.include(this.prefix);
		}.bind(this));
		
		this.formObj.observe("submit",function(e){
			e.stop();
			this.validate();
			return false;
		}.bindAsEventListener(this));
		
		this.compare = {
			STRING : function(field){ return /\b\w+\b/i.test($F(field)); },
			NUMBER : function(field){ return /\b\d+\b/.test($F(field)); },
			EMAIL : function(field){ return /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i.test(field.value); },
			EMPTY : function(field){ return /\b\w+\b/i.test($F(field)); },
			SELECT : function(field) { return field.selectedIndex > 0;},
			RADIO : function(field){
				var n = field.getAttribute("name");
				var fields = this.formObj.getElementsBySelector("input[name="+n+"]");
				for(var i=0;i<fields.length;i++){
					if($F(fields[i])) {
						return true;
					};
				};
				return false;
			}.bind(this),
			CHECK : function(field) { return !!($F(field)); },
			PHONE : function(field){ return /\b\d{10}\b/.test($F(field)); },
			ZIP : function(field){ return /\b\d{4}\s?[a-zA-Z]{2}/.test($F(field)); },
			DATE : function(field){ return /\b\d{1,2}\/\d{1,2}\/\d{4}\b/.test($F(field)); }
		};
		
		if(params.compare) {
			Object.extend(this.compare,params.compare);
		};
		
		if(params.onValidate && typeof params.onValidate == "function") {
			this.observe("validate",params.onValidate);
		};
		
		if(params.onDone && typeof params.onDone == "function") {
			this.observe("done",params.onDone);
		};
		
	},

	validate : function(){		
		
		var results = [];
		this.errors = 0;
		
		for(var i=0;i<this.formFields.length;i++){
		
			var field = this.formFields[i];
			var validationType = this.getValidationType(field);		
			var valid = this.compare[validationType](field);
			
			if(!valid) {
				this.errors++;
			};
			
			var event = {
				type : "validate",
				element : field,
				valid : valid,
				validationType : validationType
			};
			
			results.push(event);
			this.fire(event);
			
		};
		
		var event = {
			type : "done",
			results : results,
			errors : this.errors,
			element : this.formObj
		};
		
		this.fire(event);
		
		if(this.errors == 0 && this.submitOnValid) {
			this.formObj.submit();
		};
		
		return this;
	},
	
	getValidationType : function(element){
		var re = new RegExp(this.prefix+"-([a-zA-Z]+)","");
		return element.className.match(re)[1].toUpperCase();
	}
});

// +------------------------------------------------------------+
// | AUTOSUGGEST												|
// +------------------------------------------------------------+
neteffect.AutoSuggest = Class.create(neteffect.Observable,{
	
	initialize : function(field,options)
	{
		var options = options || {};
		
		this.field = $(field);
		this.suggestions = {
			a : ["Amsterdam","Amstelveen"]
		};
		this.observers = {};
		this.visible = false;
		this.selected = null;
		
		this.options = {
			rows : 6,
			boxClass : "autosuggest-box",
			selectFirst : false
		};
		
		this.patternCache = {};
		
		for (var key in options) 
		{
			this.options[key] = options[key];
		};
		
		this.field.setAttribute('autocomplete', 'off');
		this.field.setAttribute('multiline', 'true');
		
		this.box = document.createElement("ul");
		this.box = $(document.body.appendChild(this.box));
		this.positionBox();
		this.hideBox();
		this.box.addClassName(this.options.boxClass);
		
		this.field.observe("keydown",this.preventSubmit.bind(this));
		this.field.observe("keyup",this.delegateKeyEvent.bind(this));
		this.field.observe("blur",this.findMatch.bind(this));
		this.box.observe("click",this.handleSelect.bind(this));
		
		this.box.observe("mousedown",this.stopBubble);
		this.field.observe("mousedown",this.stopBubble);
		document.observe("mousedown",this.hideBox.bind(this));
		
		this.box.observe("scroll",function(){
			//alert("mouseup")
			this.field.focus();
		}.bind(this));
		
		this.box.observe("mouseover",function(e){
			var node = e.target;
			var tag = node.tagName;
			if(/li/i.test(tag))
			{
				$(node).addClassName("hover");
			};
		});
		this.box.observe("mouseout",function(e){
			var node = e.target;
			var tag = node.tagName;
			if(/li/i.test(tag))
			{
				$(node).removeClassName("hover");
			};
		});
		
	},
	
	stopBubble : function(e)
	{
		e.stopPropagation();
	},
	
	delegateKeyEvent : function(e)
	{
		var key = e.keyCode||null;
		
		if (typeof key == "number")
		{
			if ((key == Event.KEY_RETURN || key == Event.KEY_TAB) && this.visible) {
				return this.handleSelect(e);
			};
			
			if (key == Event.KEY_DOWN || key == Event.KEY_UP) {
				e.stop();
				return this.toggleSelected(key);
			};
			
			if ((key >= 48 && key <= 90) || key == Event.KEY_DELETE || key == Event.KEY_BACKSPACE) {
				this.renderSuggestions();
				e.stopPropagation();
			};
		};
		
		if(this.field.value == "")
		{
			this.hideBox();
		};
		
	},
	
	handleSelect : function(e)
	{
		var eventType = e.type;
		var element = e.target;
		var key = e.keyCode||null;
		
		if(/click/i.test(eventType))
		{
			if(/li/i.test(element.nodeName))
			{
				if(this.selected)
				{
					this.selected.removeClassName("selected");
				};
				this.selected = $(element).addClassName("selected");
			};
		};
		
		if(!this.selected)
		{
			// last attempt.
			this.findMatch(e);
		};
		
		if (this.selected) 
		{
			this.field.value = this.selected.innerHTML;
			this.fire({
				type : "select",
				target : this.field,
				value : this.field.value,
				keyCode : key
			});
			this.field.focus();
		};
		this.hideBox();
	},
	
	findMatch : function(e)
	{
		var key = e.keyCode||null;
		var type = e.type;
		var value = this.field.value.toLowerCase();
		var re = new RegExp("^"+value+"$","i");
		var firstChar = value.charAt(0);
		var list = this.suggestions[firstChar];
		if(list)
			var found = list.grep(re);
		if(found && found.length>0)
		{
			this.field.value = found.first();
			if(type != "blur")
				this.fire({
					type : "match",
					target : this.field,
					value : this.field.value,
					keyCode : key
				});
		}
		else
		{
			this.fire({
				type : "nomatch",
				value : value,
				target : this.field,
				keyCode : key
			});
		};
	},
	
	toggleSelected : function(key)
	{
		var sel = this.selected;
		if (sel) 
		{
			sel.removeClassName("selected");
		};
		if(key == Event.KEY_DOWN)
		{
			sel = (sel) ? sel.next("li") || null : this.box.down("li:first-child");
		}
		else if(key == Event.KEY_UP)
		{
			sel = (sel) ? sel.previous("li") || null : this.box.down("li:last-child");
		};
		if (sel)
		{
			sel.addClassName("selected");
			this.adjustScrollView(sel);
		};
		this.selected = sel;
	},
	
	getSuggestions : function(pattern)
	{
		var firstChar = pattern.charAt(0).toLowerCase();
		var list = this.suggestions[firstChar] || [];
		var len = list.length;
		var suggestions = [];
		for(var i=0;i<len;i++)
		{
			if(list[i].toLowerCase().indexOf(pattern) == 0)
				suggestions.push(list[i]);
		}
		return suggestions;
	},
	
	renderSuggestions : function()
	{
		this.box.innerHTML="";
		//this.box.scrollTop = 1;
		var pattern = this.field.value.toLowerCase();
		var cache = this.patternCache[pattern] || null;
		if (!cache) 
		{
			var list = this.getSuggestions(pattern);
			var len = list.length;
			var sc = "";
			for (var i = 0; i < len; i++) 
			{
				var suggestion = list[i];
				var op = document.createElement("li");
				op.innerHTML = suggestion;
				this.box.appendChild(op);
			};
			this.patternCache[pattern] = {
				html : this.box.innerHTML,
				ammount : len
			};
		}
		else
		{
			this.box.innerHTML = cache.html;
			var len = cache.ammount;
		};
		if (this.options.selectFirst) 
		{
			var frst = this.box.down("li");
			if(frst)
				frst.addClassName("selected");
		};
		this.fire({
			type: "suggestions",
			target : this.field,
			value : this.field.value,
			key : null,
			ammount : len
		});
		this.selected = this.box.down("li.selected") || null;
		this.showBox();
		this.updateDimensions(len);
	},
	
	preventSubmit : function(event)
	{
		var key = event.keyCode;
		
		if (key == Event.KEY_RETURN && this.box.visible()) 
		{
			event.stop();
		};
		if (key == Event.KEY_TAB && this.box.visible())
		{
			this.findMatch(event);
			this.hideBox();
		};
	},
	
	adjustScrollView : function(el)
	{
		if(!this.options.rowHeight)
			this.options.rowHeight = this.box.down("li").getHeight();
		var a = el.positionedOffset().top;
		var b = el.getHeight();
		var c = this.options.rows * this.options.rowHeight;
		var diff = Math.max((a+b)-(c-b),0);
		this.box.scrollTop = diff;
	},
	
	positionBox : function()
	{
		var coords = this.coords = this.field.cumulativeOffset();
		var topOffset = this.topOffset = this.field.getHeight();
		this.box.setStyle({
			position: "absolute",
			top: coords.top + topOffset + "px",
			left: coords.left + "px"
		});
	},
	
	updateDimensions : function(ammount)
	{
		var maxRows = this.options.rows;
		var wasHidden = false;
		var ammount = ammount;
		
		if(ammount > 0)
		{
			if(!this.visible)
			{
				wasHidden = true;
				this.showBox();
			};
			
			if(!this.rowHeight)
			{
				this.rowHeight = this.box.scrollHeight / ammount;
			};
			
			var boxHeight = Math.min((this.rowHeight*maxRows),(this.rowHeight*ammount));

			this.box.setStyle({
				height : boxHeight+"px"
			});
			
			if(wasHidden)
			{
				this.hideBox();
			};
		}
		else
		{
			this.hideBox();
		};
	},
	
	showBox : function()
	{
		this.box.show();
		this.visible = true;
	},
	
	hideBox : function()
	{
		this.box.hide();
		this.visible = false;
	}
	
});

// +------------------------------------------------------------+
// |LOCATIONSUGGEST												|
// +------------------------------------------------------------+
neteffect.LocationSuggest = Class.create(neteffect.Observable,{
	initialize : function(sourceField,targetField,options)
	{
		var options = options;
		this.sourceField = sourceField;
		this.targetField = targetField;
		
		this.options = {
			url : "suggestions.txt",
			rows : 6,
			selectFirst : false,
			boxClass : "autosuggest-box",
			limitSize : false,
			limitMessage : "Er zijn geen mogelijkheden beschikbaar!"
		};
		
		for (var key in options) 
		{
			this.options[key] = options[key];
		};
		
		this.locations = [];
		
		var req = new Ajax.Request(this.options.url, {
			method: "get",
			onSuccess: function(transport){
				this.locations = eval(transport.responseText);
				var locations = ["amsterdam"];
				this.locations.each(function(hash){
					var firstChar = hash.value.charAt(0).toLowerCase();
					if(!locations[firstChar])
						locations[firstChar] = [];
					locations[firstChar].push(hash.value);
				});
				
				this.AutoSuggest = new neteffect.AutoSuggest(this.sourceField,this.options);
				this.AutoSuggest.suggestions = locations;
				
				this.AutoSuggest.observe("select",this.handleSelect.bind(this));
				this.AutoSuggest.observe("match",this.handleSelect.bind(this));
				
				this.AutoSuggest.observe("nomatch",function(){
					this.targetField.value = "";
				}.bind(this));
				
				if (this.options.limitSize) 
				{
					var self = this;
					this.AutoSuggest.observe("suggestions", function(e)
					{
						var field = e.target;
						var value = e.value;
						var msg = $("errorboodschap");

						if(e.ammount)
						{
							field.maxLength = 255;
							if(msg)
								msg.hide();
						}
						else if(value.length > 0)
						{
							field.maxLength = e.value.length;
							if(msg)
								msg.update(this.options.limitMessage).show();
						};
						
					});
				};
			}.bind(this)
		});
		
		var form = this.sourceField.up("form");
		form.observe("submit",function(e){
			e.stop();
			var ls = this.AutoSuggest;
			function onMatch()
			{
				form.submit();
			};
			function onNoMatch(){
				ls.stopObserving("match",onMatch);
				ls.stopObserving("nomatch",onNoMatch);
			};
			ls.observe("match",onMatch);
			ls.observe("nomatch",onNoMatch);
			ls.findMatch(e);
			
		}.bind(this));
		
	},
	
	handleSelect : function(e)
	{
		var re = new RegExp("^"+this.sourceField.value.strip()+"$","i");
		var zip = this.locations.find(function(hash){
			return re.test(hash.value.strip());
		}).zip || null;
		
		e.target = this;
		if(zip)
		{
			this.targetField.value = zip;
			this.fire(e);
		}
		else
		{
			e.type = "nomatch";
			this.targetField.value = "";
			this.fire(e);
		};
	}
});

// +------------------------------------------------------------+
// | LOKATIENET ADAPTER											|
// +------------------------------------------------------------+
neteffect.LokatieNetAdapter = Class.create({
	initialize : function(el)
	{
		var zoomIn = el.down(".zoom-in");
		var zoomOut = el.down(".zoom-out");
		var iframe = el.down(".route-map");
		var params = iframe.src.parseQuery();
		var url = iframe.src.replace(/\?.+/,"");
		
		params.zoom = params.zoom || 1;
		
		//var form = el.down(".route-form");
		var dealerId = params.dealer;
		
		function checkToggle() {
			(params.zoom > 1) ? zoomIn.setOpacity(1) : zoomIn.setOpacity(.2);
			(params.zoom < 10) ? zoomOut.setOpacity(1) : zoomOut.setOpacity(.2);
		};
		checkToggle();
		
		zoomIn.observe("click",function(e){
			e.stop();
			if (params.zoom > 1) 
			{
				params.zoom--;
				iframe.src = url + "?" + $H(params).toQueryString();
				checkToggle();
			};
			this.blur();
		});
		
		zoomOut.observe("click",function(e){
			e.stop();
			if (params.zoom < 10) 
			{
				params.zoom++;
				iframe.src = url + "?" + $H(params).toQueryString();
				checkToggle();
			};
			this.blur();
		});
		
		/*
		form.observe("submit",function(e){
			e.stop();
			var zip = $F(form["postcode"]);
			if (/\d{4}\w{2}/.test(zip) && dealerId) 
			{
				var url = "?url=" + encodeURIComponent("http://www.volkswagen.nl/lokatienet_vw2?zoom=1&dealer=" + dealerId + "&postcode_vanaf="+zip);
				//console.log(url)
				el.update("<div class='article'>Even geduld aub. de routebeschrijving wordt opgehaald...</div>");
				new Ajax.Request(url,{
					method : "get",
					onSuccess: function(e)
					{
						//console.log(e)
					},
					onFailure: function(e)
					{
						//console.log(e)
					}
				});
			}
		});
		*/
	}
});

// +------------------------------------------------------------+
// | Compare Module												|
// +------------------------------------------------------------+
neteffect.CompareModule = function (el,dataSrc)
{					
	var container = $(el);
	var dataSrc = dataSrc || "data.txt";
	var columns = [{features:[]},{features:[]},{features:[]}];
	var engineSelect;
	
	// will be populated by the dataSrc after an Ajax.Request.
	var data = {
		engines : [],
		models : [],
		features : []
	};
	
	function addRow(parent,className) // PRIVATE METHOD
	{
		var row = $(parent.appendChild(document.createElement("tr")));
			row.addClassName(className||"&nbsp;");
		return row;
	};
	
	function addCell(parent,className,content) // PRIVATE METHOD
	{
		var cell = $(parent.appendChild(document.createElement("td")));
			cell.innerHTML = content||"<span>&nbsp;</span>";
			cell.addClassName(className||"");
		return cell;
	};
	
	function addOption(parent,label,value) // PRIVATE METHOD
	{
		var opt = $(parent.appendChild(document.createElement("option")));
			opt.innerHTML = label;
			opt.value = value;
		return opt;
	};
	
	function handleModelSelect(col) // PRIVATE METHOD
	{
		var modelId = $F(this);
		columns[col].active = (modelId >= 0) ? true : false;
		columns[col].currentModel = modelId;
		var cells = columns[col].features;
		var feats = data.features;
		for(var i=0;i<cells.length;i++)
			for (var j = 0; j < feats[i].models.length; j++) 
				if (feats[i].models[j].id == modelId) 
					cells[i].set(feats[i].models[j].option);
		handleEngineSelect();
		setPreview(col,modelId);
	};
	
	function handleEngineSelect() // PRIVATE METHOD
	{
		var engineIndex = $F(engineSelect);
		var models = data.engines[engineIndex].models;
		
		// disable or enable wheelbase options.
		for(var i=0;i<columns.length;i++)
		{
			var currentModel = columns[i].currentModel;
			if(currentModel !== undefined)
			{
				var col = columns[i];
				for (var j = 0; j < models.length; j++) 
				{
					if (models[j].id == currentModel) 
					{
						if(models[j]['long']<0)
							col.wheelbase.disable(true);
						else
							col.wheelbase.disable(false).toggle(col.wheelbase.value);
						break;
					};
				};
				setPrice(i);
			};
		};
	};
	
	function handleWheelbaseChoice(col) // PRIVATE METHOD
	{
		columns[col].wheelbase.toggle();
		setPrice(col);
	};
	
	function toIsoNumber(nr,s)
	{
		return nr.toString().split("").reverse().join("").match(/\d{3}|\d+/g).join(s||".").split("").reverse().join("");
	};
	
	function setPrice(col) // PRIVATE METHOD
	{
		var col = columns[col];
		var eng = data.engines[$F(engineSelect)];
		var lon = col.wheelbase.value;
		var pri = col.price;
		var mod = col.currentModel;
		var price = -1;
		
		for(var i=0;i<eng.models.length;i++)
		{
			if(eng.models[i].id == mod)
			{
				var engMod = eng.models[i];
				price = (lon) ? Math.max(engMod['normal'],engMod['long']) : engMod.normal;
				break;
			};
		};
		pri.innerHTML = (price > 0)? "&euro; " + toIsoNumber(price) + ",-" : "(motor n.v.t.)";
	};
	
	function setPreview(col,modelId) // PRIVATE METHOD
	{
		var pre = columns[col].preview, src;
		for (var i = 0; i < data.models.length; i++) 
		{
			if (data.models[i].id == modelId) 
			{
				src = data.models[i].image;
				break;
			};
		};
		pre.style.background = "url("+src+") no-repeat center center;";
		pre.down("span").innerHTML = "<!--"+src+"-->";
	};
	
	function CheckBox(el,col,label) // PRIVATE MODULE CLASS/PATTERN
	{
		var col = col,el = el,cb;
		el.innerHTML = "<span class='checkbox'>&nbsp;</span>"+(label||"");
		
		cb = el.down("span");
		cb.addClassName("checkbox");
		
		return {
			value: false,
			disabled: false,
			toggle: function(bln)
			{
				if (this.disabled) 
					return;
				this.value = (bln !== undefined) ? bln : !this.value;
				(this.value) ? cb.addClassName("active") : cb.removeClassName("active");
				el.blur();
				return this;
			},
			disable: function(bln)
			{
				this.disabled = (bln !== undefined) ? bln : !this.disabled;
				if (this.disabled) 
				{
					cb.removeClassName("active");
					cb.addClassName("disabled");
				}
				else 
				{
					this.toggle(this.value);
					cb.removeClassName("disabled");
				};
				el.blur();
				return this;
			}
		};
	};
	
	function Setting(parent) // PRIVATE MODULE CLASS/PATTERN
	{
		parent.innerHTML = "<span class='setting'>&nbsp;</span>";
		var s = parent.down("span.setting");
		var r = {};
			r.value = -1;
			r.set = function(n){
				if (n == this.value)
					return;
				if (n == 0)
					s.removeClassName("standard").addClassName("optional");
				else if (n == 1)
					s.addClassName("standard").removeClassName("optional");
				else
					s.removeClassName("standard").removeClassName("optional");
				this.value = n;
			};
		return r;
	};
	
	function build() // PRIVATE METHOD
	{
		container.innerHTML = "";
		var cell,row,table,tbody,i,j,sel,opt,feat,wb;
		table = $(container.appendChild(document.createElement("table")));
		table.addClassName("compare-module");
		
		tbody = $(table.appendChild(document.createElement("tbody")));
		
		// preview row
		row = addRow(tbody,"previews");
		
		// preview cells
		for(i=0;i<(1+columns.length);i++)
		{
			cell = addCell(row);
			if(i) columns[i-1].preview = cell;
		};
		
		// select row
		row = addRow(tbody,"options");
		for(i=0;i<(1+columns.length);i++)
		{
			cell = addCell(row);
			sel = $(cell.appendChild(document.createElement("select")));
			if(!i)
			{
				// add engine select box
				sel.addClassName("engines");
				for(j=0;j<data.engines.length;j++)
					addOption(sel,data.engines[j].name,j);
				sel.observe("change",handleEngineSelect);
				engineSelect = sel;
			}	
			else
			{
				// add model select box
				sel.addClassName("models");
				addOption(sel,"(selecteer)",-1);
				for(j=0;j<data.models.length;j++)
					addOption(sel,data.models[j].name,data.models[j].id);
				sel.observe("change",handleModelSelect.curry(i-1));
			};
		};
		
		// price row
		row = addRow(tbody,"prices");
		for(i=0;i<(1+columns.length);i++)
		{
			cell = addCell(row,((i)?"price":""));
			if(i) columns[i-1].price = cell;
		};
		
		// wheelbase option
		row = addRow(tbody,"wheelbase");
		for(i=0;i<(1+columns.length);i++)
		{
			cell = addCell(row,((i)?"wheelbase":""));
			if (i) 
			{
				columns[i - 1].wheelbase = new CheckBox(cell, i - 1, "lange wielbasis");
				cell.observe("click",handleWheelbaseChoice.curry(i-1));
			};
		};
		
		// features
		for(i=0;i<data.features.length;i++)
		{
			feat = data.features[i];
			row = addRow(tbody,"feature");
			cell = addCell(row,"label",feat.name);
			for(j=0;j<columns.length;j++)
				columns[j].features[i] = new Setting(addCell(row,"feature"));
		};
		
		// initial selections
		var a = container.down("select.models",0);
		var b = container.down("select.models",1);
		a.down("option",1).selected = "selected";
		b.down("option",2).selected = "selected";
		handleModelSelect.call(a,0);
		handleModelSelect.call(b,1);
	};
	
	container.innerHTML = "<div>Loading data...</div>";
	
	var req = new Ajax.Request(dataSrc,{
		method : "get",
		onSuccess : function(transport){
			var dataProvider = eval(transport.responseText);
			for(var i=0;i<dataProvider.length;i++)
				data[dataProvider[i].name] = dataProvider[i].data;
			build();
		},
		onFailure : function()
		{
			var str = "<div class='article'><p>";
				str += "De vergelijk module kan momenteel niet geladen worden. Probeer het later nog een keer.";
				str += "<!-- " + dataSrc + "  -->";
				str += "</p></div>";
			
			container.innerHTML = str;
			
			
		}
	});
};

//+-------------------------------------------------------------+
//| Compare Module 2										   	|
//+-------------------------------------------------------------+
neteffect.CompareModule2 = function(container){
	
	if(!container)
	{
		return null;
	};
	
	var bar = $(container).getElementsBySelector("table tr.bar th"),
		options = container.getElementsBySelector("input.checkbox"),
		jsonUrlProvider = container.down("input[name=jsonUrl]"),
		jsonUrl = jsonUrlProvider ? jsonUrlProvider.value : null,
		dataProvider = {},
		rows = {},
		cols = [],
		tmp_rows = $(container).getElementsBySelector("tr[id^=NAC]");
	
	bar.shift();
	
	if(!jsonUrl || !options || options.length <= 0)
	{
		return null;
	};
	
	var i = tmp_rows.length,c;
	while(i--)
	{
		c = tmp_rows[i];
		rows[c.id] = c.getElementsBySelector("td");
	};
	
	function render()
	{
		var i = 3;
		while(i--)
		{
			bar[i].innerHTML = (cols[i]) ? cols[i].spec : "";
			for(var k in rows)
			{
				rows[k][i].innerHTML = (cols[i] && cols[i][k]) ? cols[i][k] : "";
			};
		};
		return true;
	};
	
	function setInitState()
	{
		var i = options.length;
		while(i--)
		{
			options[i].checked = false;
		};
		options[0].checked = true;
		render();
	};
	
	function optionHandler(e)
	{
		var el = e.target,
			key = el.getAttribute("name").replace(/spec/i,"");

		if(/true|checked/i.test(el.checked))
		{
			if(cols.length < 3)
			{
				cols.push(dataProvider[key]);
			}
			else
			{
				e.stop();
				return;
			};
		}
		else
		{
			var i = cols.length;
			while(i--)
			{
				if(cols[i]===dataProvider[key])
				{
					cols.splice(i,1);
				};
			};
		};
		
		return render();
	};
	
	var i = options.length,c;
	while(i--)
	{
		c = options[i];
		c.observe("click",optionHandler);
	};
	
	var req = new Ajax.Request(jsonUrl,{
		method : "get",
		onSuccess : function(transport){
			// dataProvider will be the container for the JSON.
			dataProvider = eval(transport.responseText)[0];
			// On init, the first column is always prefilled with the first option.
			cols[0] = dataProvider[0];
			setInitState();
		},
		onFailure : function(){
			alert("FAIL");
		}
	});
	
	// api
	return {};	
};

// +------------------------------------------------------------+
// | Image Swapper												|
// +------------------------------------------------------------+
neteffect.ImageSwapper = function(container,srcAtt)
{
	var main = $(container).down(".main");
	var srcAtt = srcAtt||"src";
	var thumbs = container.getElementsBySelector(".thumbnail");
	
	function swapImage(e)
	{
		var el = e.target;
		if (el.getAttribute(srcAtt)!="")
		{
			main.src = el.getAttribute(srcAtt);
		};
	};
	
	container.observe("click",swapImage);
	
	thumbs.invoke("setStyle",{cursor:"pointer"});
	
};


// +------------------------------------------------------------+
// | Google Maps											|
// +------------------------------------------------------------+
function doRoute(fulladdress) 
{ 
	window.open("http://maps.google.nl/?ie=UTF8&saddr=" + document.getElementById("postcode").value + "&daddr=" + fulladdress + "&f=d&sampleq=1","new");
}

neteffect.GoogleMapAdapter = function(el)
{ 
	var atts = el.getElementsBySelector("input.attribute");	
	
	var param = {
		address : "",
		zipcode : "",
		description : "",
		housenumber : ""
	};

	for(var i=0,n;n=atts[i++];)
	{
		if(param[n.name]!=null)
		{
			param[n.name] = n.value;
		}; 
	};
	
	// now create the google map implementation.
	if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map_canvas")),
        	geocoder = new GClientGeocoder(),
        	marker;  
        
        //Sets the address in the map, and puts a marker that will show more details about the address	
        function setPoint(point) { 
        	if (point!=null) {
        		marker = new GMarker(point);	
				map.setCenter(point,13); 
				map.addControl(new GSmallMapControl());
	        	map.addControl(new GMapTypeControl());    
				
				//will show the address when the user clicks on the marker
				GEvent.addListener(marker, "click", function() {
			        map.openInfoWindowHtml(map.getCenter(), 
			        		'<div id="contentMap">'+ param["description"] + 
			        		'<br>Adres: ' + param["address"] + " " + param["housenumber"] + " " + param["zipcode"] + 
			        		'<br>' + 
			        		'<label for="route">Route: </label>' + 
							'<input type="text" id="postcode" name="postcode" size="5" maxlength="6" />' +
							'<input type="button" name="button" onclick="doRoute(' + "\'" + 
							param["address"] + " " + param["housenumber"] + " " + 
							param["zipcode"] + "\'" + ');" value="ok"/>' +
			        	    '</div>' );
			    });				
				
				map.addOverlay(marker);
				map.savePosition(); 
			 } else {
				//if the address doesn't exist, the div to show the map is hidden
			 	document.getElementById("map_canvas").hide();
			 }
	 	}
	 	
	 	//get the latitude and longitude according with the address informed
	 	//a callback function (setpoint) is called
        geocoder.getLatLng(param["address"] + " " + param["zipcode"] + " " + param["housenumber"], setPoint);
		 
      }
};

//+------------------------------------------------------------+
//| Shadowbox Implementation								   |
//+------------------------------------------------------------+
neteffect.implementShadowbox = function(){
	
	var isMobile = false, useragent, hostname;
	
	if ( !window['Shadowbox']  || top['startXopus'] ) {
		return;
	}
	
	isMobile;
	useragent = navigator.userAgent.toLowerCase();
	
	if (screen.width < 1000 ||
	        useragent.indexOf('iphone') != -1 ||
	        useragent.indexOf('ipad') != -1 ||
	        useragent.indexOf('ipod') != -1 ||
	        useragent.indexOf('android') != -1 ||
	        useragent.indexOf('blackberry') != -1 ||
	        useragent.indexOf('webos') != -1 ||
	        useragent.indexOf('symbian') != -1) {
	    isMobile = true;
	} 
	
	// sync domain hosts
	hostname = location.hostname.split('.')[location.hostname.split('.').length - 2];
    hostname += '.';
    hostname += location.hostname.split('.')[location.hostname.split('.').length - 1];
    document.domain = hostname;
    
    if ( !isMobile ) {
    	
	    Shadowbox.init( {
	    	
			displayNav: false,
			animate: false,
		    
			onOpen: function () {
			    $( "sb-container" ).addClassName( "volkswagen" );
			},
			
			onClose: function () {
			    $( "sb-wrapper-inner" ).hide();
			},
			
			onFinish: function () {
			
			    $( "sb-wrapper-inner" ).setStyle( {
				    height: 0,
					display: "block"
				});
			
			}
			
		});
	    
	    if(window.location.search != '') {
			var url = location.search.toQueryParams().openpopin
			, tid;
			if(url) {
				tid = setInterval(function(){
					if ( $( "sb-container" ) ) {
						clearInterval(tid);
						Shadowbox.open({
							player: 	'iframe', 
							title: 		'title2', 
							content:	decodeURIComponent(url)
						});
					}
				},100);
			}
		}
	    
    } else {
    	
    	$$("a[rel^=shadowbox]").each(function(el){
    		el.rel = "";
    		el.target = "_blank";
    		el = null;
    	});
    	
    }
	
};
// determine we're on the/a home page!
neteffect.atHome = /^http:\/\/[^\\\/]*\/$/.test(window.location.href);
neteffect.tagCallback = function( tagId ){
	if ( _gaq && neteffect.atHome ) {
		_gaq.push([
			"_trackEvent",
			"homepage",
			"click",
			tagId
		]);
	}
};

neteffect.wpa = function( dealerId ){
	Shadowbox.open({player: 'iframe', title: 'title2', content:'http://imswrpl.vwbedrijfswagens.nl/planbord-cartel.aspx?vestigingid='+dealerId});
};
