var WMX = WMX || { };

WMX.DealershipMap = Class.create({
	initialize: function(bingMapsDivId, mapToken, dealershipLatitude, dealershipLongitude, pushPinTitle, pushPinDescription, addressTextBoxId, 
	cityTextBoxId, stateTextBoxId, zipCodeTextBoxId, countrySelectId, getDirectionsButtonId, drivingDirectionsPanelId, 
	mapViewTogglePanelId)
	{
		this.oBingMapsDiv = $(bingMapsDivId);
		this.dealershipLatitude = (dealershipLatitude) ? dealershipLatitude : 0;
		this.dealershipLongitude = (dealershipLongitude) ? dealershipLongitude : 0;
		this.mapToken = (mapToken) ? mapToken : '';
		this.map = null;
		this.pushPinTitle = this._EscapeString(pushPinTitle);
		this.pushPinDescription = this._EscapeString(pushPinDescription);
		this.loadingImgSrc = null;
				
		if ((addressTextBoxId || cityTextBoxId || stateTextBoxId || zipCodeTextBoxId || countrySelectId) && (getDirectionsButtonId && drivingDirectionsPanelId))
		{
			this.oAddressTextBox = (addressTextBoxId) ? $(addressTextBoxId) : null;
			this.oCityTextBox = (cityTextBoxId) ? $(cityTextBoxId) : null;
			this.oStateSelect = (stateTextBoxId) ? $(stateTextBoxId) : null;
			this.oZipCodeTextBox = (zipCodeTextBoxId) ? $(zipCodeTextBoxId) : null;
			this.oCountrySelect = (countrySelectId) ? $(countrySelectId) : null;
			this.oGetDirectionsButton = $(getDirectionsButtonId);
			this.oDrivingDirectionsPanel = $(drivingDirectionsPanelId);
			this.oMapViewTogglePanel = (mapViewTogglePanelId) ? $(mapViewTogglePanelId) : null;
			
			this._customerAddress = '';
			this._dealershipAddressVELatLong = null;
			
			if (this.oGetDirectionsButton)
			{	
				this.oGetDirectionsButton.observe('click', this._GetDirections.bind(this));
			}
		}
		
		if (this.oBingMapsDiv)
		{
			this._LoadMap();
		}
	},	
	_AddDealershipPushpin: function()
	{
		if (this.map)
		{
			var shape = new VEShape(VEShapeType.Pushpin, this.map.GetCenter());
		   
			if (this.pushPinTitle != null)
			{
				shape.SetTitle(this.pushPinTitle);
			}
			if (this.pushPinDescription != null)
			{
				shape.SetDescription(this.pushPinDescription);
			}
		               
			this.map.AddShape(shape);
		}
	},
	_AttachMapControlEventHandlers: function()
	{
		if (this.oMapViewTogglePanel)
		{
			var oDealershipMapViewRadioButton = $(this.oMapViewTogglePanel).down('.dealershipMapViewRadioButton');
			if (oDealershipMapViewRadioButton)
			{
				oDealershipMapViewRadioButton.observe('click', this._LoadMap.bind(this)); 
			}
			
			var oDirectionsMapViewRadioButton = $(this.oMapViewTogglePanel).down('.directionsMapViewRadioButton');
			if (oDirectionsMapViewRadioButton)
			{
				oDirectionsMapViewRadioButton.observe('click', this._LoadRouteMap.bind(this));
			}
		}		
		
		var oGetDirectionsButton = $('getDirectionsButton');
		if (oGetDirectionsButton)
		{
			oGetDirectionsButton.observe('click', this._GetDirections.bind(this));
		}							
	},
	_BuildAddress: function(addressToBuild, addressValue, isZipCodeOrCountry)
	{
		var addressPart = ''; 
		if (addressToBuild.length > 0)
		{				  
			if (!isZipCodeOrCountry)
			{
				addressPart = ', ' + addressValue;
			}
			else
			{
				addressPart = ' ' + addressValue;
			}
		}
		else
		{
			addressPart = addressValue;
		}
		return addressPart;	
	},
	_DisplayDirectionsInfoSections: function(display)
	{
		if (this.oDrivingDirectionsPanel)
		{
			this.oDrivingDirectionsPanel.className = (display) ? "drivingDirectionsPanel" : "drivingDirectionsPanel_hidden";
			if (!display)
			{
				var oDirectionsDiv = $('this.oDrivingDirectionsPanel').down('.directions');
				if (oDirectionsDiv)
				{
					oDirectionsDiv.innerHTML = ''; // clear previous search results
      		}
      		this._LoadMap();
			}
		}
		
		if (this.oMapViewTogglePanel)
		{
			this.oMapViewTogglePanel.className = (display && this.oBingMapsDiv) ? "mapViewTogglePanel" : "mapViewTogglePanel_hidden";
		}		
	},
	_DisplayLoadingImage: function(display)
	{
		if ((this.loadingImgSrc) && (this.loadingImgSrc != ''))
		{
			if (!this.loadingImgSpan)
			{
				var spanId = this.oBingMapsDiv.id + "_loadingImage";
				this.loadingImgSpan = new Element('span', {id: spanId, 'class': 'loadingImage_container'});
				$(this.loadingImgSpan).update('<span class="loadingImageText">Loading...</span>');
				
				var loadingImg = new Element('img', {'class': 'loadingImage', 'src': this.loadingImgSrc});
				$(this.loadingImgSpan).insert(loadingImg);
				
				var ancestors = $(this.oGetDirectionsButton).ancestors();
				if (ancestors.length > 1)
				{
					this.loadingImgParentFieldset = ancestors[1];
				}
			}
			
			if (display)
			{
				if (this.loadingImgParentFieldset && this.loadingImgSpan)
				{
					$(this.loadingImgParentFieldset).insert(this.loadingImgSpan);
				}
			}	
			else
			{
				if (this.loadingImgParentFieldset && this.loadingImgSpan)
				{
					$(this.loadingImgSpan).remove();
				}
			}
		}
	},
	_EscapeString: function(value)
	{
		if ((value) && (value.indexOf("\'") < 0) && (value.indexOf("'") > 0))
		{
			return value.replace("'", "\'");
		}											 
		return value;
	},
	_GetCustomerAddress: function()
	{
		var address = '';
		
		if (this.oAddressTextBox && (this.oAddressTextBox.value != ''))
		{
			address += this._BuildAddress(address, this.oAddressTextBox.value, false); 
		}
		
		if (this.oCityTextBox && (this.oCityTextBox.value != ''))
		{
			address += this._BuildAddress(address, this.oCityTextBox.value, false); 
		}
		
		if (this.oStateTextBox && (this.oStateTextBox.value != ''))
		{
			address += this._BuildAddress(address, this.oStateTextBox.value, false); 
		}
		
		if (this.oZipCodeTextBox && (this.oZipCodeTextBox.value != ''))
		{
			address += this._BuildAddress(address, this.oZipCodeTextBox.value, true); 
		}		
			 	
		if (this.oCountrySelect && (this.oCountrySelect.selectedIndex > -1))
		{
			address += this._BuildAddress(address, this.oCountrySelect.options[this.oCountrySelect.selectedIndex].value, true);
		}
				
		return address;
	},
	_GetDirections: function(event)
	{
		Event.stop(event); // stop the event
		
		if (!this.map)
		{
			var aBingMapsDiv = $$(".bingMaps");  // check if a map exists on the page
			if (aBingMapsDiv.length > 0)
			{
				this.oBingMapsDiv = aBingMapsDiv[0];
				this.map = new VEMap($(this.oBingMapsDiv).id);
				this._AttachMapControlEventHandlers();
			}
			else
			{
				// another map does not exists, preload one in an invisible iframe
				var oHiddenIframe = new Element('iframe', {id: 'bingMaps', 'class': 'hidden', 'style': 'position:relative;height:0;overflow:hidden;margin:0;padding:0;border:0;font-size:0;'});
				$(this.oDrivingDirectionsPanel).insert(oHiddenIframe);
				this.map = new VEMap($(oHiddenIframe).id);
			}
			this.map.LoadMap();
		}		
		
		try
		{
			var defaultAltitude = 0;
			this._dealershipAddressVELatLong = new VELatLong(this.dealershipLatitude, this.dealershipLongitude, defaultAltitude, VEAltitudeMode.Default);
			this._customerAddress = this._GetCustomerAddress();
			
			var locations = new Array(this._customerAddress, this._dealershipAddressVELatLong);
			
			var options = new VERouteOptions;
			options.DrawRoute = true;
			options.SetBestMapView = true;
			options.RouteCallback = this._ShowTurns.bind(this);
			options.DistanceUnit = VERouteDistanceUnit.Mile;
			options.ShowDisambiguation = true;
			
			if (this.map)
			{
				this._DisplayLoadingImage(true);
				this.map.GetDirections(locations, options);  
			}
			
			
			var detailsArray = new Array();
			
			
			if (this.oAddressTextBox && (this.oAddressTextBox.value != ''))
			{
				detailsArray[detailsArray.length] = "Address=" + this.oAddressTextBox.value;
			}
			
			if (this.oCityTextBox && (this.oCityTextBox.value != ''))
			{
				detailsArray[detailsArray.length] = "City=" + this.oCityTextBox.value;
			}
			
			if (this.oStateTextBox && (this.oStateTextBox.value != ''))
			{
				detailsArray[detailsArray.length] = "State=" + this.oStateTextBox.value;
			}
			
			if (this.oZipCodeTextBox && (this.oZipCodeTextBox.value != ''))
			{
				detailsArray[detailsArray.length] = "ZipCode=" + this.oZipCodeTextBox.value;
			}		
					
			if (this.oCountrySelect && (this.oCountrySelect.selectedIndex > -1))
			{
				detailsArray[detailsArray.length] = "Country=" + this.oCountrySelect.options[this.oCountrySelect.selectedIndex].value;
			}
			
			createEventWithDetails('Driving Directions','Driving Directions','',detailsArray);
			waPost();
		}
		catch(err)
		{
		}		  		
	},
	// time is an integer representing seconds
	// returns a formatted string
	_GetTime: function(time)
	{
		if(time == null)
		{
			return("");
		}
	   
		var totalSecondsInAMinute = 60;
		if(time > totalSecondsInAMinute)
		{                                 
			var seconds = (time % totalSecondsInAMinute);       
			var minutes = (time - seconds);  
			minutes     = (minutes / totalSecondsInAMinute);    
	      
			var totalMinutesInAHour = 60;
			
			if(minutes > totalMinutesInAHour)
			{                                     
				var minLeft = (minutes % totalMinutesInAHour);        
				var hours   = (minutes - minLeft);   
				hours       = (hours / totalMinutesInAHour);   

				return(hours + " hour(s), " + minLeft + " minute(s), " + seconds + " second(s)");
			}
			else
			{
				return(minutes + " minutes, " + seconds + " seconds");
			}
		}
		else
		{
			return(time + " seconds");
		}
	},
	_LoadMap: function()
	{
		try
		{
			this.map = new VEMap(this.oBingMapsDiv.id);
			this.map.AttachEvent("ontokenerror", this._TokenErrorHandler.bind(this, "The Token is invalid."));
			this.map.AttachEvent("ontokenexpire", this._TokenErrorHandler.bind(this, "The Token is expired."));
			this.map.SetClientToken(this.mapToken);
			this.map.SetDashboardSize(VEDashboardSize.Normal);
			this.map.ShowScalebar();
			
			if ((this.dealershipLatitude != 0) && (this.dealershipLongitude != 0))
			{
				var mapStyle = VEMapStyle.Road;
				var mapMode = VEMapMode.Mode2D;
				var mapIsFixed = false;
				var defaultZoomLevel = 14; // 1 to 19 are valid values; 1 being deepest zoom, 19 being the farthest zoom			
				this.map.LoadMap(new VELatLong(this.dealershipLatitude, this.dealershipLongitude), defaultZoomLevel, mapStyle, mapIsFixed, mapMode);
				
				this._AddDealershipPushpin();
			}
			else
			{
				this.map.LoadMap();
			}
			
			this._AttachMapControlEventHandlers();
			
			this._LoadMissingMapLabels();	
		}
		catch(err)
		{
			alert("Bing Maps Error = " + err);
		}
	},
	_LoadMissingMapLabels: function()
	{
		var oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_FlatlandMapMode');
		this._SetMissingMapLabel(oMapLabelDiv, '2D');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_View3DMapMode');
		this._SetMissingMapLabel(oMapLabelDiv, '3D');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_RoadMapStyle');
		this._SetMissingMapLabel(oMapLabelDiv, 'Road');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_AerialMapStyle');
		this._SetMissingMapLabel(oMapLabelDiv, 'Aerial');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_ObliqueMapView');
		this._SetMissingMapLabel(oMapLabelDiv, 'Bird\'s eye');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_showLabels');
		this._SetMissingMapLabel(oMapLabelDiv, 'Labels');
		
		oMapLabelDiv = $(this.oBingMapsDiv).down('#MSVE_navAction_HybridMapStyle');
		this._SetMissingMapLabel(oMapLabelDiv, 'Hybrid');
	},
	_LoadRouteMap: function()
	{
		if (this.map && this._customerAddress && this._dealershipAddressVELatLong)
		{
			var locations = new Array(this._customerAddress, this._dealershipAddressVELatLong);
			var options = new VERouteOptions;
			options.DrawRoute = true;

			// So the map doesn't change:
			options.SetBestMapView = true;

			// Show as miles
			options.DistanceUnit = VERouteDistanceUnit.Mile;

			// Show the disambiguation dialog
			options.ShowDisambiguation = true;

			this.map.GetDirections(locations, options);	
		}
	},
	_ShowDrivingDirections: function(htmlString)
	{
		var oDirectionsDiv = $(this.oDrivingDirectionsPanel).down('.drivingDirections_container');
		if (oDirectionsDiv)
		{
			this._DisplayDirectionsInfoSections(true);
			oDirectionsDiv.innerHTML = htmlString;
	      
			var oDirectionsMapViewRadioButton = $(this.oMapViewTogglePanel).down('.directionsMapViewRadioButton');
			if (oDirectionsMapViewRadioButton)
			{
				oDirectionsMapViewRadioButton.checked = true;      
			}
		}
	},
	_SetMissingMapLabel: function(oParentDiv, label)
	{
		if (oParentDiv && !oParentDiv.firstChild)
		{
			var oTextNode = document.createTextNode(label);
			oParentDiv.appendChild(oTextNode);
		}
	}, 
	_ShowTurns: function(route)
	{
		var turns = '<div class="directions_header"><span>Turn-by-Turn Directions</span></div>';
		turns += '<div class="directions_disclaimer"><span>(rounding errors are possible)</span></div>';
		turns += '<div class="directionsTotals_header">';
		turns += '<div class="totals_section"><span>Total Trip Distance:</span>' + route.Distance.toFixed(1) + " miles</div>";
		turns += '<div class="totals_section"><span>Total Trip Time:</span>' + this._GetTime(route.Time) + " miles</div>";
		turns += "</div>";
		
		if (route)
		{
			// Unroll route and populate DIV
			var legs = route.RouteLegs;
			var leg = null;
			var turnNum = 0;  // The turn #
			
			for(var i = 0; i < legs.length; i++)
			{
				// Get this leg so we don't have to derefernce multiple times
				leg = legs[i];  // Leg is a VERouteLeg object

				var legNum = i + 1;
				turns += '<div class="leg_header">';  // start of leg header section
				turns += '<div class="header_section"><span class="title">Distance for Leg ' + legNum + ':</span>';
				turns += leg.Distance.toFixed(1) + " miles</div>";
				turns += '<div class="header_section"><span class="title">Time for Leg ' + legNum + ':</span>';
				turns += this._GetTime(leg.Time) + "</div>";
				turns += '</div>'; // end of leg header section
		      
				// Unroll each intermediate leg
				var turn = null;  // The itinerary leg
				var legDistance = null;  // The distance for this leg
		      
				for(var j = 0; j < leg.Itinerary.Items.length; j ++)
				{
					turnNum++;
		         
					turn = leg.Itinerary.Items[j];  // turn is a VERouteItineraryItem object
		         
					turns += '<div class="drivingDirection">'; // start of direction container
					turns += '<div class="directionNumber">' + turnNum + '.</div>';
					turns += '<div class="instruction"><span>' + turn.Text + '</span></div>';
		         
					legDistance = turn.Distance;

					if(legDistance > 0)
					{
						turns += '<div class="distance_time"><span>(';
		                           
						// Round distances to 1/10ths
						turns += legDistance.toFixed(1) + " miles";

						// Append time if found
						if(turn.Time != null)
						{
							turns += "; " + this._GetTime(turn.Time);
						}

						turns += ")</span></div>";
					}
		         
					turns += '<div class="clear"></div>';
					turns += '</div>'; // end of direction container
				}
			}

			// Populate DIV with directions
			this._ShowDrivingDirections(turns);
		}
		else
		{
			this._DisplayDirectionsInfoSections(false);
		}
		
		this._DisplayLoadingImage(false);
	},	
	_TokenErrorHandler: function(errorMessage)
	{
		alert("Token Error = " + errorMessage);
	}
});

