/*
	TheLockUp.com - maps.js
	Maps base functions, requires mootools.js, Google maps v3 script: "http://maps.google.com/maps/api/js?sensor=false", and mootools-more.js (for fx.Scroll)
	11/09/09
	// Note: Closing infowindows seems to cause a memory leak in IE6.
	// This is odd, as it should have the opposite effect by removing the infowindow from the DOM.
	// Not sure how to get around that, but disabling infowindows for IE6 is not yet an option.
*/

var LocationMap = new Class({
	initialize: function(element, options){
		//Use: instancename = new LocationMap( element, {type:string, address:string, latlong:array, windowOpen:boolean, viewOptions:boolean, controlType:string, additional options to pass on to addLocation} );
		/*
			'controlType' string should have one of the following values, or will set to default:
				'small' - 
				'large' - 
				'default' - (default)
		*/
		//Parse options:
		if(!options){options = 'undefined'}
		this.el = element;
		this.type = typeof options.type != 'undefined'? options.type : 'single';
		this.topZ = 200;
		this.markerBounds = new google.maps.LatLngBounds();
		this.infowindow = new google.maps.InfoWindow();
		
		if(typeof options.latlong != 'undefined'){
			this.addMap( new google.maps.LatLng(options.latlong[0], options.latlong[1]), options );
		}else if(typeof options.address != 'undefined'){
			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({address: options.address}, function(results, status){
				if(status == google.maps.GeocoderStatus.OK && results.length){
					this.addMap( results[0].geometry.location, options );
				}
			});
		}else{
			//A center point is required to initialize the map, so if none is provided we will just start out in the center of the Atlantic Ocean.
			//It loads fast with no distracting features, so the potential flicker of this map view won't be confusing.
			this.addMap( new google.maps.LatLng(29.943035391587742, -42.659912109375), options );
		}
	},
	addMap: function(latlong, options){
		//Adds map instance
		//Use: this.addMap({latlong:array, additional options to pass on to addLocation});
		this.zoomlevel = this.type == 'single' ? 14 : 7;
		this.zoomOverride = false;
		if(typeof options.zoom != 'undefined'){this.zoomlevel = options.zoom;this.zoomOverride = true}
		var bwindowOpen = typeof options.windowOpen != 'undefined'? options.windowOpen : false;
		var viewOptions = typeof options.viewOptions != 'undefined'? options.viewOptions : false;
		var controlType = typeof options.controlType != 'undefined'? options.controlType : 'default';
		if(controlType == 'small'){
			controlType = google.maps.NavigationControlStyle.SMALL;
		}else if(controlType == 'large'){
			controlType = google.maps.NavigationControlStyle.ZOOM_PAN;
		}else{
			controlType = google.maps.NavigationControlStyle.DEFAULT;
		}
		
		//Create map instance:
		var myOptions = {
			zoom: this.zoomlevel,
			mapTypeControl: viewOptions,
			navigationControlOptions: {
				style: controlType
			},
			scrollwheel: viewOptions,
			center: latlong,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		this.map = new google.maps.Map(this.el, myOptions);
		
		//If address/etc. passed through init function, pass those to addLocations function:
		if( this.type == 'single' && typeof options.title != 'undefined' && typeof options.address != 'undefined' ){
			if(typeof options.latlong != 'undefined'){
				this.addLocation( { latlong:options.latlong, address:options.address, title:options.title, marker:'single', windowOpen: bwindowOpen } );
			}else{
				this.addLocation( { address:options.address, title:options.title, marker:'single', windowOpen: bwindowOpen } );
			}
		}
	},
	addLocation: function(options){
		//Adds location(s), add markers and infowindows
		/*
			Use: instancename.addLocation( {latlong:array, address:string, title:string, phone:string, url:string, marker:string, number:number, matchElement:object} );
			
			'marker' string should have one of the following values, or will set to default:
				'single' - Full sized marker with TLU icon
				'mini' - (Default) mini marker
				'number' - Numbered markers, used with numbered search results
		}
		*/
		
		
		if(typeof options.latlong != 'undefined'){
			this.addMarker( new google.maps.LatLng(options.latlong[0], options.latlong[1]), options );
		}else{
			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({address: options.address}, function(results, status){
				if(status == google.maps.GeocoderStatus.OK && results.length){
					this.addMarker( results[0].geometry.location, options );
				}
			}.bind(this) );
		}
	},
	addMarker: function(latlong, options){
		this.markerBounds.extend(latlong); 
		//Add marker:
		if(options.marker == 'single'){
			var image = "/images/marker.png";
			var z = 201;
		}else if(options.marker == 'number' && typeof options.number != 'undefined'){
			var image = new google.maps.MarkerImage("/images/marker-" + options.number +".png",
				new google.maps.Size(23, 37),
				new google.maps.Point(4,0),
				new google.maps.Point(14, 37));
			var z = this.topZ - options.number;
		}else{
			var image = "/images/mini-marker.png";
			var z = this.topZ;
			this.topZ--;
		}
		var marker = new google.maps.Marker({
			position: latlong,
			map: this.map,
			icon: image,
			zIndex: z,
			title: options.title
		});
		
		//Create infowindow content:
		var contentString = '<div class="infowindow">'+
			'<strong><span>The Lock Up Self Storage:</span>'+ options.title +'</strong>'+
			'<span class="address">'+ options.address +'</span>'+
			(typeof options.phone != 'undefined'? '<span class="phone">'+ options.phone +'</span>' : '') +
			(options.marker=='single'? '<a href="http://maps.google.com/maps?saddr=&daddr='+ options.address +'" target="_blank" class="link">Get directions</a>' : '<a href="'+ options.link +'" class="link">View this location</a>') +
			'</div>';
		
		if(typeof options.windowOpen != 'undefined' && options.windowOpen){
			var showwindow = function(){
				this.infowindow.setContent(contentString);
				this.infowindow.open(this.map, marker);
				if(this.type !== 'single'){
					this.topZ++;
					marker.setZIndex(this.topZ);
				}
			}.bind(this);
			showwindow.delay(1100);
		}
		
		google.maps.event.addListener(marker, 'click', function(){
			this.infowindow.setContent(contentString);
			this.infowindow.open(this.map,marker);
			if(this.type !== 'single'){
				this.topZ++;
				marker.setZIndex(this.topZ);
			}
		}.bind(this));

		//If map is a multilocation type, fit all markers and center
		if(this.type !== 'single'){
			this.map.fitBounds(this.markerBounds);
			//if(this.zoomOverride){this.map.setZoom(this.zoomlevel)}
			if(this.zoomOverride){
				var tfunc = (function(){ this.map.setZoom(this.zoomlevel) }.bind(this)).delay(250);
			}
		}
		
		//Add events to a specified "matched" element within the page
		if(typeof options.matchElement != 'undefined' && options.matchElement){
			var mel = options.matchElement;
			mel.set('title', 'Show on map');
			mel.addEvent('click', function(e){
				this.infowindow.setContent(contentString);
				this.infowindow.open(this.map,marker);
				if(this.type !== 'single'){
					this.topZ++;
					marker.setZIndex(this.topZ);
				}
				var tempscroll = new Fx.Scroll(window);
				tempscroll.scrollIntoView(this.el);
				tempscroll = null;
			}.bind(this));
		}
	}
});
