var announce = function(message){
	alert(message);
};
window.addEvent("load", function() {
	// Display map
	var map = new RoutePlanningMap('ptvmap', 'description');
	
	var geoData = new AutoAddressComplete('startAddress', 'addressSelection', 'map').addEvent('updateAddress', function(address){
		if(address == null)
		{
			announce("Geen bekende start locatie");
			return;
		}
		
		map.setStartLocation(address);
		map.displayRoute(reverse);
	});
	
	aCampings.each(function(camping){
		map.addLocation(camping);
	});
	map.focusMap();
	
	$('calculate').addEvent('click', geoData.getAddress);
	
	$('print').addEvent('click', function(event){
		new Event(event).stop();		 
				
		if (Browser.ie8 && (Cookie.read('ie8_print_bug_check') != '1'))
		{
			alert(translations[53997]);
			Cookie.write('ie8_print_bug_check', '1');
			return false;
		}
				
		map.addStat('print');
		window.print();
	});
	
	$('reverseDirections').addEvent('click', function(event){
		new Event(event).stop();
		map.displayRoute(true);
	});
});

var RoutePlanningMap = new Class({
	ptvmap: null,
	mapElement: null,
	descriptionElement: null,
	startLocation: null,
	locations: new Array(),
	waitPopup: null,
	Binds: ['focusRow', 'reverseRoute', 'displayRoute'],
	
	initialize: function(mapElement, descriptionElement)
	{
		this.mapElement = $(mapElement);
		this.descriptionElement = $(descriptionElement);
		this.descriptionElement.setStyle('display', 'none');
		
		//var com;
		if(com == undefined)
		{
			this.mapElement.set('html', translations[35777]);
			return;
		}
		
		this.ptvmap = new com.ptvag.webcomponent.map.Map(this.mapElement);
		this.ptvmap.setAllowMouseWheelZoom(false);
		this.ptvmap.getLayer('label').setEnabled(true);
		this.ptvmap.getLayer('vector').setEnabled(true);
		this.ptvmap.getLayer('toolbar').switchToMoveMode();
		this.ptvmap.getLayer('toolbar').setEnabled(false);
	},
	
	setStartLocation: function(location)
	{
		this.startLocation = location;
		this.setStartPoint(location.longitude, location.latitude);
	},
	
	setStartPoint: function(longitude, latitude)
	{
		this.clearRoute();
		this.setPoi(this._createPoint(longitude, latitude), "startPoint", '/maps/green_flag.gif');
		this.focusMap();
	},
	
	clearStartPoint: function()
	{
		this.startLocation = null;
		this.clearRoute();
		this.focusMap();
	},
	
	addLocation: function(location)
	{
		this.locations.push(location);
		this.setPoi(this._createPoint(location.longitude, location.latitude), "camping_" + location.ca, '/maps/tent.gif');
	},
	
	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, more) {
					if(!$defined(json) || !$defined(json.nodes) || !$defined(json.description))
					{
						// Hide waiting bubble
						this.hideWait();
						announce(translations[43572]);
						return;
					}
					
					// Draw route
					var points = new Array();
					var i = 0;
					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')
					);
					/*this.ptvmap.getLayer('vector').showLine(
						'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();
					announce(translations[35777]);
				}.bind(this)
			}).send(new Hash({
				'from': from,
				'to': to,
				'profile': profile,
				'languageID': languageID
			}).toQueryString());
		}
	},
	
	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;
		}
		
		var firstRow = stepTemplate.getElement('.context');
		var rowContainer = firstRow.getParent();
		
		description.each(function(item){
			var row = firstRow.clone();
			row.inject(rowContainer, 'bottom');
			
			var html = row.get('html');
			new Hash(item).each(function (value, key){
				html = html.replace("%" + key + "%", value);
			});
			row.set('html', html);
		});
		firstRow.destroy();
		
		// 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');
	},
	
	setPoi: function(point, name, img)
	{
		if(!$defined(this.ptvmap)) return;
		this.removePoi(name);
		
		point = this._getSuPoint(point);
		
		var layer = this.ptvmap.getLayer('vector');
        var id = "poi_" + name;
                
        layer.showImageMarker(point.x, point.y, img,
            com.ptvag.webcomponent.map.layer.VectorLayer.ALIGN_MID_HORIZ +
            com.ptvag.webcomponent.map.layer.VectorLayer.ALIGN_BOTTOM,
            null, id);
	},
	
	removePoi: function(name)
	{
		if(!$defined(this.ptvmap)) return;
		this.ptvmap.getLayer('vector').removeElement("poi_" + name);
	},
	
	getLocationList: function()
	{
		var totalList = new Array();
		if(this.startLocation != null)
		{
			totalList.push(this.startLocation);
		}
		
		this.locations.each(function(location){
			totalList.push(location);
		});
		return totalList;
	},
	
	focusMap: function()
	{
		if(!$defined(this.ptvmap)) return;
		
		var locations = this.getLocationList();
		
		// no known location
		if(locations.length == 0)
		{
			return;
		}
		
		if(locations.length == 1)
		{
			// center arround the one location
			this.ptvmap.setCenter(this._getSuPoint(this._createPoint(locations[0].longitude, locations[0].latitude)));
			return;
		}
		
		// Set visible rectangle
		var box = {
			left: null,
			right: null,
			top: null,
			bottom: null
			
		};
		
		locations.each(function(location){
			var point = this._getSuPoint(this._createPoint(location.longitude, location.latitude))
			// fetch best left location
			if(point.x < box.left || box.left == null)
			{
				box.left = point.x;
			}
			
			// fetch best right location
			if(point.x > box.right || box.right == null)
			{
				box.right = point.x;
			}
			
			// fetch best top location
			if(point.y > box.top || box.top == null)
			{
				box.top = point.y;
			}
			
			// fetch best bottom location
			if(point.y < box.bottom || box.bottom == null)
			{
				box.bottom = point.y;
			}
		}.bind(this));
		
		// zoom to box
		this.ptvmap.setRect(
			box.left,
			box.top,
			box.right,
			box.bottom
		);
	},
	
	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();
	},
	
	reverseRoute: function()
	{
		if(!$defined(this.ptvmap)) return;
		if(!$defined(this.startLocation) || this.locations.length == 0)
		{
			return;
		}
		
		this.displayRoute(true);
	},
	
	addStat: function(statType)
	{
		// Request route
		new Request.JSON({
			url: 'stats.php',
			method: 'get'
		}).send(new Hash({
			'languageID': languageID,
			'action': statType
		}).toQueryString());
	},
	
	/**
	 * 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 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,
	waitPopup: 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);
			this.showWait();
			new Request.JSON({
				method: 'get',
				url: 'geocode.php',
				data: requestData,
				onSuccess: function(json)
				{
					if(json == null || json.length == undefined || json.length == 0)
					{
						announce(translations[722]);
					}
					else
					{
						this.filterAddress(json);
					}
				}.bind(this),
				onComplete: function()
				{
					this.hideWait();
				}.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
		}.bind(this));
		
		selectElement.addEvent('click', this.proccessAddressSelection);
		this.addressSelectContainer.setStyle('display', '');
		this.addressSelectLoc.setStyle('display', 'none');
	},
	
	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)
			{
				element.set('value', data[name]);
			}
		}.bind(this));
		
		this.fireEvent('updateAddress', data);
		this.showForm();
	},
	
	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();
	}
	
});

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');
		
	}
});
