/**
 * 	Google Maps v3 for D3mls
 * 	@author D3
 *	@version 2.7
 *	@date 2011-7-20
 *	@requires jQuery and Google Maps API
 */

function Map() 
{
	this.initialLocation = null;
	this.divId = null;
	this.divId2 = null;
	this.map = null;
	this.marker = null;
	this.map2 = null;
	this.markers = [];
	this.listings = null;
	this.listingsIterator =0;
	this.infowindow = null;
	this.latLngBounds = null;
	this.pano = null;
	this.zoom = 16;
	this.details = null;
	this.detailLatlng = null;
}

/**
 *	Init maps
 */
Map.prototype.initialize = function (divId,divId2,geolocate,details) 
{		
	if (details)
		this.details = details;
	else
		this.details = {
			name : "Coldwell Banker",
			address: "Rehoboth Beach Office, 20184 Coastal Highway",
			city:"Rehoboth Beach",
			state:"Delaware",
			zip:"19971",
			description:"",
			latitude:38.71315485617035, 
			longitude:-75.08294713850097
		};

	this.divId = divId;
	if (divId2 != null)
		this.divId2 = divId2;

	var detailLatlng;
	if (this.details != null)
		detailLatlng = new google.maps.LatLng(this.details.latitude, this.details.longitude);
	
	this.detailLatlng = detailLatlng;
	var opts = {
		zoom: this.zoom,
		center: detailLatlng,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	//set up main map
	this.map = new google.maps.Map(document.getElementById(divId), opts);

	var marker = new google.maps.Marker({
	  position: detailLatlng, 
	  map: this.map, 
	  title: this.details.name,
	  draggable:false
	}); 

	//marker.setAnimation(google.maps.Animation.BOUNCE);
	this.marker = marker;

	var self = this;
	//set marker and link to popup dialog
	if (divId2 != null)
	{
		google.maps.event.addListener(marker, 'click', function(){
			self._popup(self);
		});
		$("#pushpinLink").bind('click', function(e){
			e.preventDefault();
			self._popup(self);
		});		
	}
	else 
	{
		google.maps.event.addListener(marker, 'click', function() {
				var infowindow = new google.maps.InfoWindow({
					content: d3mls_maps.details.name,
					maxWidth: 150,
					position: marker.getPosition()
				});
				infowindow.open(d3mls_maps.map,marker);
		});
	}

	//geolocate
	if (geolocate)
		this.geolocate();
	else 
		$("#geolocateLink").bind('click', function(e){
			e.preventDefault();
			self.geolocate();
		});			
}

Map.prototype.geolocate = function()
{
	this.initialLocation = new google.maps.LatLng(this.latitude,this.longitude);
	d3mls_main.loadProgressWheel(this.divId);
	this._geolocate();
}

Map.prototype._geolocate = function()
{
	var useragent = navigator.userAgent;
	var browserSupportFlag = new Boolean();
	var self = this;

	if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
		this.map.style.width = '100%';
		this.map.style.height = '100%';
	} /*else {
		this.map.style.width = '600px';
		this.map.style.height = '200px';
	}*/

	// W3C Geolocation
	if(navigator.geolocation) {
		browserSupportFlag = true;
		navigator.geolocation.getCurrentPosition(function(position) {
			self.initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
			drawPolyline();
		}, function() {
			handleNoGeolocation(browserSupportFlag);
		});
	// Google Gears geolocation
	} else if (google.gears) {
		browserSupportFlag = true;
		var geo = google.gears.factory.create('beta.geolocation');
		geo.getCurrentPosition(function(position) {
			self.initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
			drawPolyline();
		}, function() {
			handleNoGeoLocation(browserSupportFlag);
		});
	// no browser geolocation
	} else {
		browserSupportFlag = false;
		handleNoGeolocation(browserSupportFlag);
	}

	function handleNoGeolocation(errorFlag)
	{
		if (errorFlag == true) 
			alert("Geolocation service failed.");
		else
			alert("Your browser doesn't support geolocation. We've placed you near our office.");
		d3mls_main.hideProgressWheel(self.divId);		
	}
	//draw polyline
	function drawPolyline()
	{
		if (self.initialLocation != null)
		{
			//place geolocated marker
			var initialMarker = new google.maps.Marker({
			  position: self.initialLocation, 
			  map: self.map, 
			  title:"My Location",
			  draggable:true
			}); 					
			initialMarker.setAnimation(google.maps.Animation.BOUNCE);

			//draw polyline between geolocation and property
			var polylineCoordinates = [
				self.initialLocation,
				self.detailLatlng
			];
			var polylinePath = new google.maps.Polyline({
				path: polylineCoordinates,
				strokeColor: "#FF0000",
				strokeOpacity: 1.0,
				strokeWeight: 2
			});
			polylinePath.setMap(self.map);

			//reset boundary
			var latLngBounds = new google.maps.LatLngBounds(self.detailLatlng);
			latLngBounds.extend(initialMarker.getPosition());
			self.map.setCenter(latLngBounds.getCenter());
			self.map.fitBounds(latLngBounds);
			d3mls_main.hideProgressWheel(self.divId);		
		}			
	}
}

Map.prototype.setListings = function(listings)
{
	if (this.markers != null && this.markers.length>0){
		for (var i=0; i<this.markers.length; i++)
			this.markers[i].setMap(null);
		this.markers = new Array();
	}
	this.listingsIterator = 0;
	this.listings = listings;
}

/**
 *	Input markers on the main map
 *	@param linkType String Currently html|function|functionhtml
 *	@param linkValue String Function name or infowindow content
 *	@param linkArg String Argument if linkType is function or functionhtml
 *	@return dropTime Integer Computed drop time of all markers
 */
Map.prototype.inputMarkers = function(linkType, linkValue, linkArg)
{
	this.latLngBounds = new google.maps.LatLngBounds();
	var self = this;
	this.markerIterator =0;	
	var dropTime = 0;
	for (var i=0; i< this.listings.length; i++)
	{
		dropTime = i*500;
		var detailLatlng = new google.maps.LatLng(this.listings[i].latitude,this.listings[i].longitude);
		this.latLngBounds.extend(detailLatlng);
		setTimeout(function() {
			self._inputMarker(linkType, linkValue, linkArg);
		}, dropTime);
	}
	this.map.setCenter(this.latLngBounds.getCenter());
	this.map.fitBounds(this.latLngBounds);
	return dropTime;
}

Map.prototype._inputMarker = function(linkType, linkValue, linkArg)
{
	//console.log(this.listingsIterator);
	var listing = this.listings[this.listingsIterator];
	this.listingsIterator++;
	var detailLatlng = new google.maps.LatLng(listing.latitude,listing.longitude);
	this.latLngBounds.extend(detailLatlng);
	var marker = new google.maps.Marker({
		position: detailLatlng, 
		map: this.map, 
	    animation: google.maps.Animation.DROP,
		title: listing.address + " " + listing.city + " " + listing.state + " " + listing.zip,
		system_id:listing.system_id,
		draggable:false
	});
	
	this.markers.push(marker);

	var self = this;

	if (this.infowindow == null)
		this.infowindow = new google.maps.InfoWindow();
	switch (linkType){
		case 'html' :
			google.maps.event.addListener(marker, 'click', function() {
				self.infowindow.close();
				self.infowindow.setContent(linkValue);
				self.infowindow.setPosition(detailLatlng);
				self.infowindow.open(self.map,marker);
			});				
			break;
		case 'function' :
			google.maps.event.addListener(marker, 'click', function() {
				eval(linkValue+"(marker, "+ linkArg + ")");
			});
			break;
		case 'functionhtml' :
			var htmlcontent = eval(linkValue+"("+ linkArg + ")");
			google.maps.event.addListener(marker, 'click', function() {
				self.infowindow.close();
				self.infowindow.setContent(htmlcontent);
				self.infowindow.setPosition(detailLatlng);				
				self.infowindow.open(self.map,marker);
			});			
			break;
		default :
			break;
	}
}

/**
 *	Popup dialog with map, panorama, directions
 */
Map.prototype._popup = function(self)
{	/*
	 * Load map
	 */
	var detailLatlng = new google.maps.LatLng(self.details.latitude,self.details.longitude);
	var opts = {
		zoom: self.zoom,
		center: detailLatlng,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		streetViewControl :true
	};

	self.map2 = new google.maps.Map(document.getElementById(self.divId2), opts);
	var marker = new google.maps.Marker({
	  position: detailLatlng, 
	  map: self.map2, 
	  title:self.details.name
	}); 

	/*
	 * Setup street view
	 */
	var panoramaOptions = {
	  position: detailLatlng,
	  pov: {
		heading: 34,
		pitch: 10,
		zoom: 1
	  },
	  visible:false
	};
	self.pano = new google.maps.StreetViewPanorama(document.getElementById("pano"),panoramaOptions);
	self.map2.setStreetView(self.pano);//set pano to respond to pegman

	var sv = new google.maps.StreetViewService();
	sv.getPanoramaByLocation(detailLatlng, 50, function(data, status){

		if (status == google.maps.StreetViewStatus.OK) {
			self.pano.setVisible(true);
		}
	});

	/*
	 * Setup directions
	 */
	var directionsService = new google.maps.DirectionsService();
	var directionsDisplay = new google.maps.DirectionsRenderer();	
	directionsDisplay.setMap(self.map2);
	directionsDisplay.setPanel(document.getElementById("directionsPanel"));

	$("#getDirectionsButton").bind('click',function(){
		var start = $("#getDirectionsInputAddress").val();
		if (start != null)
		{
			var request = {
				origin:start, 
				destination:detailLatlng,
				travelMode: google.maps.DirectionsTravelMode.DRIVING
			};
			directionsService.route(request, function(response, status) {
				if (status == google.maps.DirectionsStatus.OK) {
					directionsDisplay.setDirections(response);
					$("#directionsPanel").show();
				}
			});
		}
	});

	/*
	 * Setup tabs
	 **/
	$("#d3mlsMapsTabs").tabs();
	//check resize when map tab selected
	$('#d3mlsMapsTabs').bind('tabsshow', function(event, ui) {
		switch(ui.panel.id)
		{
			case "d3mlsMapsMap" :
				google.maps.event.trigger(self.map2, 'resize');
				self.map2.setZoom(self.zoom);				
				self.map2.setCenter(detailLatlng, 15);
				break;
			case "d3mlsMapsStreetView" :
				google.maps.event.trigger(self.pano, 'resize');
				break;
		}
	});		
	/*
	 * Setup dialog, respond to resize
	 */
	$("#d3mlsMapsDialog").dialog({
		title:self.details.name,
		minWidth:parseInt($("#d3mlsMapsDialog").css("width")),
		open : function()
		{
			google.maps.event.trigger(self.map2, 'resize');
			self.map2.setZoom(self.zoom);
			google.maps.event.trigger(self.pano, 'resize');
		},
		close : function(){
			//d3mls_maps.map2.clearOverlays();
			//$(d3mls_maps.tabsObj).tabs('select', 0); // on close, switch to first tab so that the dialog map will redraw
		},
		resize : function()
		{
			var dialogWidth = $("#d3mlsMapsDialog").width();
			var dialogHeight = $("#d3mlsMapsDialog").height();
			var tabsWidth = dialogWidth - 20;
			var tabsHeight = dialogHeight - 40;
			var tabPanelWidth = tabsWidth - 20;
			var tabPanelHeight = tabsHeight - 40;
			var tabPanelItemWidth = tabPanelWidth - 20;
			var tabPanelItemHeight = tabPanelHeight - 40;

			$("#d3mlsMapsTabs").css({'width': tabsWidth, 'height': tabsHeight});
			$(".d3mlsMapsTab").css({'width': tabPanelWidth, 'height': tabPanelHeight});
			$(".d3mlsMapsTabContent").css({'width': tabPanelItemWidth, 'height': tabPanelItemHeight});
			google.maps.event.trigger(self.map2, 'resize');
			self.map2.setZoom(self.zoom);
			google.maps.event.trigger(self.pano, 'resize');
		}
	});
}






