/** @package eScript */

/**
 * Googlemaps Class - initializes googlemaps
 *
 * @author Mirjam <mirjam@efocus.nl>
 * @author Klaas Dieleman
 * @since 1.1, nov 2010
 * @copyright eFocus
 * @package eFocus js lib
 * @uses GoogleMaps API v3
 * @uses markerclusterer (http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/) with added onComplete option
 */

var GoogleMaps = new Class({

	Implements: [Options],

	options: {
		'mapContainer': false,
		'mapZoom': 10,
		'mapCenter': false,
		'mapMapType': 'google.maps.MapTypeId.ROADMAP',
		'streetView': true,
		'mapMarkerData': null,
		'customIcon': null,
		'customActiveIcon': null,
		'clusterMaxZoom': 10,
		'clusterStyles': [],
		'clusterGridSize': 20,
		'infoWindowClass': null,
		'infoWindowShow': 'click',
		'ajaxLoader': null,
		'showInfoWindow': true,
		'fullScreenMode': false
	},

	initialize: function(options) {

		this.setOptions(options);

		this.mapContainer = this.options.mapContainer;
		this.mapZoom = this.options.mapZoom;
		this.mapCenter = this.options.mapCenter;
		this.mapMapType = this.options.mapMapType;
		this.streetView = this.options.streetView;
		this.mapMarkerData = this.options.mapMarkerData;
		this.customIcon = this.options.customIcon;
		this.customActiveIcon = this.options.customActiveIcon;

		this.clusterMaxZoom = this.options.clusterMaxZoom;
		this.clusterStyles = this.options.clusterStyles;
		this.clusterGridSize = this.options.clusterGridSize;

		this.infoWindowClass = this.options.infoWindowClass;
		this.infoWindowShow = this.options.infoWindowShow;
		this.ajaxLoader = this.options.ajaxLoader;
		this.showInfoWindow = this.options.showInfoWindow;

		this.fullScreenMode = this.options.fullScreenMode;

		this.mapMarkers = new Array();
		this.markerCluster = null;

		this.initializeMap();

	},

	initializeMap: function() {

		if (this.ajaxLoader) this.hideOverlay();

		var latLng = new google.maps.LatLng(this.mapCenter.lat, this.mapCenter.lng);
		var objMapOptions = {
			zoom: this.mapZoom,
			center: latLng,
			mapTypeId: this.mapMapType,
			streetViewControl: this.streetView
		}

		this.map = new google.maps.Map(this.mapContainer, objMapOptions);

		google.maps.event.trigger(this.map, 'resize');
		this.map.setZoom(this.mapZoom);

		if (this.mapMarkerData.length > 0) {
			this.setMarkers();
		}

		if (this.ajaxLoader) google.maps.event.addListener(this.map, 'zoom_changed', function() {

			this.showOverlay();
			if (document.getElement('div.customwindow')) {
				this.openCustomInfoWindow(this.currentInfoWindowEl, this.currentInfoWindowMarker);
			}

			if (this.map.getZoom() <= 0 || this.map.getZoom() >= 15) {
				this.hideOverlay();
			}

		} .bind(this));

	},

	setMarkers: function() {

		this.mapMarkerData.each(function(el) {

			if (this.customIcon) {

				if (this.currentLat && this.currentLng) {
					if (el.lat == this.currentLat && el.lng == this.currentLng) {
						var newMarker = this.getActiveMarker(el);
					} else {
						var newMarker = this.getCustomMarker(el);
					}
				} else {
					var newMarker = this.getCustomMarker(el);
				}

			} else {
				var newMarker = this.getDefaultMarker(el);
			}

			this.mapMarkers.push(newMarker);

			if (el.title) {
				if (this.infoWindowClass) {
					this.addCustomInfoWindow(el, newMarker);
				} else {
					this.addInfoWindow(el, newMarker);
				}
			}

		} .bind(this));

		this.markerCluster = new MarkerClusterer(this.map, this.mapMarkers, {
			maxZoom: this.clusterMaxZoom,
			gridSize: this.clusterGridSize,
			onComplete: function() {
				this.hideOverlay(this);
			} .bind(this)
		});

		this.markerCluster.setStyles(this.clusterStyles);

	},

	positionMap: function(lat, lng) {

		var latLng = new google.maps.LatLng(lat, lng);
		this.currentLat = lat;
		this.currentLng = lng;

		this.map.setZoom(10);
		this.map.panTo(latLng);

	},


	positionMapAddress: function(address) {

		var geocoder = new google.maps.Geocoder();
		geocoder.geocode({ 'address': address }, function(result, status) {
			if (result[0]) {
				this.map.setZoom(5);
				this.map.panTo(result[0].geometry.location);
			}
		} .bind(this));

	},

	positionMapCenterZoom: function(lat, lng, zoom) {

		var latLng = new google.maps.LatLng(lat, lng);
		this.currentLat = lat;
		this.currentLng = lng;

		this.map.setZoom(zoom);
		this.map.setCenter(latLng);

	},

	refreshMarkers: function(markerData) {

		if (this.markerCluster) {
			this.markerCluster.removeMarkers(this.mapMarkers);
		}

		if (this.mapMarkers) {
			for (i in this.mapMarkers) {
				if (typeof (this.mapMarkers[i]) == 'object' && this.mapMarkers[i].name != 'array') {
					this.mapMarkers[i].setMap(null);
				}
			}
			this.mapMarkers.length = 0;
		}

		this.showOverlay();

		this.mapMarkerData = markerData;
		this.setMarkers();

	},

	getDefaultMarker: function(el) {

		var latLng = new google.maps.LatLng(el.lat, el.lng);

		var marker = new google.maps.Marker({
			position: latLng,
			map: this.map
		});

		return marker;

	},

	getCustomMarker: function(el) {

		var latLng = new google.maps.LatLng(el.lat, el.lng);

		var marker = new google.maps.Marker({
			position: latLng,
			map: this.map,
			icon: this.customIcon
		});

		return marker;

	},

	getActiveMarker: function(el) {

		var latLng = new google.maps.LatLng(el.lat, el.lng);

		var marker = new google.maps.Marker({
			position: latLng,
			map: this.map,
			icon: this.customActiveIcon
		});

		return marker;

	},

	addInfoWindow: function(el, marker) {

		marker.infowindow = new google.maps.InfoWindow({
			content: el.info,
			maxWidth: 240
		});

		google.maps.event.addListener(marker, 'click', function() {
			this.mapMarkers.each(function(item, index) {
				if (item.infowindow) item.infowindow.close();
			});
			marker.infowindow.open(this.map, marker);
		} .bind(this));

	},

	addCustomInfoWindow: function(el, marker) {

		google.maps.event.addListener(marker, 'click', function() {
			marker.setIcon(this.customActiveIcon);
			this.openCustomInfoWindow(el, marker);
		} .bind(this));

	},

	closeCustomInfoWindow: function() {

		if (document.getElement('div.customwindow')) {
			document.getElement('div.customwindow').dispose();
		}
	},

	openCustomInfoWindow: function(el, marker) {

		this.closeCustomInfoWindow();

		var infowindow = new google.maps.OverlayView();
		infowindow.setMap(this.map);

		this.currentInfoWindowEl = el;
		this.currentInfoWindowMarker = marker;

		var cIcon = this.customIcon;

		var customInfo;
		var customClass = this.infoWindowClass;

		var customshowInfoWindow = this.showInfoWindow;
		var fullScreen = this.fullScreenMode;

		infowindow.onAdd = function() {

			if (!document.getElement('div.customwindow')) {

				var html = "<h3>" + el.title + "</h3>";
				html += "<p>" + el.onderwijsvormen + "<br/>";
				html += "<span class='location'>" + el.plaats + ", " + el.land + "</span></p>";

				if (customshowInfoWindow == true) {
					html += "<a href='" + el.url + "' class='more'>Meer informatie</a>";
				}
				html += "<span class='close'>X</span>";

				customInfo = new Element('div', {
					'class': 'customwindow',
					html: html
				});

				customInfo.addClass(customClass);
				customInfo.addEvent('click', function() {

				});

				if (customInfo.getElement('a.more')) {
					customInfo.getElement('a.more').addEvent('click', function(e) {
						e.stop();

						// cookie
						var cookieData = this.map.getCenter() + '|';
						cookieData += this.map.getZoom();

						Cookie.write('nob_schools', cookieData);

						if (fullScreen == true) {

							window.opener.location.href = customInfo.getElement('a.more').get('href');
							window.close();

						} else {
							// go to specific page
							window.location = customInfo.getElement('a.more').get('href');

						}

					} .bind(this));
				}


			}

			var panes = this.getPanes();
			panes.overlayImage.appendChild(customInfo);

			if (document.getElement('div.customwindow span.close')) {
				document.getElement('div.customwindow span.close').addEvent('click', function() {
					marker.setIcon(cIcon);
					if (document.getElement('div.customwindow')) {
						document.getElement('div.customwindow').dispose();
					}
				} .bind());
			}

			var overlayProjection = this.getProjection();
			var markerPosition = overlayProjection.fromLatLngToDivPixel(marker.getPosition());

			var overlayPosition = { x: markerPosition.x, y: markerPosition.y };
			customInfo.setStyle('left', overlayPosition.x + 17);
			customInfo.setStyle('top', overlayPosition.y - 52);

			panMap(getOverlayBounds(overlayProjection, overlayPosition));

		};

		infowindow.draw = function() { void (0) };

		infowindow.onRemove = function() {
			customInfo.parentNode.removeChild(customInfo);
			customInfo = null;
		};

		getOverlayBounds = function(overlayProjection, overlayPosition) {

			var overlayPixelBounds = { sw: {}, ne: {} };
			overlayPixelBounds.sw.x = overlayPosition.x - 10;
			overlayPixelBounds.sw.y = overlayPosition.y + customInfo.getSize().y + 10;
			overlayPixelBounds.ne.x = overlayPosition.x + customInfo.getSize().x + 10;
			overlayPixelBounds.ne.y = overlayPosition.y - 10;

			var overlayBounds = new google.maps.LatLngBounds(overlayProjection.fromDivPixelToLatLng(overlayPixelBounds.sw), overlayProjection.fromDivPixelToLatLng(overlayPixelBounds.ne))
			return overlayBounds;

		};

		panMap = function(overlayBounds) {
			this.map.panToBounds(overlayBounds);
		} .bind(this);

	},

	drawTextOnCustomMarker: function(marker, markertext) {

		var customMarkerText = new google.maps.OverlayView();
		customMarkerText.setMap(this.map);

		var markerText;

		customMarkerText.onAdd = function() {

			markerText = new Element('div', {
				'class': 'custommarkertext',
				html: markertext
			});

			var panes = this.getPanes();
			panes.overlayImage.appendChild(markerText);

		}

		customMarkerText.draw = function() {

			var overlayProjection = this.getProjection();
			var markerPosition = overlayProjection.fromLatLngToDivPixel(marker.getPosition());

			markerText.setStyle('z-index', 999);
			markerText.setStyle('left', markerPosition.x - 14);
			markerText.setStyle('top', markerPosition.y - 38);

		}

	},

	resetMap: function() {

		this.closeCustomInfoWindow();

		this.mapMarkers.each(function(item, index) {
			if (item.infowindow) item.infowindow.close();
		});

		var latLng = new google.maps.LatLng(this.mapCenter.lat, this.mapCenter.lng);
		this.map.setCenter(latLng);
		this.map.setZoom(this.mapZoom);

	},

	showOverlay: function() {

		this.ajaxLoader.setStyle('display', 'block');

	},

	hideOverlay: function() {

		this.ajaxLoader.setStyle('display', 'none');

	}

});
