var map, route_finder, route;
var max_zindex = 1000;
var newCenter;
var nearbyCounter = 0;
var nearbyArray = new Array();
var primaryHotel;
var poiCollectionArray = new Array();
var toFromStatus = "to";
var myRouteOptions;
var index = 0;
var results = null;
var placesArray = new Array();
var suggestionsArray;
var navContent = new Array();
var poisBuilt = "false";
var xmlhttp = false;
var proxyServlet = "";
var veTokenURL = "";
var tk = "";
var primaryLatLongFound = "true";

jQuery(document).ready(function(){
	//MULTIMAP INIT

	jQuery('#updatingBlockOverlay').show();
	jQuery('#updatingBlock').show();
	proxyServlet = jQuery('#veServletPath').val();
	veTokenURL = jQuery('#veServletUrl').val();
	var zoomMap = 10;
	if(primaryLatLongFound == "false")
	{
		zoomMap = 1;
	}
	initPoiCollectionArray();
	map = new VEMap( 'mapWindow' );
	callServlet();
	map.AttachEvent('ontokenexpire', MyHandleTokenExpire);
	map.AttachEvent('ontokenerror', MyHandleTokenError);
	map.SetDashboardSize(VEDashboardSize.Small);
	map.LoadMap( newCenter, zoomMap ,'r' ,false);
	myRouteOptions = initializeRouteOptions();
	
	if(primaryLatLongFound == "true")
	{
		//set any rollover and pop-up text]
	    var shape = new VEShape(VEShapeType.Pushpin, newCenter );
	   	var content = document.getElementById('hotelAtrName').innerHTML;
	
	    shape.SetCustomIcon( primaryHotel.Icon );  
	    shape.SetTitle( content );          
	    shape.SetDescription( document.getElementById('hotelInfoDiv').innerHTML );
	    map.AddShape(shape);
	    primaryHotel.Marker = shape;
		//DWR HERE WE GO
		MappingUtils.getPointsOfInterest( primaryHotel.Ctyhocn, 3, { callback:getDwrResultsPoi,  errorHandler:errorPoi } );	
	}
	else
	{
	    document.getElementById("mapItBtn").disabled = true;
	    document.getElementById("mapItBtn").onclick = null;
		jQuery('#updatingBlockOverlay').hide();
	    jQuery('#updatingBlock').hide();
		alert( jQuery('#alertNoMap').val() );
	}


});//end of page load


function MyHandleTokenExpire()
{
   // insert code here to handle token expiration
   alert("Your Mapping Session With Microsoft Has Expired\nPlease Hit Your Browsers Refresh Button To Continue");
}

function MyHandleTokenError()
{
   // insert code here to handle token errors
}	

function getDwrResultsPoi( e ) {
	if((e != 'undefined') && (e != 'null'))
	{
		var tmpA = eval( e );
		//alert( "tmpA is type of " + typeof(tmpA) );
		if(typeof tmpA == "object")	
		{
			navContent = tmpA;
		}
		else
		{
			navContent = new Array();
		}	
	}
	else
	{
		navContent = new Array();
	}

	buildPois();	
}

function errorPoi( e ) {
	if( poisBuilt == "false" )
	{
		buildPois();
	}
}


function initPoiCollectionArray()
{
   for(var i = 0; i < (document.cbForm.poi.length); i++) {
   	 var mqCollection = new Array();
     var collectionType = document.cbForm.poi[i].value;
     var mqObject = { "Type" : collectionType, "PoiCollection" : mqCollection };
     poiCollectionArray[i] = mqObject;
   }
}


function enablePois(  ) {
	//loop through the poi's to see what needs to be shown or hidden
	for (i = 0; i < navContent.length; i++) 
	{
       	var jsonCont = navContent[i];
		if( document.cbForm.poi[jsonCont.TypeIndex].checked )
		{
       		jsonCont.Marker.Show();
       	}
       	else
       	{
       		jsonCont.Marker.Hide();
       	}
   }
}

function buildPois( ) {
	//build the poi's found in our dwr request
	for (i = 0; i < navContent.length; i++) {
	    	createPoi( navContent[i], (i+4), i );
	}
	
	//build the nearbyHotels received from content 
	for (i=0; i < nearbyArray.length; i++)
	{
	  	   createNearbyPoi( nearbyArray[i] );
	}
	
	//turn off our javascript update message
	jQuery('#updatingBlockOverlay').hide();
	jQuery('#updatingBlock').hide();
	
	//once we've built the initial set of poi's no need to re-create  
	poisBuilt = "true";
}

function createNearbyPoi( nrby )
{
	//force our values from the server into floats
	var latti = parseFloat( nrby.Latitude ) + 0.00;
	var longi = parseFloat ( nrby.Longitude ) + 0.00;
	//If we do not get a legit long/lat return
	if(( isNaN( latti ) ) || ( isNaN( longi ) ) )
	{
		return;
	}
 	var headId = "nearby"+nrby.ID;
	var infoId = "info"+nrby.ID;
	var latLon = new VELatLong(latti,longi);
    var shape = new VEShape(VEShapeType.Pushpin, latLon );
	
	shape.SetCustomIcon( nrby.Icon );
	shape.SetTitle( document.getElementById(headId).innerHTML );
	shape.SetDescription( document.getElementById(infoId).innerHTML );
	nrby.Marker = shape;
	map.AddShape(shape);
}

function createPoi(jsonObj, i, originalIndex  ) {
	//force our values from the server into floats
	var longi = parseFloat( (jsonObj.address.latLong.longitude).toFixed(5) ) + 0.00;
	var latti = parseFloat( (jsonObj.address.latLong.latitude).toFixed(5)  ) + 0.00;
	if(( isNaN( latti ) ) || ( isNaN( longi ) ) )
	{
		return;
	}
	
	var content = "";
	content += "<div class=\"mapPopPOIContent vcard\"><span class=\"adr\">" + jsonObj.address.addressLine+ "</span>";
	content += "<span class=\"mapPopPOILocale locale\">" + jsonObj.address.city;
	content += "," + jsonObj.address.postalCode + "," + jsonObj.address.countryCode + "</span></div>";
	content += '<p>'+jQuery('#poiGetDir').val()+'<a href="#" onClick="javascript:doPoiRouting( \'1\',\''+originalIndex+'\' );" >'+jQuery('#poiToHere').val()+'</a>  - ';
	content += '<a href="#" onClick="javascript:doPoiRouting( \'2\',\''+originalIndex+'\' )" >'+jQuery('#poiFromHere').val()+'</a></p>';
	var hd = "<h4 class=\"mapPopPOIName fn org\">" + jsonObj.name + "</h4>";

	
	//Build the Multimap poi
	var latLon = new VELatLong(latti,longi);
    var shape = new VEShape(VEShapeType.Pushpin, latLon );
	var image;

	//so that we don't hard-code our buttons we get the results from skin path of the jsp page
	if(jsonObj.type == "TRAINS")
	{
		image = jQuery('#trainPath').val();
	}
	else if(jsonObj.type == "BUSES")
	{
		image = jQuery('#busPath').val();
	}
	else if(jsonObj.type == "PLANES")
	{
		image = jQuery('#airportPath').val();
	}
	else if(jsonObj.type == "SUBWAY")	
	{
		image = jQuery('#subwayPath').val();
	}
	else if(jsonObj.type == "BOATS")	
	{
		image = jQuery('#ferryPath').val();
	}
	else
	{
		image = jQuery('#genericPath').val();
	}
	var imgTag = '<img width="40" height="40" src="'+image+'" />';
	//now create our shape and add it to the map in a hidden state 
    shape.SetCustomIcon( imgTag );  
    shape.SetDescription( content );
    shape.SetTitle( hd );
    shape.Hide();
    map.AddShape(shape);
	jsonObj.Marker = shape;
	
	//so that we can re-show the icon at a later time save the checkbox index
	//it is associated with so that it can be an atrtibute of the node in the array
	for(l = 0; l < poiCollectionArray.length; l++)
	{
	  var myNode = poiCollectionArray[l];
	  if(jsonObj.type == myNode.Type)
	  {
	  	jsonObj.TypeIndex = l;
	  	l = poiCollectionArray.length;
	  }
	}
}

function doPoiRouting( toFrom, nodeIndex )
{
	var jsonNode = navContent[nodeIndex];
	jQuery('#myResultsDiv').hide();
 	jQuery('#updatingBlockOverlay').show();
    jQuery('#updatingBlock').show();
	
	if(toFrom == 1)
	{		
		if(toFromStatus == "to")
		{
			document.getElementById("directionsFrom").value = document.getElementById("directionsTo").value ;
		}
		document.getElementById("directionsTo").value = jsonNode.name;
		toFromStatus = "from";
	}
	else
	{
		if(toFromStatus == "from")
		{
			document.getElementById("directionsTo").value = document.getElementById("directionsFrom").value ;
		}
		document.getElementById("directionsFrom").value = jsonNode.name;
		toFromStatus = "to";
	}

	document.getElementById("mapItBtn").innerHTML = "<span>"+jQuery('#clearLabel').val()+"</span>";
	callRoute(nodeIndex, "poi");	
}

//function createStepMarker(location, instruction, text, zindex) {
//    var marker = map.createMarker(location, {zIndex: zindex, 'text' : text});
//    marker.setInfoBoxContent('<p>' + instruction + '<' + '/p>');
//}        

function findLoc( index )
{
 	jQuery('#updatingBlockOverlay').show();
    jQuery('#updatingBlock').show();
    try
	{
		var node = placesArray[index];
		document.getElementById("directionsFrom").value = node.Name;
		jQuery('#autoHelpSuggestion').hide();
		document.getElementById("mapItBtn").innerHTML = "<span>"+jQuery('#clearLabel').val()+"</span>";
		cleanUp();
		var start = node.LatLong;
		var end = primaryHotel.Marker.GetPoints();
		var myOptions = initializeRouteOptions();
		map.GetDirections(new Array(start, end[0]), myOptions);
	}catch(e)
	{
		alert('Error name: '+e.name+' desc: '+e.description);		
	}
}

function callRoute (  ctr, arrayType  ) {

	cleanUp();
	
    var addressNode;
    if(arrayType == "nearby")
    {
 	    addressNode = suggestionsArray[ctr];
	}
	else
	{
		addressNode = navContent[ctr];
	}
	
	var ptStart = addressNode.Marker.GetPoints();
	var ptEnd = primaryHotel.Marker.GetPoints();
	if(toFromStatus == "to")
	{
		map.GetDirections([ ptStart[0], ptEnd[0] ], myRouteOptions);
	}
	else
	{
		map.GetDirections([ ptEnd[0], ptStart[0] ], myRouteOptions);
	}
	
}
   
function echoNewHotel(  lat, lon, name, add, city, country, icon, ctyhocn ) {
  //force our longitude and latitude into a float by multiplication
  var latti = parseFloat( lat ) + 0.00;
  var longi = parseFloat ( lon ) + 0.00;
  if(( isNaN( latti ) ) || ( isNaN( longi ) ) )
  {
	 //set up a center somewhere in the middle of the world
  	 latti = 30.00000;
  	 longi = 30.00000;
  	 primaryLatLongFound = "false";	
  }

  //set the center of our map on our primary hotel's longitude and latitude
  newCenter = new VELatLong( latti, longi )

  //build the primaryHotel object and it's attributes
  primaryHotel = { "Ctyhocn" : ctyhocn, "Name" : name, "Longitude" : longi, "Latitude" : latti, "Icon" : icon,  "Address" : add, "City" : city, "Country" : country };
}

function appendNearbyHotel( name, add, country, city, state, zip, icon, latitude, longitude )
{
	//increment our nearby counter
	nearbyCounter++;
	
	//build the nearbyHotel object and it's attributes and add it to the nearbyArray array
	var NearbyHotel = { "Name" : name, "Longitude" : longitude, "Latitude" : latitude, "Icon" : icon, "ID" : nearbyCounter, "Address" : add, "City" : city, "Country" : country };
	var arCtr = nearbyCounter - 1;
	nearbyArray[arCtr] = NearbyHotel;
}

// time is an integer representing seconds
// returns a formatted string
function GetTime(time)
{
   if(time == null)
   {
      return("");
   }

   if(time > 60)
   {                                 // if time == 100
      var seconds = time % 60;       // seconds == 40
      var minutes = time - seconds;  // minutes == 60
      minutes     = minutes / 60;    // minutes == 1


      if(minutes > 60)
      {                                     // if minutes == 100
         var minLeft = minutes % 60;        // minLeft    == 40
         var hours   = minutes - minLeft;   // hours      == 60
         hours       = hours / 60;          // hours      == 1

         return(hours + " " + jQuery('#hourPref').val() + ",  " + minLeft + " " + jQuery('#minPref').val() + ",  " + seconds + " " + jQuery('#secPref').val());
      }
      else
      {
         return(minutes + " " + jQuery('#minPref').val() + ",  " + seconds + " " + jQuery('#secPref').val());
      }
   }
   else
   {
      return(time + " " + jQuery('#secPref').val());
   }
}


function cleanUp () {
	//clear off all existing routes from the map
	map.DeleteRoute();
}

function myRouteHandler(route)
{
   // Unroll route and populate alert text
   var leg           = null;
   var turnNum       = 0;  // The turn #
   var totalDistance = 0;  // The sum of all leg distances
   var legs          = route.RouteLegs;
   var myMinutes     = route.Time;
   var myTotTime     = GetTime( myMinutes );
   var turns = "";

   turns = '<h2 class="destinationDirectionsInstructions">'+jQuery('#routeHdrLabel').val()+'</h2>';
   turns += '<ol class="destinationDirectionsInstructions">';

   // Get intermediate legs
   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

      // 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 is a VERouteItineraryItem object
         turns += '	<li><span class="directionsCommand">';
         turn = leg.Itinerary.Items[j];  
         turns += turn.Text;
         legDistance    = turn.Distance;
         totalDistance += legDistance;

         // Round distances to 1/10ths
         // Note that miles is the default
  		 turns += '</span><span class="directionsTime">'
  		 turns +=  legDistance.toFixed(2) + " " + jQuery('#distPref').val() + " </span></li>";
     	 
     	 //I don't want the shapes to show up on the map, just the route color
      	 map.DeleteShape(leg.Itinerary.Items[j].Shape);
      }
   	}
    turns += "</ol><p>"+jQuery('#driveTime').val() + "  " + myTotTime + "<br />"
    turns += jQuery('#driveDist').val() + " " + totalDistance.toFixed(2) + " " + jQuery('#distPref').val() + "</p>";
	document.getElementById("myResultsDiv").innerHTML = turns;
	jQuery('#myResultsDiv').show();
	jQuery('#updatingBlockOverlay').hide();
   	jQuery('#updatingBlock').hide();	
}	

function getDirections(displayIt,toValue)
{
 	 var directions = "";
	 if(displayIt == "true")
	 {
		 jQuery('#autoHelpSuggestion').hide();
  	}
	else
	{
		var mbtn = "";
		if(document.all){
 		    mbtn = document.getElementById('mapItBtn').innerText;
		} else{
		    mbtn = document.getElementById('mapItBtn').textContent;
		}	
		if( mbtn == jQuery('#clearLabel').val() )
		{
		    if(document.getElementById("autoHelpSuggestion").style.display != "none")
		    {
				jQuery('#autoHelpSuggestion').toggle();
    	 	}
    	 	document.getElementById("mapItBtn").innerHTML = "<span>"+jQuery('#mapItLabel').val()+"</span>";
 		 	jQuery('#myResultsDiv').toggle();
			cleanUp();
		 	if(	toFromStatus == "from")
		 	{
		 		document.getElementById("directionsTo").value = document.getElementById("directionsFrom").value ;
		 	}
		    document.getElementById("directionsFrom").value = "";
		    toFromStatus = "to";
		 }
		 else
		 {
		 	jQuery('#updatingBlockOverlay').show();
		    jQuery('#updatingBlock').show();
            try
            {
               results = map.Find(null,
                                  document.getElementById('directionsFrom').value,
                                  null,
                                  null,
                                  index,
                                  10,
                                  false,
                                  false,
                                  false,
                                  false,
                                  MoreResults);
                index = parseInt(index)+9;
            }
            catch(e)
            {
               errorDidYouMean( null );
            }  	 	 
		  	
 		 }
	}  
  
}

function MoreResults(layer, resultsArray, places, hasMore, veErrorMessage)
{
	placesArray = null;
	if((places != 'null') && (places.length > 0))
	{
		if(places.length == 1)
		{
			placesArray = places;
			findLoc( "0" );
		}
		else
		{
			placesArray = places;
			myDisambiguationCallback( places );
		}
	}
	else
	{
		errorDidYouMean( null );
	}
	
	jQuery('#updatingBlockOverlay').hide();
   	jQuery('#updatingBlock').hide();	
		
}


function myDisambiguationCallback( e ) //DisambiguationCallback
{
    var r='<p class="didYouMean">'+jQuery('#didYouMeanLabel').val()+'</p>';
    r += '<ul>';
    for (x=0; x<e.length; x++)
    {
    	var node = e[x];
        r+="<li><a onclick='findLoc(\""+x+"\");' href='#'>"+node.Name+"</a></li>";
    }

	r += '</ul>';
	r += '<p><a href="javascript:resetDidYouMean()">'+jQuery('#resetDidYouMeanLabel').val()+'</a></p>';
    
    document.getElementById("autoHelpSuggestion").innerHTML=r;
    document.getElementById("autoHelpSuggestion").style.display = "block";
    jQuery('#autoHelpSuggestion').show();
    
}

function resetDidYouMean()
{
	//reset the did you mean by hiding and removing it's elements
	jQuery('#autoHelpSuggestion').hide();
	document.getElementById("directionsFrom").value = "";
}

function errorDidYouMean(e) {

	var inner;
	inner = '<p class="didYouMean">'+jQuery('#addNotFoundLabel').val();
	inner += '</p>';
	inner += '<p/><p><a href="javascript:resetDidYouMean()">'+jQuery('#closeDidYouMeanLabel').val()+'</a></p>';
	document.getElementById("autoHelpSuggestion").innerHTML = inner;
  	jQuery('#autoHelpSuggestion').show();

}

/* Make an AJAX call to the servlet, set servletHandler as the callback function*/
function callServlet()
{
	var veURL = proxyServlet + "?url=" + veTokenURL;
	
    InitXmlHttp();
    xmlhttp.onreadystatechange=servletHandler;    
    xmlhttp.open("GET", veURL, true );
    xmlhttp.send(null);
}

/* Initialize the xmlHttp object */
function InitXmlHttp() {
    // Attempt to initialize xmlhttp object
    try
    {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
        // Try to use different activex object
        try
        {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (E)
        {
            xmlhttp = false;
        }
    }
    // If not initialized, create XMLHttpRequest object
    if (!xmlhttp && typeof XMLHttpRequest!='undefined')
      {     
            xmlhttp = new XMLHttpRequest();
      }
      // Define function call for when Request obj state has changed
      xmlhttp.onreadystatechange=servletHandler;
}

/* Handles and evals the Response from Servlet */
function servletHandler()
{
    if (xmlhttp.readyState==4)
    {
        try
        {
            //Evaluate the response if AJAX call was successful
            //alert("The following VE call was made: " + xmlhttp.responseText);
            map.SetClientToken( xmlhttp.responseText );
        }
        catch (E)
        {            
            alert("error: " + E );
        }
    }
}

function initializeRouteOptions(){
	var options = new VERouteOptions();
	options.UseMWS = false;
	options.SetBestMapView = true; // Don't change map view
	options.RouteCallback = myRouteHandler;  // Gets VERoute
  	options.DistanceUnit = jQuery('#msnUnitPref').val();
	
	return options;
}
