var x ;
var ZoneMap = new Class({

		map: {},
		begin: {},
		end: {},
		intersection: {},
		clickListener: {},
		baseIcon: {},
		startIcon: {},
		endIcon: {},
		syntaxLoader: {},

        initialize: function()
        {
			if (!GBrowserIsCompatible()) return false;
			
			//set up icons
			this.baseIcon = new GIcon();
			this.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
			this.baseIcon.iconSize = new GSize(20, 34);
			this.baseIcon.shadowSize = new GSize(37, 34);
			this.baseIcon.iconAnchor = new GPoint(9, 34);
			this.baseIcon.infoWindowAnchor = new GPoint(9, 2);
			this.baseIcon.infoShadowAnchor = new GPoint(18, 25);
	
			this.startIcon = new GIcon(this.baseIcon);
			this.startIcon.image = "http://www.google.com/mapfiles/dd-start.png";
			this.endIcon = new GIcon(this.baseIcon);
			this.endIcon.image = "http://www.google.com/mapfiles/dd-end.png";
			
			this.map = new GMap2($("map_canvas"));
			
			this.map.setCenter(new GLatLng(55.406074,10.391564), 10);
			
			$('messageContainer').setStyle('display','block');
			
			this.clickListener = GEvent.addListener(this.map,'click',(function(overlay, point) {
				// Place markers
				if (this.begin instanceof GMarker == false) {
					this.begin = this.addZoneMarker(point, false);
				} else if (this.end instanceof GMarker == false) {
					this.end = this.addZoneMarker(point, true);
				} else {
					GEvent.removeListener(this.clickListener); // remove when no longer in use
				}
			}).bind(this));
			
			this.map.enableScrollWheelZoom();
			this.map.addControl(new GOverviewMapControl());
			this.map.addControl(new GSmallMapControl());
			
		this.syntaxLoader = new Request({
			url: 'zonemap/ticketsyntax',
				method: 'get',
				autoCancel: true,
				onComplete: this.injectSyntax.bind(this)
			});
        },
        
        addZoneMarker: function(point, isEndMarker) {
        	var marker = new GMarker(point, {
        		draggable: true,
        		icon: isEndMarker ? this.endIcon : this.startIcon
        	});
			this.map.addOverlay(marker);
			GEvent.addListener(marker, 'dragstart', this.map.closeInfoWindow.bind(this.map));
			GEvent.addListener(marker, 'dragend', this.loadZone.pass(marker,this));
		marker.zoneLoader = new Request({
			url: 'zonemap/zone',
				method: 'get',
				autoCancel: true
			});
		marker.zoneLoader.addEvent('success', this.injectZone.pass([marker,marker.zoneLoader],this));
			this.loadZone(marker);
			return marker;
        },
        
        updateIntersection: function()
        {
        	if (this.intersection instanceof GPolyline) this.map.removeOverlay(this.intersection);
        	if (this.begin instanceof GMarker && this.end instanceof GMarker && this.begin.zone instanceof Zone && this.end.zone instanceof Zone) {
        		this.syntaxLoader.options.data = {
        			fromZone: this.begin.zone.id,
        			toZone: this.end.zone.id
        		}
			this.syntaxLoader.send();
        		this.intersection = new GPolyline([this.begin.getPoint(), this.end.getPoint()], '#0000ff', 5, 0.5);
        		this.map.addOverlay(this.intersection);
        	}
        },
        
        injectSyntax: function(text,xml)
        {
			$('messageContent').innerHTML = text;
        },
        
        loadZone: function(marker)
        {
        	marker.zoneLoader.options.data = {
				'latitude': marker.getPoint().lat(),
				'longitude': marker.getPoint().lng()
        	}
		marker.zoneLoader.send();
        },
        
        injectZone: function(marker, zoneLoader) {
			var zone = zoneLoader.response.xml.documentElement;
			var polygons = $A(zone.getElementsByTagName('polygon'));
			
			if (polygons.length == 0 && zoneLoader.response.xml.documentElement.tagName == 'response' && zoneLoader.response.xml.documentElement.getAttribute('success') == 'false') {
				marker.openInfoWindow('<div class="invalidPlacementText">Ugyldig placering af markør, prøv venligst igen.<div class="hint">Tip: Træk i markøren for at flytte position.</div></div>');
				return void(0);
			}
			
			// If polygons were found, remove old polygon and update intersection
			if (polygons.length > 0 && marker.zone) {
				marker.zone.overlays.forEach(function(overlay) {
					this.map.removeOverlay(overlay);
				},this);
        	}
        	
			var overlays = new Array();
			polygons.forEach(function (polygon) {
				var polylines = $A(polygon.getElementsByTagName('polyline'));
				var gpolylines = $A();
				polylines.forEach(function (polyline) {
					this.push({
						points: polyline.getElementsByTagName('points').item(0).firstChild.data,
						levels: polyline.getElementsByTagName('levels').item(0).firstChild.data,
						opacity: 1,
						weight: 3,
						numLevels: 9,
						zoomFactor: 3,
						color: '#5EBA02'
					});
				},gpolylines);
				
				var gpoly =	new GPolygon.fromEncoded({
					polylines: gpolylines,
					fill: true,
					color: "#5EBA02",
					opacity: 0.2,
					outline: true
				});
				
				this.map.addOverlay(gpoly);
				overlays.push(gpoly);
			},this);
			marker.zone = new Zone(zone, overlays);
			this.updateIntersection();
        }
});

var Zone = new Class({
	overlays: {},
	data: {},
	name: '',
	number: NaN,
	id: NaN,
	
	initialize: function(data, overlays) {
		this.data = data;
		this.overlays = overlays;
		this.name = data.getAttribute('name');
		this.number = parseInt(data.getAttribute('number'));
		this.id = parseInt(data.getAttribute('id'));
	}
});

/**
 * Order ticket modal dialog.
 *
 * Must be called from the zone-map as it depends on information it fetches from
 * the DOM, which has been created when two points have been selected.
 */
var OrderTicket = new Class({
	Extends: Dialog,
	options: {
		buttonBar: false,
		dialogClass: 'orderTicket'
	},

	fromZoneNumber: null,
	fromZoneName: null,
	toZoneNumber: null,
	toZoneName: null,
	adultPrice: null,
	childPrice: null,
	groupPrice: null,
	maxPrice: null,

	orderRequest: null,

	/**
	 * When ordering tickets, final dialog will not be shown before at least
	 * two seconds has passed. This helps force that.
	 */
	orderDone: {shownForTwoSecs: false, requestFinished: false},
	

	initialize: function() {
		this.parent();
		this.elemBodyContainer.grab(new Element('div.topback'));
		this.initializeSubmit();
	},

	/**
	 * Prepares Request-object and adds event listener to form submission.
	 */
	initializeSubmit: function() {
		// the request
		this.orderRequest = new Request({
			url: 'ticket/rpcsendsmsticket',
			method: 'post'
		});

		// When ordering-request has finished, show final dialog
		var orderDone = function() {
			this.orderDone.requestFinished = true;
			this.showFinalDialog();
		};
		this.orderRequest.addEvent('success', orderDone.bind(this));
		this.orderRequest.addEvent('failure', orderDone.bind(this));

		// handle submission only in ajax
		this.getForm().addEvent('submit', function(ev) {
			ev.stop();

			this.orderTicket();

			return false;
		}.bind(this));
	},

	/**
	 * Send the order-request to the server.
	 */
	orderTicket: function() {
		this.disableClose();
		this.orderDone = {shownForTwoSecs: false, requestFinished: false};

		var data = {
			ZoneStartOut: this.fromZoneNumber,
			ZoneEndOut: this.toZoneNumber,
			StartTimeOut: 'NOW +14 MINUTES 59 SECONDS',
			TicketType: $('ticketType').getSelected()[0].get('value'),
			PhoneNumber: $('mobileNumber').get('value')
		};

		if ($('ticketType').getSelected()[0].get('value') == 'group') {
			data.Persons = $('groupSize').getSelected()[0].get('value')
		}

		this.orderRequest.send({data: data});

		this.showOrderingScreen();
	},

	/**
	 * When having clicked "order", show this dialog until server has replied and
	 * two seconds has passed since click.
	 */
	showOrderingScreen: function() {
		this.elemBody.empty();

		var outer = new Element('p', {'class': 'oneLineDialog loading', text: 'Bestiller billet, vent venligst.'});
		this.elemBody.adopt([outer, this.getFooter(false)]);

		this.resize();

		// to not make a lot of flicker, ordering screen must show for at least two
		// seconds
		(function(){this.orderDone.shownForTwoSecs = true; this.showFinalDialog()}.delay(2000, this));
	},

	/**
	 * Inform the user how the ordering went.
	 */
	showFinalDialog: function() {
		if (!this.orderDone.shownForTwoSecs || !this.orderDone.requestFinished) return;

		var cls;
		var msg = this.orderRequest.response.text;
		
		switch(this.orderRequest.getHeader('X-Result')) {
			case 'EXCEPTION':
				cls = 'error';
				break;
				
			case 'OK':
				cls = 'success';
				break;

			default:
				cls = 'error';
				msg = 'Der opstod en ukendt fejl. Dit køb er annulleret. Vi beklager!';
				break;
		}

		this.elemBody.empty();
		var content = new Element('p', {'class': 'oneLineDialog '+cls, html: msg});
		this.elemBody.grab(content);
		this.elemBody.grab(this.getFooter());

		this.enableClose();
		this.resize();
	},

	loadData: function() {
		this.fromZoneNumber = $('fromZoneNumber').get('text').trim();
		this.fromZoneName = $('fromZoneName').get('text').trim();
		this.toZoneNumber = $('toZoneNumber').get('text').trim();
		this.toZoneName = $('toZoneName').get('text').trim();
		this.adultPrice = new Number($('adultPrice').get('value').replace(',', '.').trim());
		this.childPrice = new Number($('childPrice').get('value').replace(',', '.').trim());
		this.groupPrice = new Number($('groupPrice').get('value').replace(',', '.').trim());

		this.maxPrice = new Number($('maxPrice').get('value').trim());
	},

	start: function() {
		this.loadData();

		this.setTitle('Køb SMS-billet');

		var content = new Element('div');

		var intro = new Element('p', {'class': 'intro', html: 'Du er nu ved at bestille en <strong>SMS billet</strong><br />fra <strong>{from}</strong> til <strong>{to}</strong>'.substitute({from: this.fromZoneName, to: this.toZoneName})});
		var hereAndNowInfo = new Element('p', {style: 'color: red', 'class': 'intro', html: '<strong>Bemærk:</strong> Billetten du køber er en “her og nu”-billet med begrænset gyldighed. Det er ikke muligt at købe SMS-billetter til bestemte datoer eller tidspunkter.'});
		var smsInfo = new Element('p', {html: 'Nedenunder skal du vælge typen af billet.<br />Indtast dit mobilnummer for at modtage en bekræftelses-sms på din mobiltelefon.'});

		var type = new Element('p');
		type.grab(new Element('label', {text: 'Vælg billettype:', 'for': 'ticketType'}));
		var typeSelect = new Element('select', {name: 'ticketType', id: 'ticketType'}).adopt([
			new Element('option', {value: 'adult', text: 'Voksen'}),
			//new Element('option', {value: 'group', text: 'Voksengruppe'}),
			new Element('option', {value: 'child', text: 'Barn'})
		]);
		type.grab(typeSelect);

		var groupSize = new Element('p', {'class': 'groupSize'});
		groupSize.grab(new Element('label', {text: 'Vælg gruppestørrelse:', 'for': 'groupSize'}));
		groupSize.grab(new Element('select', {id: 'groupSize', name: 'groupSize'}).adopt(this.getGroupSizeOptions()));

		var price = new Element('p');
		price.grab(new Element('label', {text: 'Pris:', style: 'font-weight: bold'}));
		price.grab(new Element('span', {id: 'totalPrice', style: 'font-weight: bold'}));

		var number = new Element('p');
		number.grab(new Element('label', {text: 'Indtast mobilnummer:', 'for': 'mobileNumber'}));
		var numberInput = new Element('input', {id: 'mobileNumber', name: 'mobileNumber', type: 'text', maxlength: 8, size: 10});
		formHandler.limitNumber(numberInput);
		number.grab(numberInput);
		var purchaseBtn = new Element('input', {type: 'submit', value: 'Køb billet', 'class': 'submitBtn', disabled: true});
		number.grab(purchaseBtn);

		numberInput.addEvent('keyup', function() {
			purchaseBtn.set('disabled', numberInput.get('value').length != 8);
		}.bind(this));

		content.adopt([intro, hereAndNowInfo, smsInfo, type, groupSize, price, number, this.getFooter()]);

		this.setBody(content);
		this.elemBody.setStyle('z-index', 1);

		this.updateTotalPrice();
		$$('#groupSize, #ticketType').addEvent('change', this.updateTotalPrice.bind(this));

		this.show();

		typeSelect.addEvent('change', function(sel) {
			groupSize.setStyle('display', sel.target.getSelected()[0].get('value') == 'group' ? 'block' : 'none');
			this.resize();
		}.bind(this));

		this.elemModalClickarea.setStyle('display', 'none');
		this.elemModalClickarea.setStyle.delay(500, this.elemModalClickarea, ['display', 'block']);
	},

	getFooter: function(useLink) {
		var footer = new Element('div', {'class': 'footer'});
		var address = new Element('div', {'class': 'address', html: 'Mvh<br />FynBus<br />Dannebrogsgade 10<br />5000 Odense C'});
		var link = new Element('div', {'class': 'link', html: '<a href="http://www.fynbus.dk/wm141224">Læs mere om SMS-billetten her</a>'});

		var elems = [address];
		if (useLink !== false) elems.push(link);

		footer.adopt(elems);

		return footer;
	},

	updateTotalPrice: function() {
		var type = $('ticketType').getSelected()[0].get('value');
		var price = 0;

		switch(type) {
			case 'adult':
				price = this.adultPrice;
				break;

			case 'child':
				price = this.childPrice;
				break;

			case 'group':
				var groupSize = new Number($('groupSize').getSelected()[0].get('value'));
				price = this.groupPrice * groupSize;
				break;
		}

		var left = Math.floor(price);
		var right = price*100 % 100;
		if (right<10) right = '0'+right;
		$('totalPrice').set('text', 'DKK '+left+','+right);
	},

	getGroupSizeOptions: function() {
		var maxSize = Math.floor(this.maxPrice/100/this.groupPrice);

		var options = [];
		for(var i=2; i<= maxSize; i++) {
			options.push(new Element('option', {value: i, text: i+' personer'}));
		}

		return options;
	},

	/**
	 * Makes the Dialog uncloseable.
	 *
	 * Used to ensuring the user waits for the request to finish, when clicking
	 * "Order ticket".
	 */
	disableClose: function() {
		this.elemModalClickarea.setStyle('display', 'none');
		this.elemCloseBtn.setStyle('display', 'none');
	},

	/**
	 * Makes the Dialog closeable again.
	 */
	enableClose: function() {
		this.elemModalClickarea.setStyle('display', 'block');
		this.elemCloseBtn.setStyle('display', 'block');
	}
});

//quickly enable svg support
_mSvgEnabled = true;
//_mSvgForced = true;

var zonemap;
window.addEvent('load', function() {
	zonemap = new ZoneMap();
});

function getTicket() {
	var orderTicket = new OrderTicket();
	orderTicket.start();
}

//window.addEvent('domready', function() {getTicket()})
