var Map = new Class({
	Implements : [Options, Events],
	options :
	{
		aMarkers : [],
		aPoiImages : {
			'def'       : {'src' : '/maps/tent.png', 'width' : 12, 'height' : 15},
			'highlight' : {'src' : '/maps/tent_hl.png', 'width' : 33, 'height' : 34}
		},
		iOverlapMargin: 10,
		bTooltips : true
	}
});

var StaticMap = new Class({
	Extends: Map,
	Implements : [Options, Events],

	oMenuCloseTimer: null,
	oMenuOpenTimer: null,

	initialize: function(el, options)
	{
		this.setOptions(options);
		this.oMapDiv   = $(el);
		this.oMapImage = this.oMapDiv.getElementById('mapimage');
		this.oMapCoords = this.getImageCoords(this.oMapImage);
		this.bPngToGif = (Browser.Engine.trident && Browser.Engine.version <= 4); //Use gifs on IE6 and lower
		if (this.options.bTooltips)
		{
			this.oTips = new Tips('', {className : 'tip-wrapper'});
		}

		this.drawHotspots();
		if (this.options.aMarkers.length > 0)
		{
			this.drawPoiMarkers();
		}
	},

	drawHotspots: function()
	{
		aHotspots = {};
		//Grid Hotspots
		$$('area').each(function(oArea) {
			sShape = oArea.getProperty('shape').toLowerCase();
			sCoords = oArea.getProperty('coords');

			if (this.options.bTooltips)
			{
				oArea.store('tip:title', oArea.get('alt') );
				oArea.removeProperty('alt');
			}

			if (sShape == 'rect')
			{
				aCoords = sCoords.split(",");
				aSplitID = oArea.get('id').split("_");
				iAreaNumber = aSplitID[1];
				sHotspotID = "hotspot_"+iAreaNumber;

				//Create hotspot divs
				aHotspots[oArea.id] = new Element('div', {'id' : sHotspotID, 'class' : 'grid_hotspot', 'styles' : {
					'top' : aCoords[1]+'px',
					'left' : aCoords[0]+'px',
					'width' : (aCoords[2]-aCoords[0]-1)+'px',
					'height' : (aCoords[3]-aCoords[1]-1)+'px'}
				}).inject(this.oMapDiv);

				oLabel = new Element('div', {'class' : 'label', 'text': iAreaNumber}).inject(aHotspots[oArea.id]);

				oArea.addEvents({
					'mouseover' : function() {

						this.toggleHotspot(true, aHotspots[oArea.id]);
					}.bind(this),
					'mouseout' : function() {
						this.toggleHotspot(false, aHotspots[oArea.id]);
					}.bind(this)
				});
			}
			//Poly hotspots (image overlays)
			else if (sShape == 'poly')
			{
				oArea.addEvents({
					'mouseover' : function() {
						aSplit = this.id.split("_");
						oHotspot = $('hotspot_'+aSplit[1]); //Get hotspot element for this area
						if ($defined(oHotspot))
						{
							oHotspot.setStyle('visibility', 'visible');
						}
					},
					'mouseout' : function() {
						if ($defined(oHotspot))
						{
							oHotspot.setStyle('visibility', 'hidden');
						}
					}
				});
			}
		}.bind(this));

		if (this.options.bTooltips)
		{
			this.oTips.attach('area');

		}
	},

	toggleHotspot : function(bShow, oHotspot)
	{
		oHotspot = $(oHotspot);
		if ($defined(oHotspot))
		{
			if (oHotspot.hasClass('grid_hotspot'))
			{
				if (bShow)
					oHotspot.addClass('grid_hotspot_hover');
				else
					oHotspot.removeClass('grid_hotspot_hover');
			}
			else if (oHotspot.hasClass('map_hotspot'))
			{
				oHotspot.setStyle('visibility', (bShow ? 'visible' : 'hidden')); //Show hotspot
			}
		}
		return false;
	},

	toggleMultipleHotspots : function(bShow, aHotspotIDs)
	{
		aHotspotIDs.each(function(iHotspotID) {
			oHotspot = $('hotspot_'+iHotspotID);
			this.toggleHotspot(bShow, oHotspot);
		}.bind(this));
	},

	drawPoiMarkers : function()
	{
		this.options.aMarkers.each(function(oMarker, iIndex)
		{
			iXPos = oMarker.iMapXPos - (this.options.aPoiImages.def.width / 2).round();
			iYPos = oMarker.iMapYPos - (this.options.aPoiImages.def.height / 2).round();
			sImageSource = (this.bPngToGif) ? this.options.aPoiImages.def.src.replace(/\.png/g, '.gif') : this.options.aPoiImages.def.src;

			oMarkerOverlay = new Asset.image(sImageSource, {'id' : oMarker.sElementID, 'class' : 'map_marker' });
			if (this.options.bTooltips)
			{
				oMarkerOverlay.store('tip:title', oMarker.sName);
			}
			oMarkerOverlay.setStyles({'left' : iXPos, 'top'  : iYPos});
			oMarkerOverlay.inject(this.oMapDiv);

			oMarkerOverlay.store('orgleft', oMarker.iMapXPos);
			oMarkerOverlay.store('orgtop',  oMarker.iMapYPos);
			oMarker.oElement = oMarkerOverlay;



			oMarkerOverlay.addEvents({
				'mouseover' : function(e) {

					oMenuOpenTimer = this.showPoiInfo.delay(500, this, [oMarker, e]);
				}.bind(this),
				'mouseout' : function() {
					if ($chk(oMenuOpenTimer)) $clear(oMenuOpenTimer);
					this.hidePoiInfo(oMarker)
				}.bind(this),
				'click' : function() {
					if (oMarker.sUrl.length > 0)
					{
						document.location.href = oMarker.sUrl;
					}
				}
			});
		}.bind(this));

		if (typeof(oTooltip) == 'undefined' && this.options.bTooltips)
		{
			//USe native mootools tips class
			this.oTips.attach('.map_marker');
		}
	},

	showPoiInfo : function(toMarker, event)
	{
		iLeft = toMarker.iMapXPos;
		iTop  = toMarker.iMapYPos;

		//Check if there are overlapping POI markers
		aOverlapMarkers = [];
		aOverlapMarkers.push(toMarker); //Add nearest marker first
		this.options.aMarkers.each(function(oMarker, iIndex)
		{
			iLeftComp = oMarker.iMapXPos;
			iTopComp  = oMarker.iMapYPos;

			if ((oMarker.sElementID != toMarker.sElementID
					&& (iLeft-this.options.iOverlapMargin) <= iLeftComp)
					&& ((iLeft+this.options.iOverlapMargin) >= iLeftComp)
					&& ((iTop-this.options.iOverlapMargin) <= iTopComp)
					&& ((iTop+this.options.iOverlapMargin) >= iTopComp))
			{
		    aOverlapMarkers.push(oMarker);
			}
		}.bind(this));

		oContextMenu = $('markermenu');

		//Hide existing contextmenu
  	if ($chk(oContextMenu)) oContextMenu.dispose();

		//Hide existing tooltip
		if (typeof(oTooltip) != 'undefined' && this.options.bTooltips) { oTooltip.tipOut(); }

		//Show contextmenu to select underlying POI's
		if (aOverlapMarkers.length > 1)
		{
  	  oContextMenu = new Element('div',
  	  {
  	  	'id': 'markermenu',
  	  	'class' : 'contextmenu',
  	  	'styles' : {
  	  		'position' : 'absolute',
  	  		'left' : (this.oMapCoords.x + iLeft),
  	  		'top' : (this.oMapCoords.y + iTop),
  	  		'visibility' : 'visible'
  	  	}
  	  }).inject(document.body);

		  oList = new Element('ul').inject(oContextMenu);

		  aOverlapMarkers.each(function(oMarker) //Create links for each overlapping POI
		  {
			  oListitem = new Element('li').inject(oList);
				oLink     = new Element('a', {'href': oMarker.sUrl, 'text': oMarker.sName}).inject(oListitem);
		  });

		  oContextMenu.addEvents({
		  	'mouseover' : function() {
		  		if (this.oMenuCloseTimer) { $clear(this.oMenuCloseTimer) };
		  	},
		  	'mouseout' : function() {
		  		this.oMenuCloseTimer = this.dispose.delay(2000, this);
		  	}
			});
			this.oMenuCloseTimer = oContextMenu.dispose.delay(2000, this);
		}
  	else
  	{
		  if (typeof(oTooltip) != 'undefined' && this.options.bTooltips)
		  {
		  	toMarker.oElement.setProperty('title', toMarker.sName)
		  	oTooltip.addTooltipEvents(toMarker.oElement);
		  	oTooltip.tipOver(event, toMarker.oElement);
  		}
  	}
	},

	hidePoiInfo : function(toMarker)
	{
		if (typeof(oTooltip) != 'undefined' && this.options.bTooltips)
		{
			oTooltip.tipOut();
		}
	},

	highlightPoi : function(oPoiMarker)
	{
		if ($chk(this.oHighlightedPoi))
		{
			sImageSource = (this.bPngToGif) ? this.options.aPoiImages.def.src.replace(/\.png/g, '.gif') : this.options.aPoiImages.def.src;
			this.oHighlightedPoi.set('src', sImageSource);
			iXPos = this.oHighlightedPoi.retrieve('orgleft') - (this.options.aPoiImages.def.width / 2).round();
			iYPos = this.oHighlightedPoi.retrieve('orgtop')  - (this.options.aPoiImages.def.height / 2).round();
			this.oHighlightedPoi.setStyles({'left' : iXPos, 'top' : iYPos, 'width' : this.options.aPoiImages.def.width, 'height' : this.options.aPoiImages.def.height, 'z-index' : 5});
		}
		oPoiMarker = $(oPoiMarker);
		if (!oPoiMarker) return;
		this.oHighlightedPoi = oPoiMarker;
		oPoiMarker.setStyle('visibility', 'hidden');
		sImageSource = (this.bPngToGif) ? this.options.aPoiImages.highlight.src.replace(/\.png/g, '.gif') : this.options.aPoiImages.highlight.src;
		oPoiMarker.set('src', sImageSource);
		iXPos = oPoiMarker.retrieve('orgleft') - (this.options.aPoiImages.highlight.width / 2).round();
		iYPos = oPoiMarker.retrieve('orgtop')  - (this.options.aPoiImages.highlight.height / 2).round();
		oPoiMarker.setStyles({'left' : iXPos, 'top'  : iYPos, 'z-index' : 6, 'width' : this.options.aPoiImages.highlight.width, 'height' : this.options.aPoiImages.highlight.height, 'visibility' : 'visible'});
		window.scrollTo(0, 0); //Scroll to top of page
	},

	//Hum getCoordinates en getPosition werken niet goed onder IE6. padding en margin van body worden niet meegenomen, dan maar zo
	getImageCoords : function(oImage)
	{
	  var x = 0;
	  var y = 0;
		var iBorderWidth = 0;
	  //Get map border width
	  if (typeof document.defaultView != "undefined" && typeof document.defaultView.getComputedStyle != "undefined")
			sBorderWidth = document.defaultView.getComputedStyle(oImage, "").getPropertyValue('border-left-width');
		else if (typeof oImage.currentStyle != "undefined")
			sBorderWidth = oImage.currentStyle.borderWidth;
		else
			sBorderWidth = oImage.style.borderWidth;

	  if (sBorderWidth.length > 0)
	  	iBorderWidth = parseInt(sBorderWidth.substring(0, 1));
		if (isNaN(iBorderWidth))
			iBorderWidth = 0;

		x = x + iBorderWidth;
		y = y + iBorderWidth;

	  do {
	    x += oImage.offsetLeft;
	    y += oImage.offsetTop;
	  }
	  while (oImage = oImage.offsetParent);

	  return {x: x, y: y};
	}
});

var DynamicMap = new Class({
	Extends: Map,
	Implements: [Options],

	ptvmap: null,
	mapElement: null,
	locations: new Array(),
	waitPopup: null,
	mapSize: null,
	initialZoomLevel: null,
	Binds: ['focusRow', 'reverseRoute', 'displayRoute'],

	options: {
		mapBoundaries: null
	},

	initialize: function(mapElement, options)
	{
		this.mapElement = $(mapElement);

		this.setOptions(options);

		//XServer is not available
		if(!$defined(com))
		{
			this.mapElement.set('html', translations[35777]);
			return;
		}

		this.showWait();

		//this.mapSize = this.mapElement.getSize();

		this.ptvmap = new com.ptvag.webcomponent.map.Map(this.mapElement);

		if (this.options.mapBoundaries != null)
		{
			var point1 = this._getSuPoint(this._createPoint(this.options.mapBoundaries.left, this.options.mapBoundaries.top));
			var point2 = this._getSuPoint(this._createPoint(this.options.mapBoundaries.right, this.options.mapBoundaries.bottom));
			this.ptvmap.setRect(point1.x, point1.y, point2.x, point2.y, true);
		}
		else
		{
			this.ptvmap.setRect(4303500, 5495900, 4304200, 5495200);
		}

		this.ptvmap.getLayer('background').setShowTileBoundaries(false);
		this.ptvmap.getLayer('label').setEnabled(true);
		this.ptvmap.getLayer('vector').setEnabled(true);
		this.ptvmap.getLayer('toolbar').setEnabled(false);
		//this.ptvmap.setAnimate(true);
		//this.ptvmap.getLayer('overview').setEnabled(true);

		this.initialZoomLevel = this.ptvmap.getZoom();
		this.ptvmap.addEventListener('changeZoom', this.changeZoomListener.bind(this));

		this.options.aMarkers.each(function(oMarker, iIndex)
		{
			this.addPoi(oMarker);
		}.bind(this));

		this.hideWait();
	},

	enlargeMap: function()
	{
		var mapCoords = this.mapElement.getCoordinates();
		this.mapElement.setStyles({
			'width': 572,
			'height': 550,
			'position': 'absolute',
			'z-index': 99,
			'top' : mapCoords.x,
			'left' : mapCoords.y
		});
		window.addEvent('keydown', function(e) {
			if (e.key == 'esc')
			{
				this.dockMap();
			}
		}.bind(this));
		this.ptvmap.getLayer('overview').setEnabled(false);
		this.ptvmap.updateSize();
	},

	dockMap: function()
	{
		this.mapElement.setStyles({
			'width': 360,
			'height': 280,
			'position': 'relative'
		});
		this.ptvmap.getLayer('overview').setEnabled(false);
		this.ptvmap.updateSize();
	},

	addPoi: function(toMarker)
	{
		var point = this._getSuPoint(this._createPoint(toMarker.fLongitude, toMarker.fLatitude));
		var identifier = toMarker.sElementID;
		var img = this.options.aPoiImages.def.src;
		//this.removePoi(identifier);

		var layer = this.ptvmap.getLayer('vector');
		if (layer.elementExists(identifier))
		{
			layer.hideElement(identifier);
		}
		else
		{
			var popupHTML = toMarker.sName + '<br /><a href="'+toMarker.sUrl+'">naar camping</a>';
			var marker = new com.ptvag.webcomponent.map.vector.POI(point.x, point.y, img, com.ptvag.webcomponent.map.layer.VectorLayer.ALIGN_MID_HORIZ + com.ptvag.webcomponent.map.layer.VectorLayer.ALIGN_MID_VERT, null, popupHTML, null, identifier);
			infoBox = marker.createInfoBox();
			marker.createVisibleElement();
			layer.addElement(marker);
		}
	},

	removePoi: function(identifier)
	{
		this.ptvmap.getLayer('vector').removeElement(identifier);
	},

	highlightPoi : function(identifier)
	{
		/*$chk(this.oHighlightedPoi)
		{
			this.oHighlightedPoi.set({url:this.options.aPoiImages.def.src});
			this.oHighlightedPoi.refresh();
		}*/
		var marker = this.ptvmap.getLayer('vector').getElement(identifier);
		marker.set({url:this.options.aPoiImages.highlight.src})
		marker.refresh();
		//this.oHighlightedPoi = marker;
	},

	changeZoomListener: function(event)
	{
		event.stopPropagation();
		event.preventDefault();
		if (this.ptvmap.getZoom() > this.initialZoomLevel)
		{
			//console.log('doe iets, cancel event ofzo');
		}
	},

	showWait: function()
	{
		if(this.waitPopup == null)
		{
			this.waitPopup = new PopUp('<img class="wait" src="images/pleasehold.gif" alt="Please wait"/>', {width: 49, height: 49});
		}

		this.waitPopup.showPopup();
	},

	hideWait: function()
	{
		this.waitPopup.hidePopup();
	},

	/**
	 * Utilitie methods below
	 */
	_getSuPoint: function(point)
	{
		return com.ptvag.webcomponent.map.CoordUtil.geoDecimal2SmartUnit(point);
	},

	_createPoint: function(longitude, latitude)
	{
		var point = {
			x: parseFloat(longitude) * 100000,
			y: parseFloat(latitude) * 100000
		};

		return point;
	}
});

var RoutePlannerMap = new Class({
	Extends: DynamicMap,

	descriptionElement: null,
	startLocation: null,

	initialize: function(mapElement, descriptionElement)
	{
		this.parent(mapElement);

		this.descriptionElement = $(descriptionElement);
		this.descriptionElement.setStyle('display', 'none');
	},

	setStartLocation: function(location)
	{
		this.startLocation = location;
		this.setStartPoint(location.longitude, location.latitude);
	},

	setStartPoint: function(longitude, latitude)
	{
		this.clearRoute();
		this.addPoi(this._createPoint(longitude, latitude), "startPoint", '/maps/green_flag.gif');
		this.focusMap();
	},

	clearStartPoint: function()
	{
		this.startLocation = null;
		this.clearRoute();
		this.focusMap();
	},

	getLocationList: function()
	{
		var totalList = new Array();
		if(this.startLocation != null)
		{
			totalList.push(this.startLocation);
		}

		this.locations.each(function(location){
			totalList.push(location);
		});
		return totalList;
	},

	clearEndPoint: function()
	{
		this.endPoint = null;
		this.clearRoute();
		this.focusMap();
	},

	displayRoute: function(reverseRoute)
	{
		if(this.locations.length > 0 && this.startLocation != null)
		{
			if (!$defined(reverseRoute)) reverseRoute = false;

			// Show waiting bubble
			this.showWait();
			this.clearRoute();

			// Fetch profil
			var profile;
			$$("input[name='traficProfile']", 'address').each(function(radio){
				if(radio.get('checked'))
					profile = radio.get('value');
			});

			var from = JSON.encode(this.startLocation);
			var to = JSON.encode(this.locations);
			if(reverseRoute)
			{
				var lastLocation = this.locations.pop();
				this.locations.push(lastLocation);
				from = JSON.encode(lastLocation);
				var locations = new Array();
				locations.push(this.startLocation);
				to = JSON.encode(locations);
			}


			// Request route
			new Request.JSON({
				url: 'router.php',
				method: 'get',
				onSuccess: function(json) {
					if(!$defined(json) || !$defined(json.nodes) || !$defined(json.description))
					{
						// Hide waiting bubble
						this.hideWait();
						announce(translations[35777]);
					}

					// Draw route
					var points = new Array();
					json.nodes.each(function(node){
						points.push(this._getSuPoint(this._createPoint(node.x, node.y)));
					}.bind(this));

					this.ptvmap.getLayer('vector').addElement(
						new com.ptvag.webcomponent.map.vector.Line('rgba(10,10,255,0.5)', 10, points, null, 'route')
					);

					// Create description
					this.renderDescription(json.description);

					// Show totals
					this.descriptionElement.getElement('#totals .time').set('html', json.totals.time);
					this.descriptionElement.getElement('#totals .distance').set('html', json.totals.distance + " km");

					// Hide waiting bubble
					this.hideWait();

				}.bind(this),
				onFailure: function() {
					this.hideWait();
				}.bind(this)
			}).send(new Hash({
				'from': from,
				'to': to,
				'profile': profile,
				'languageID': languageID
			}).toQueryString());
		}
	},

	reverseRoute: function()
	{
		if(!$defined(this.ptvmap)) return;
		if(!$defined(this.startLocation) || this.locations.length == 0)
		{
			return;
		}

		this.displayRoute(true);
	},

	renderDescription: function(description)
	{
		var stepTemplate = this.descriptionElement.getElement('.steps');
		if(this.stepTemplate == null)
		{
			this.stepTemplate = stepTemplate.clone();
		}
		else
		{
			var newTemplate = this.stepTemplate.clone();
			newTemplate.replaces(stepTemplate);
			stepTemplate = newTemplate;
		}

		stepTemplate.autoRender(description);

		// Bind focus on click events
		var i = 0;
		this.descriptionElement.getElement('.steps').getElements('.context').each(function(contextRow){
			contextRow.addEvent('click', this.focusRow);
			contextRow.addEvent('mouseout', function(event){
				$(new Event(event).target).getParent('tr').removeClass('hover');
			});
			contextRow.addEvent('mouseover', function(event){
				$(new Event(event).target).getParent('tr').addClass('hover');
			});

			// Add odd or even class
			contextRow.addClass((i++ % 2 ? 'even' : 'odd'));

			// Remove empty pictures
			contextRow.getElements('img').each(function(imgElement){
				if(!$defined(imgElement.get('src')) || imgElement.get('src') == '')
				{
					imgElement.destroy();
				}
			});
		}.bind(this));


		this.descriptionElement.setStyle('display', '');
	},

	focusRow: function(event)
	{
		var row = $(new Event(event).target).getParent('tr');
		var point = this._getSuPoint(this._createPoint(
			row.getElement('.longitude').get('html'),
			row.getElement('.latitude').get('html')
		));

		this.ptvmap.setCenter(point);
		this.ptvmap.setZoom(6);

		// scrool to element
		new Fx.Scroll(window).toElement(this.mapElement);
	},

	clearRoute: function()
	{
		if(!$defined(this.ptvmap)) return;
		this.ptvmap.getLayer('vector').removeElement('route');
	}
});

var AutoAddressComplete = new Class({
	Implements: [Events],
	Binds: ['eachFormElement', 'hook', 'filterAddress', 'updateSelectAddress', 'getAddress', 'proccessAddressSelection', 'showForm', 'setFormData'],
	formElement: null,
	formContainer: null,
	addressSelectContainer: null,
	addressSelectElement: null,
	addressList: null,
	addressSelectLoc: null,

	initialize: function(formContainer, addressSelectElement, addressSelectLoc)
	{
		this.addressSelectContainer = $(addressSelectElement);
		this.formContainer = $(formContainer);
		this.addressSelectLoc = $(addressSelectLoc);

		this.formElement = this.formContainer.getElement('form');

		this.hook(this.formElement);

		this.showForm();
	},

	hook: function (form)
	{
		this.formElement = $(form);
		if(!$defined(this.formElement))
		{
			throw new Error("Could not find form element: " + form + ".");
		}

		if(this.formElement.get('tag') != 'form')
		{
			throw new Error(form + " is not a form element.");
		}

		this.formElement.addEvent('submit', function(event){new Event(event).stop()});
	},

	eachFormElement: function(callback)
	{
		this.formElement.getElements('input, select').each(callback);
	},

	requestCodeOptions: function()
	{
		var requestData = new Hash();
		this.eachFormElement(function(inputElement){
			var inputName = inputElement.get('name');
			if(inputElement.get('value'))
			{
				requestData.set(inputName, inputElement.get('value'));
			}
		});

		if(requestData.getLength() > 0)
		{
			requestData.set('languageID', languageID);
			new Request.JSON({
				method: 'get',
				url: 'geocode.php',
				data: requestData,
				onSuccess: function(json)
				{
					if(json.length == 0)
					{
						announce(translations[722]);
					}
					else
					{
						this.filterAddress(json);
					}
				}.bind(this)
			}).send();
		}
	},

	filterAddress: function(addressList)
	{
		if(addressList.length == 0)
		{
			fireEvent('updateAddress', null);
			return;
		}

		if(addressList.length == 1)
		{
			this.setFormData(addressList[0]);
			return;
		}

		this.showAddressSelector(addressList);
	},

	showAddressSelector: function(addressList)
	{
		this.addressList = new Array();
		var selectElement = this.getAddressSelectElement();
		selectElement.empty();
		addressList.each(function(item){
			var index = this.addressList.push(item) - 1;
			var optionElement = new Element('option', {
				'value': index,
				'html':  item.city + " (" + item.postcode + " - " + item.country + ")"
			});

			// Insert option to the selectable elements
			optionElement.inject(selectElement);

			// add onclick event
			optionElement.addEvent('click', this.proccessAddressSelection);
		}.bind(this));

		this.addressSelectContainer.setStyle('display', '');
		this.addressSelectLoc.setStyle('display', 'none');
		selectElement.focus();
	},

	proccessAddressSelection: function(event)
	{
		// Stop form submit
		if(event.type == 'submit') new Event(event).stop();

		var index = parseInt(this.getAddressSelectElement().get('value'));

		this.setFormData(this.addressList[index]);
	},

	getAddressSelectElement: function()
	{
		if(this.addressSelectElement == null)
		{
			// create form
			var form = new Element('form');
			form.addEvent('submit', this.proccessAddressSelection);
			form.inject(this.addressSelectContainer);

			// Create select element
			this.addressSelectElement = new Element('select', {'class': 'elementSelector', 'multiple': false, 'size': 10});
			this.addressSelectElement.inject(form);

			// Create submit button
			//new Element('input', {'type': 'submit', 'value': translations[731]}).inject(form); // Bereken route
		}

		return this.addressSelectElement;
	},

	getAddress: function()
	{
		this.requestCodeOptions();
	},

	showForm: function()
	{
		this.addressSelectContainer.setStyle('display', 'none');
		this.addressSelectLoc.setStyle('display', '');
	},

	setFormData: function(data)
	{
		// Update form elements
		this.eachFormElement(function(element){
			var name = element.get('name');
			var value = element.get('value');

			if(data[name] != undefined && (!$defined(value) || value == ''))
			{
				element.set('value', data[name]);
			}
		}.bind(this));

		this.fireEvent('updateAddress', data);
		this.showForm();
	}
});

var PopUp = new Class( {
	html :'No HTML defined.',
	contentSpan :null,
	Implements : [ Options, Events ],

	// Default options
	getOptions : function() {
		return {
			width :500,
			height :300,
			ajaxHtml: false,
			closeButton: false,
			requestOptions: {}
		};
	},

	initialize : function(html, options) {
		this.setOptions(this.getOptions(), options);
		this.html = html;

		if(this.options.ajaxHtml) {
			this.updateAjaxHtml(this.options.ajaxHtml);
		}
	},

	updateHtml : function(html) {
		this.html = html;
		if(this.contentSpan != null) {
			this.contentSpan.set('html', html);
		}
	},

	updateAjaxHtml: function(url) {
		this.updateHtml('<img src="/html/images/ajax-loader-big.gif" alt="loading" />');
		// Start loading real content
		new Request.JSON({
			url: url,
			onSuccess: function(data)
			{
				this.updateHtml(data.html);
				this.fireEvent('ajaxHtmlComplete', this);
				this.fireEvent('ajaxHtmlSuccess', this);
			}.bind(this),
			onFailure: function(data)
			{
				this.updateHtml(data);
				this.fireEvent('ajaxHtmlComplete', this);
				this.fireEvent('ajaxHtmlFailed', this);
			}.bind(this)
		}).get(new Hash({request: 'popuphtml'}).extend(this.options.requestOptions));
	},

	dispose : function()
	{
		$('infinityPopUp').destroy();
	},

	showPopup : function() {

		this.showModel();

		size = Window.getSize();

		popUpLeft = size.x / 2 - (this.options.width / 2);

		popUpTop = size.y / 2 - (this.options.height / 2);

		if ($('infinityPopUp') == undefined) {

			size = Window.getSize();
			var infinityPopUp = new Element('div', {
				'class' :'infinityPopUp',
				'id' :'infinityPopUp',
				'styles' : {
					'position' :'absolute',
					'width' :this.options.width,
					'height' :this.options.height,
					'top' :popUpTop,
					'left' :popUpLeft
				}
			});

			infinityPopUp.inject($(document.body));

			this.contentSpan = new Element('div', {
				'class' :'spanContentHTML',
				'html' : '',
				'styles' : {

					'height' : this.options.height + 'px'
				}
			});

			this.contentSpan.inject(infinityPopUp);


		} else {
			$('infinityPopUp').set( {
				'styles' : {
					'display' :'block'
				}
			});
		}

		var scroller = new Fx.Scroll(document.body);
		scroller.toTop();
		this.updateHtml(this.html);
		this.fireEvent('show', this);
	},

	hidePopup : function() {

		if ($('infinityPopUp') != undefined) {
			$('infinityPopUp').set( {
				'styles' : {
					'display' :'none'
				}
			});
		}

		this.hideModel();
		this.fireEvent('hide', this);
	},

	// Show model
	showModel : function() {
		// disable scrollbar
		$(document.body).setStyle('overflow', 'hidden');

		if ($('backgroundModelDiv') == undefined) {

			size = Window.getSize();
			var backgroundModelDiv = new Element('div', {
				'class' :'backgroundModelDiv',
				'id' :'backgroundModelDiv',
				'styles' : {
					'width' :size.x
				}
			});

			backgroundModelDiv.inject($(document.body));

		} else {
			$('backgroundModelDiv').set( {
				'styles' : {
					'display' :'block'
				}
			});
		}
	},

	// Hide model
	hideModel : function() {
		if ($('backgroundModelDiv') != undefined) {
			$('backgroundModelDiv').set( {
				'styles' : {
					'display' :'none'
				}
			});
		}

		// disable scrollbar
		$(document.body).setStyle('overflow', 'auto');

	}
});