/*
 * GoogleMaps
 * 
 * Frank van 't Padje
 * versie 1.0
 * 
 */
var GoogleMaps = new Class({
	Implements: [Events, Options],
		
	options:{
		canvas: {
			id:		'canvas',			// id voor canvas element
			width: 	400,				// breedte voor canvas element
			height: 300					// hoogte voor canvas element
		},
		zoom: {
			level:   11,				// standaard zoomlevel
			control: 'large',			// laat zoomcontrols zien -> false / default / large / small
			min:	 false,				// minimale zoomlevel -> false / num
			max: 	 false				// maximale zoomlevel -> false / num
		},
		center: {
			lat: 	null,				// standaard center lat, bij null wordt de eerste marker gecentreerd
			lng: 	null,				// standaard center lng, bij null wordt de eerste marker gecentreerd
			bounds: false				// centreren op alle markers -> true / false
		},
		map: {
			type:	 	'satellite', 	// soort kaart -> roadmap / hybrid / satellite / terrain
			control: 	'dropdown',  	// control soort kaart -> false / default / dropdown / bar  
			draggable: 	true,	  	 	// map draggable met muis 	
			overview: 	false,	 	 	// overview rechtsonder -> false / opened / closed
			streetview: true		 	// streetview icon weergeven
		},
		cluster: {
			use: false,					// markers clusteren
			gridSize: 5,				// Grid grootte
			style: [
				{
					url: '/img/png/map_pin.png',
					height: 24,
					width: 25,
					anchor: [4, 10],
					textColor: '#ffffff',
					textSize: 9
				}, {
					url: '/img/png/map_pin.png',
					height: 24,
					width: 25,
					anchor: [4, 6],
					textColor: '#ffffff',
					textSize: 9
				}, {
					url: '/img/png/map_pin.png',
					height: 24,
					width: 25,
					anchor: [4, 4],
					textColor: '#ffffff',
					textSize: 9
				}
			]
		},
		infoBox: {
			use: false
		},
		directions: {
			use: 		false,			// routebeschrijving -> true / false
			id:			'directions',	// id voor routebeschrijving element
			type:		'site',			// type direction -> site = routebeschrijving op eigen site / google => printpagina Google Maps openen
			width: 		null,			// breedte voor routebeschrijving element -> 100 / null (neem de breedte van canvas over)
			height: 	'auto',			// hoogte voor routebeschrijving element -> 100 / auto
			formulier: {
				show: 	false,			// laat formulier in voor routebeschrijving
				input:  'inputVan',		// ID van input routebeschrijving
				text:	'Vul hier uw straat en plaats in'
			}
		},
		markers: 	[], 				// [{lat:51.839723, lng:4.241200},{lat:51.839730, lng:4.241295},...]
		icon: 		false 				// standaard icon -> false = standaard Google icon / custom icon = relatief pad ('/img/png/icon.png')
	},
	
	initialize: function(el, options){
		this.setOptions(options);
		
		this.container = el;
		this.container.setStyle('width', this.options.canvas.width);
		
		this.mapOptions = {};
		this.markers = Array();
		if(this.options.center.bounds) this.bounds = new google.maps.LatLngBounds();
		this.geocodeBusy = true;
		
		this.initCanvas();
		if(this.options.directions.use) this.initDirections();
		
		if(this.options.cluster.use){
			this.cluster = new MarkerClusterer();
			this.cluster.setGridSize(this.options.cluster.gridSize);
			this.cluster.setStyles(this.options.cluster.style);
		} 
		
		if (this.options.infoBox.use) {
			var container = new Element('div', {
				'class': 'item'
			});
			this.infoBox = new InfoBox({
				content: container,
				disableAutoPan: false,
				maxWidth: 0,
				pixelOffset: new google.maps.Size(12, -25),
				zIndex: null,
				closeBoxMargin: "5px",
				closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
				infoBoxClearance: new google.maps.Size(1, 1),
				isHidden: false,
				pane: "floatPane",
				enableEventPropagation: false
			});
			this.infoBox.container = container;
		}
		
		this.createMap();
		this.setMarkers();
		
		this.setMapCenter();
		
	},
	
	initCanvas: function(){
		this.element = new Element('div', {
			'id': this.options.canvas.id,
			styles: {
				'width':  this.options.canvas.width,
				'height': this.options.canvas.height
			}
		}).inject(this.container);
	},
		
	setMapType: function(){
		switch(this.options.map.type){
			case 'hybrid': 		var type = google.maps.MapTypeId.HYBRID; break;
			case 'satellite': 	var type = google.maps.MapTypeId.SATELLITE; break;
			case 'terrain': 	var type = google.maps.MapTypeId.TERRAIN; break;
			default: 			var type = google.maps.MapTypeId.ROADMAP; break;
		}
		
		this.mapOptions.MapTypeId = type;
	},
	
	setMapTypeControl: function(){
		switch(this.options.map.control){
			case 'dropdown': var style = google.maps.MapTypeControlStyle.DROPDOWN_MENU ; break;
			case 'bar': 	 var style = google.maps.MapTypeControlStyle.HORIZONTAL_BAR ; break;
			default: 		 var style = google.maps.MapTypeControlStyle.DEFAULT ; break;
		}
		
		this.mapOptions.mapTypeControlOptions = {  
			style: style  
		};
	},
	
	setMapZoomControl: function(){
		switch(this.options.zoom.control){
			case 'large': var style = google.maps.ZoomControlStyle.LARGE ; break;
			case 'small': var style = google.maps.ZoomControlStyle.SMALL ; break;
			default: 	  var style = google.maps.ZoomControlStyle.DEFAULT ; break;
		}
		
		this.mapOptions.zoomControlOptions = {  
			style: style  
		};
	},
	
	setMapCenter: function(){
		if(this.options.center.bounds && !this.bounds.isEmpty()){
			this.map.fitBounds(this.bounds);
		}else if(this.options.center.lat != null && this.options.center.lng != null){
			// latlng van options pakken
			this.map.setCenter(new google.maps.LatLng(this.options.center.lat, this.options.center.lng));
		}else if(this.markers.length > 0){
			// latlng van de eerste marker pakken
			this.map.setCenter(this.markers[0].position);
		}
	},
	
	setMapOverview: function(){
		if(this.options.map.overview){
			switch(this.options.map.overview){
				case 'opened': var opened = true; break;
				default: 	   var opened = false; break;
			}
			
			this.mapOptions.overviewMapControl = true;
			this.mapOptions.overviewMapControlOptions = {  
				opened: opened  
			};
		}
	},
	
	createMap: function(){
		
		if(this.options.zoom.min) this.mapOptions.minZoom = this.options.zoom.min;
		if(this.options.zoom.max) this.mapOptions.maxZoom = this.options.zoom.max;
		this.mapOptions.zoom		= this.options.zoom.level;
		this.mapOptions.zoomControl	= (!this.options.zoom.control?false:true);
		
		this.mapOptions.mapTypeControl		= (!this.options.map.control?false:true);
		this.mapOptions.draggable			= this.options.map.draggable;
		this.mapOptions.streetViewControl	= this.options.map.streetview;
		
		this.setMapZoomControl();
		this.setMapType()
		this.setMapTypeControl();
		this.setMapOverview();
		
		this.map = new google.maps.Map(this.element, this.mapOptions);
		if(this.options.cluster.use) this.cluster.setMap(this.map);
	},
	
	setMarkers: function(){
		if(this.options.markers.length > 0){
			this.options.markers.each(function(marker, i){
				this.addMarker(marker,false);
			}.bind(this));
		}
	},
	
	/*
	 * haal de positie op
	 * data = {lat:51.8861739, lng:4.5363513, adres: 'Lijnbaan 17a, Brielle, Nederland'}
	 */
	getPosition: function(data,func){
		if(data.lat != undefined && data.lng != undefined && data.lat != '' && data.lng != ''){
			func(new google.maps.LatLng(data.lat, data.lng));
		}else if(data.adres != undefined){
			if(this.geocoder == undefined) this.geocoder = new google.maps.Geocoder();
			this.geocoder.geocode({'address': data.adres}, function(results, status){
				if(status==google.maps.GeocoderStatus.OK){
					func(results[0].geometry.location)				
				}
			}.bind(this));
			return false;
		}
	},
	
	addMarker: function(data, resetCenter){
		this.getPosition(data, function(result) {
			data.position = result;
			this.createMarker(data,resetCenter)
		}.bind(this));
	},
	
	/*
	 * Marker toevoegen aan map
	 * data = {lat:51.8861739, lng:4.5363513, icon:'icon.png', draggable: false}
	 */
	createMarker: function(data, resetCenter){
		var standaard = { icon: this.options.icon, draggable: false };
		
		// maak marker aan
		var marker = new google.maps.Marker({
			position: data.position,
			map: this.map
		});
		
		// infoWindow
		if(this.options.infoBox.use && data.infoBox != 'undefined'){
			google.maps.event.addListener(marker, 'click', function() {
				this.infoBox.container.set('html', data.infoBox);
				this.infoBox.open(this.map, marker);
			}.bind(this));
		}else if(data.infoWindow != 'undefined'){
			var infowindow = new google.maps.InfoWindow({ content: data.infoWindow });
			google.maps.event.addListener(marker, 'click', function() {
		      	infowindow.open(this.map,marker);
		    });
		}
		
		// icon toevoegen aan marker
		data.icon = (data.icon ? data.icon : standaard.icon);
		if (data.icon) marker.setIcon(data.icon);
		
		// marker draggable maken
		if (data.draggable){
			marker.setDraggable(data.draggable);
			
			google.maps.event.addListener(marker, 'drag', function(){
				this.fireEvent('onDrag', marker.getPosition());
			}.bind(this));
			google.maps.event.addListener(marker, 'dragend', function(){
				this.fireEvent('onDrag', marker.getPosition());
			}.bind(this));
		}
		
		// marker toevoegen aan bounds
		if (this.options.center.bounds) this.bounds.extend(marker.position);
		
		//console.log(marker);
		if(this.options.cluster.use) this.cluster.addMarker(marker,false);
		this.markers.push(marker);
		
		if (resetCenter) this.setMapCenter();
	},
	
	deleteMarkers: function(){
		this.markers.each(function(marker){
			if(this.options.cluster.use) this.cluster.clearMarkers()
			if(this.options.center.bounds) this.bounds = new google.maps.LatLngBounds();
			marker.setMap(null);
		}.bind(this));
		
		this.markers = Array();
	},
	
	initDirections: function(){
		this.directions = {
			display: new google.maps.DirectionsRenderer(),
			service: new google.maps.DirectionsService()
		}
		
		if(this.options.directions.formulier.show){
			var container = new Element('div', {
				'class': 'formulier',
				styles: {
					'width': (this.options.directions.width != null?this.options.directions.width:this.options.canvas.width)
				}
			}).inject(this.container);
			
			var button = new Element('button', {
				'html': 'Bereken route',
				styles: {
					'float': 'right',
					'margin': 0,
					'padding': 0
				},
				events: {
					'click': function(){ 
						if(this.options.directions.type == 'google') this.directions.window = window.open();
						var destination = this.markers[0].position;
						this.getPosition({'adres': input.get('value')}, function(origin) {
							this.getDirections(origin, destination);
						}.bind(this));
						
					}.bind(this)
				}
			}).inject(container);
			
			var input = new Element('input', {
				'id': this.options.directions.formulier.input,
				'value': this.options.directions.formulier.text,
				styles: {
					'width': (container.getSize().x.toInt() - button.getSize().x.toInt() - 6)
				},
				events: {
					'focus': function(){ if(input.get('value') == this.options.directions.formulier.text) input.set('value', ''); }.bind(this),
					'blur': function(){ if(input.get('value') == '') input.set('value', this.options.directions.formulier.text); }.bind(this),
					'keydown': function(ev){
						if(ev.key == 'enter'){
							if(this.options.directions.type == 'google') this.directions.window = window.open();
							var destination = this.markers[0].position;
							this.getPosition({'adres': input.get('value')}, function(origin) {
								this.getDirections(origin, destination);
							}.bind(this));
						}
					}.bind(this)
				}
			}).inject(button, 'before');
		}
		
		this.directions.container = new Element('div', {
			'id': this.options.directions.id,
			styles: {
				'width':  		(this.options.directions.width != null?this.options.directions.width:this.options.canvas.width),
				'height': 		this.options.directions.height,
				'overflow-y': 	'auto',
				'display': 		'none'
			}
		}).inject(this.container);
	},
	
	getDirections: function(origin, destination){
		console.log(origin);
		console.log(destination);
		if(this.options.directions.type == 'site'){
			this.directions.container.setStyle('display', 'block');
			
			this.directions.display.setMap(this.map);
		  	this.directions.display.setPanel(this.directions.container);
			
			var request = {
				origin: origin, 
				destination: destination,
				travelMode: google.maps.DirectionsTravelMode.DRIVING
			};
			this.directions.service.route(request, function(response, status) {
				if (status == google.maps.DirectionsStatus.OK) {
			  		this.directions.display.setDirections(response);
				}else{
					alert('De straat en plaats is niet gevonden.\nProbeer het nog eens.');
				}
			}.bind(this));
		}else if(this.options.directions.type == 'google'){
			var url = 'http://maps.google.nl/maps?f=d&source=s_d&saddr='+origin.Pa+','+origin.Qa+'&daddr='+destination.Pa+','+destination.Qa+'&hl=nl&pw=2';
			this.directions.window.location.href = url;
			
			//console.log(origin);
			//console.log(destination);
		}
	}
});
