
var ppaMapStyles = [
	{
		featureType: "water",
		elementType: "all",
		stylers: [
			{ hue: "#35a1cf" },
			{ saturation: 30 },
			{ lightness: -33 },
			{ visibility: "on" }
		]
	},{
		featureType: "landscape.natural",
		elementType: "all",
		stylers: [
			{ hue: "#7fa255" },
			{ saturation: 19 },
			{ lightness: -49 },
			{ visibility: "on" }
		]
	},{
		featureType: "road",
		stylers: [
		    { visibility: "off" }
	    ]
	},{
		featureType: "poi.park",
		stylers: [
		  	{ visibility: "off" }
		]
	},{
		featureType: "administrative",
		elementType: "labels",
		stylers: [
		  	{ visibility: "off" }
		]
	},{
		featureType: "landscape.man_made",
		stylers: [
		    { visibility: "off" }
	    ]
	}
];

var ppaMapType = new google.maps.StyledMapType(ppaMapStyles, {name: "PPA Map"});

var regionalHousePricesChart;


dojo.require("dojox.charting.Chart");
dojo.require("dojox.charting.DataSeries");
dojo.require("dojox.charting.plot2d.Default");
dojo.require("dojox.charting.plot2d.Columns");
dojo.require("dojox.charting.axis2d.Default");

dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojo.data.ItemFileWriteStore");

dojo.provide("ppa.charting.themes.Map");


dojo.provide('ppa.Map');
dojo.declare('ppa.Map', null, {
	constructor: function(elementID, areaDataURL, options) {
		this.elementID = elementID;
		this.areas = new dojo.data.ItemFileWriteStore({url: areaDataURL});

		// merge with default options
		defaultOptions = {
			zoomControl: true,
			zoom: 5,
			centerPoint: new google.maps.LatLng(54.5, -3.2),
			tooltips: true,
			tooltipStyle: 'small',
			basePath: '/house-prices/'
		};
		this.mapOptions = dojo.mixin(defaultOptions, options);

		this.googleMapOptions = {
			zoom: this.mapOptions.zoom,
			center: this.mapOptions.centerPoint,
			mapTypeControlOptions: {
				mapTypeId: [google.maps.MapTypeId.ROADMAP, 'ppa_map']
			},
			panControl: false,
			zoomControl: this.mapOptions.zoomControl,
		    zoomControlOptions: {
		        style: google.maps.ZoomControlStyle.SMALL,
		        position: google.maps.ControlPosition.LEFT_TOP
		    },
			mapTypeControl: false,
			scaleControl: false,
			streetViewControl: false,
			overviewMapControl: false,
			scrollwheel: false
		};

		this.googleMap = new google.maps.Map(document.getElementById(this.elementID), this.googleMapOptions);

		this.googleMap.mapTypes.set('ppa_map', ppaMapType);
		this.googleMap.setMapTypeId('ppa_map');

		this.overlay = new google.maps.OverlayView();
		this.overlay.draw = function(){};
		this.overlay.setMap(this.googleMap);

		if (this.mapOptions.title && this.mapOptions.title.length > 0) {
			dojo.create('h2', {innerHTML: this.mapOptions.title, className: 'title'}, this.elementID + 'Wrapper');
		}

		this.showAreas();
	},

	mapMessage: function(message) {
		messageContainer = dojo.create('span', {innerHTML: message, className: 'mapMessage'}, this.elementID);
		dojo.style(messageContainer, 'margin-bottom', '-' + (dojo.style(messageContainer, 'height') / 2) + 'px');
	},

	showAreas: function() {
		this.areas.fetch({
			onItem: dojo.hitch(this, function(item, request){
				if (!this.areas.isItem(item)) {
					return;
				}

				// extract coords
				geometry = this.areas.getValues(item, 'geometry');
				if (geometry && geometry.length > 0) {
					polyCoords = [];

					if (geometry.length == 1) {
						// simple polygon (array of coord arrays)
						dojo.forEach(geometry[0], dojo.hitch(this, function(item, index){
							polyCoords.push(new google.maps.LatLng(item[1], item[0]));
						}));
					} else {
						// complex polygon (array of array of coord arrays)
						dojo.forEach(geometry, dojo.hitch(this, function(rawCoords, index) {
							tempCoords = [];
							dojo.forEach(rawCoords, function(item, index){
								tempCoords.push(new google.maps.LatLng(item[1], item[0]));
							});
							polyCoords.push(tempCoords);
						}));
					}

					polygonOptions = {
					    paths: polyCoords,
					    strokeColor: "#FFFFFF",
					    strokeOpacity: 1,
					    strokeWeight: 0.5,
					    fillColor: "#96c763",
					    fillOpacity: 1,
					    areaID: this.areas.getValue(item, this.mapOptions.areaIdentifier),
					    title: this.areas.getValue(item, 'name')
					}

					if (this.mapOptions.highlightedPoly && this.mapOptions.highlightedPoly == polygonOptions.areaID) {
						polygonOptions.fillColor = "#D9048D";
						polygonOptions.strokeWeight = 0;
					}

					areaPolygon = new google.maps.Polygon(polygonOptions);
					areaPolygon.setMap(this.googleMap);

					// add listeners
					this.addPolyListeners(areaPolygon);
				}
			}),

			onComplete: dojo.hitch(this, function(){
				// hide spinner
				spinner = dojo.byId(this.elementID + 'Spinner');
				if (spinner) {
					dojo.style(spinner, 'display', 'none');
				}
			}),

			onError: dojo.hitch(this, function(err){
				// hide spinner
				spinner = dojo.byId(this.elementID + 'Spinner');
				if (spinner) {
					dojo.style(spinner, 'display', 'none');
				}

				this.mapMessage('An error occurred loading the map data. Please try reloading the page.');

				//console.log('Error!');
				//console.log(err);
			})
		});
	},

	addPolyListeners: function(poly){
	    google.maps.event.addListener(poly, 'mouseover', dojo.hitch(this, function(){
	    	if (this.mapOptions.tooltips) {
	    		if (poly.areaID) {
	    			if (this.mapOptions.tooltipStyle == 'small') {
	    				poly.tooltip = this.createSmallTooltip(poly);

	    			} else if (this.mapOptions.tooltipStyle == 'big') {
				    	var pricesForChart;
				    	var labelsForChart;

				    	queryObject = new Array();
				    	queryObject[this.mapOptions.areaIdentifier] = poly.areaID;

				    	area = this.areas.fetch({
				    		query: queryObject,
				    		onItem: function(item) {
				    			pricesForChart = item.averageHousePrices;
				    			labelsForChart = item.averageHousePriceLabels;
				    		}
				    	});

				    	if (pricesForChart) {
				    		poly.tooltip = this.createBigTooltip(poly, pricesForChart, labelsForChart);
				    	}
	    			}
	    		}
	    	}

	    	poly.setOptions({fillColor: "#ffffff", strokeColor: "#FFFFFF", fillOpacity: 0.8});
	    }));

	    google.maps.event.addListener(poly, 'mouseout', dojo.hitch(this, function(){
	    	if (this.mapOptions.highlightedPoly && this.mapOptions.highlightedPoly == poly.areaID) {
	    		poly.setOptions({fillColor: "#D9048D", strokeColor: "#FFFFFF", fillOpacity: 1, strokeWeight: 0});
	    	} else {
	    		poly.setOptions({fillColor: "#96c763", strokeColor: "#FFFFFF", fillOpacity: 1, strokeWeight: 0.5});
	    	}

	    	if (poly.tooltip) {
		    	if (regionalHousePricesChart) {
		    		regionalHousePricesChart.destroy();
		    	}

	    		dojo.destroy(poly.tooltip.id);
	    	}
	    }));

	    google.maps.event.addListener(poly, 'click', dojo.hitch(this, function(kmlEvent){
	    	if (poly.infoWindow) {
	    		poly.infoWindow.close();
	   	    }

	    	if (poly.areaID) {
		    	var areaShortname;

		    	queryObject = new Array();
		    	queryObject[this.mapOptions.areaIdentifier] = poly.areaID;

		    	area = this.areas.fetch({
		    		query: queryObject,
		    		onItem: function(item) {
		    			areaShortname = item.shortname;
		    		}
		    	});

		    	if (areaShortname) {
		    		window.location.href = this.mapOptions.basePath + areaShortname + '/';
		    	}
	    	}
	    }));
	},

	calculateTooltipPosition: function(poly, tooltip){
		// calculate bounds
		bounds = new google.maps.LatLngBounds();
        paths = poly.getPaths();

        for (var p = 0; p < paths.getLength(); p++) {
        	path = paths.getAt(p);
        	for (var y = 0; y < path.getLength(); y++) {
        		bounds.extend(path.getAt(y));
        	}
        }

		nePoint = this.overlay.getProjection().fromLatLngToContainerPixel(bounds.getNorthEast());
		swPoint = this.overlay.getProjection().fromLatLngToContainerPixel(bounds.getSouthWest());

		tooltipHeight = dojo.style(tooltip, 'height');
		tooltipWidth = dojo.style(tooltip, 'width');

		styleTop = nePoint.y - tooltipHeight - 14;
		if ((styleTop + tooltipHeight) < 0) {
			// put the tooltip below the polygon instead
			styleTop = swPoint.y + 8
		}

		styleLeft = swPoint.x + ((nePoint.x - swPoint.x) / 2) - (tooltipWidth / 2);
		if ((styleLeft + tooltipWidth) < 0) {
			styleLeft = 0;
		}

		return {top: styleTop, left: styleLeft};
	},

	createBigTooltip: function(poly, chartData, labels){
		// create tooltip div and add to wrapper
		tooltip = dojo.create('div', {id: this.elementID + 'Tooltip', className: 'mapTooltip'});
		dojo.create('h3', {innerHTML: poly.title}, tooltip);
		dojo.create('p', {innerHTML: 'Average house prices: trend'}, tooltip);
		dojo.create('div', {id: 'mapChart', style: 'width: 150px; height: 120px;'}, tooltip);
		dojo.create('p', {innerHTML: 'Click on the region for full details'}, tooltip);
		dojo.place(tooltip, this.elementID + 'Wrapper');

		// convert the labels into a format for use in the chart
		chartLabels = [];
		dojo.forEach(labels, function(price, index){
			chartLabels.push({value: (index + 1), text: labels[index]});
		});

		// create bar chart
		regionalHousePricesChart = new dojox.charting.Chart("mapChart");
		regionalHousePricesChart.addAxis("x", {labels: chartLabels});
		regionalHousePricesChart.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, labelFunc: formatAmount});
		regionalHousePricesChart.setTheme(ppa.charting.themes.Map);
		regionalHousePricesChart.addPlot("default", {type: dojox.charting.plot2d.Columns, gap: 6, minBarSize: 13});
		regionalHousePricesChart.addSeries("Prices", chartData);
		regionalHousePricesChart.render();

		// calculate correct position for the tooltip and adjust div
		tooltipPosition = this.calculateTooltipPosition(poly, tooltip);
		dojo.style(tooltip, 'top', tooltipPosition.top + 'px');
		dojo.style(tooltip, 'left', tooltipPosition.left + 'px');

		return tooltip;
	},

	createSmallTooltip: function(poly){
		// create tooltip div and add to wrapper
		tooltip = dojo.create('div', {id: this.elementID + 'Tooltip', className: 'mapTooltip'});
		dojo.create('span', {innerHTML: poly.title}, tooltip);
		dojo.place(tooltip, this.elementID + 'Wrapper');

		// calculate correct position for the tooltip and adjust div
		tooltipPosition = this.calculateTooltipPosition(poly, tooltip);
		dojo.style(tooltip, 'top', tooltipPosition.top + 'px');
		dojo.style(tooltip, 'left', tooltipPosition.left + 'px');

		return tooltip;
	}

});


//var regionalHousePricesChart = null;

var regionalAverages = {};

dojo.ready(function(){
	ppa.charting.themes.Map = new dojox.charting.Theme({
		colors: ['#fff', '#ddd', '#bbb', '#999', '#777', '#555', '#333'],

		chart: {
			fill: "transparent"
		},

		plotarea: {
			fill: "transparent"
		},

		axis:{
			stroke:	{
				color: "#fff",
				width: 1
			},
			tick: {
				color: "#fff",
				position: "center",
				font: "normal normal normal 7pt Helvetica, Arial, sans-serif",	// labels on axis
				fontColor: "#fff", // color of labels
				titleFont: "normal normal normal 8pt Helvetica, Arial, sans-serif",
				titleFontColor: "#fff" // color of labels
			}
		},

		marker: {
			stroke: { width: 0.5 },
			outline: { width: 0.5 },
			font: "normal normal normal 8pt Helvetica, Arial, sans-serif",
			fontColor: "#444"
		}
	});
});

function formatAmount(val) {
	if (val == 0) {
		return '0';
	}

	var parts = [];
	while (val.length > 3) {
		parts.unshift(val.substr(val.length - 3));
		val = val.substr(0, val.length - 3);
	}
	if (val.length > 0) {
		parts.unshift(val);
	}
	val = parts.join(',');
	return '\u00A3' + val;
}



