RegisterNamespace('NPR.Stations.Directions');

NPR.Stations.Directions.EndLocation = null;
NPR.Stations.Directions.ResultsElement = null;
NPR.Stations.Directions.RouteSegments = new Array();
NPR.Stations.Directions.RouteSegmentsLoaded = 0;
NPR.Stations.Directions.RouteStationsLoaded = 0;
NPR.Stations.Directions.StartLocation = null;
NPR.Stations.Directions.VERoute = null;

NPR.Stations.Directions.AddArtificialWaypoints = function(routeSegments)
{
    for(var i = 0; i < routeSegments.length - 1; i++)
    {
    	if (routeSegments[i].ArtificialDistance > NPR.Stations.Settings.CreateArtificialWaypointsForDistancesOver)
    	{
    	    var latLong1 = routeSegments[i].VERouteSegment.LatLong;
    	    var latLong2 = routeSegments[i+1].VERouteSegment.LatLong;
    	    var halfDistance = routeSegments[i].ArtificialDistance / 2;
    	    var midpoint = new VELatLong((latLong1.Latitude + latLong2.Latitude) / 2, (latLong1.Longitude + latLong2.Longitude) / 2);
    	    
    	    var artificialWaypoint = new Object();
            artificialWaypoint.Distance = halfDistance;
            artificialWaypoint.LatLong = midpoint;
            artificialWaypoint.Text = 'After driving for about ' + parseInt(halfDistance) + ' ' + NPR.Stations.Settings.DistanceUnit.toString().toLowerCase() + 's...';
            
            var routeSegment = new NPR.Stations.RouteSegment(artificialWaypoint);
            routeSegment.ArtificialDistance = halfDistance;
            routeSegment.IsArtificial = true;
            
            routeSegments[i].ArtificialDistance = halfDistance;
            routeSegments.splice(i + 1, 0, routeSegment);
    	}
    }
}

NPR.Stations.Directions.Clear = function()
{
    map.DeleteRoute();
    map.DeleteAllPushpins();
    
    if(NPR.Stations.Directions.ResultsElement)
    {
        NPR.Stations.Directions.ResultsElement.innerHTML = '';
    }
    
    NPR.Stations.Directions.EndLocation = null;
    NPR.Stations.Directions.ResultsElement = null;
    NPR.Stations.Directions.RouteSegments = new Array();
    NPR.Stations.Directions.RouteSegmentsLoaded = 0;
    NPR.Stations.Directions.RouteStationsLoaded = 0;
    NPR.Stations.Directions.StartLocation = null;
    NPR.Stations.Directions.VERoute = null;	
}

NPR.Stations.Directions.FindEndLocationCallback = function(shapeLayer, findResults, places, moreResults, errorMessage)
{
    if(places.length == 1)
    {
        NPR.Stations.Directions.EndLocation = places[0];
        NPR.Stations.Directions.GetDirectionsWorker();
    }
    else
    {
        var html = '<h4>Did you mean?</h4>';
        html += '<ul class="AmbiguousPlaces">';
        
        for(var i = 0; i < places.length; i++)
        {
            html += '<li><a href="#" onclick="NPR.Stations.Directions.EndLocation = {\'Name\':\'' + places[i].Name + '\', \'LatLong\':new VELatLong(' + places[i].LatLong.Latitude + ', ' + places[i].LatLong.Longitude + ')}; NPR.Stations.Directions.GetDirectionsWorker(); return false;">' + places[i].Name + '</a></li>';
        }
        
        html += '</ul>';
        
        NPR.Stations.Directions.ResultsElement.innerHTML = html;
        
        //Visual Sciences
		//vsPageEvent("didyoumean");        
    }
}

NPR.Stations.Directions.FindStartLocationCallback = function(shapeLayer, findResults, places, moreResults, errorMessage)
{    
    if(places.length == 1)
    {
        NPR.Stations.Directions.StartLocation = places[0];
        NPR.Stations.Directions.GetDirectionsWorker();
    }
    else
    {
        var html = '<h4>Did you mean?</h4>';
        html += '<ul class="AmbiguousPlaces">';
        
        for(var i = 0; i < places.length; i++)
        {
            html += '<li><a href="#" onclick="NPR.Stations.Directions.StartLocation = {\'Name\':\'' + places[i].Name + '\', \'LatLong\':new VELatLong(' + places[i].LatLong.Latitude + ', ' + places[i].LatLong.Longitude + ')}; NPR.Stations.Directions.GetDirectionsWorker(); return false;">' + places[i].Name + '</a></li>';
        }
        
        html += '</ul>';
        
        NPR.Stations.Directions.ResultsElement.innerHTML = html;
        
        //Visual Sciences
		//vsPageEvent("didyoumean");        
    } 
}

NPR.Stations.Directions.GetDirections = function(start, end, resultsElement)
{
	if (start == getDefault(document.getElementById('txtStartAddress')) && end == getDefault(document.getElementById('txtEndAddress')))
	{
		alert("Please enter a starting and ending address.");
		return;
	}
	else if (start == getDefault(document.getElementById('txtStartAddress')))
	{
		alert("Please enter a starting address.");
		return;
	}
	else if (end == getDefault(document.getElementById('txtEndAddress')))
	{
		alert("Please enter an ending address.");
		return;
	}	

    NPR.Stations.Clear();
    
    NPR.Stations.Directions.ResultsElement = resultsElement;
    NPR.Stations.Directions.ResultsElement.innerHTML = NPR.Stations.Settings.DirectionsLoadingText;
    
    NPR.Stations.Directions.StartLocation = start;
    NPR.Stations.Directions.EndLocation = end;

	//Visual Sciences 
	//vsPageEvent("GetDirections");    
    
    NPR.Stations.Directions.GetDirectionsWorker();
}

NPR.Stations.Directions.GetDirectionsComplete = function(route)
{
    // Save the route
    NPR.Stations.Directions.VERoute = route;
    
    // Create our own route segments from the Virtual Earth data (some our of waypoints are artificial)
    for(var i = 0; i < NPR.Stations.Directions.VERoute.RouteLegs[0].Itinerary.Items.length; i++)
    {
        var routeSegment = new NPR.Stations.RouteSegment(NPR.Stations.Directions.VERoute.RouteLegs[0].Itinerary.Items[i]);
        routeSegment.ArtificialDistance = routeSegment.VERouteSegment.Distance;          
        NPR.Stations.Directions.RouteSegments.push(routeSegment);
    }
    
    // Keep adding artificial waypoints until we no longer need to
    while(NPR.Stations.Directions.NeedsArtificialWaypoints(NPR.Stations.Directions.RouteSegments))
    {
        NPR.Stations.Directions.AddArtificialWaypoints(NPR.Stations.Directions.RouteSegments);
    }
      
    // Load each route segments station coverage
    if(NPR.Stations.Directions.RouteSegments.length > 0)
    {
	    for(var i = 0; i < NPR.Stations.Directions.RouteSegments.length; i++)
        {
            var routeSegment = NPR.Stations.Directions.RouteSegments[i];            
            routeSegment.LoadStations(NPR.Stations.Directions.OnLoadRouteSegmentComplete);
        }
    }
    else
    {
        NPR.Stations.Directions.OnLoadRouteSegmentComplete();
    }
}

NPR.Stations.Directions.GetDirectionsWorker = function()
{
    NPR.Stations.Directions.ResultsElement.innerHTML = NPR.Stations.Settings.DirectionsLoadingText;
    
    if(typeof(NPR.Stations.Directions.StartLocation) == 'string')
    {
        // Need to geocode the start address
        NPR.Stations.Directions.StartLocation = NPR.Stations.Localize(NPR.Stations.Directions.StartLocation);
        map.Find(null, NPR.Stations.Directions.StartLocation, null, null, null, 10, false, false, false, false, NPR.Stations.Directions.FindStartLocationCallback);
    }
    else if(typeof(NPR.Stations.Directions.EndLocation) == 'string')
    {
        // Need to geocode the end address
        NPR.Stations.Directions.EndLocation = NPR.Stations.Localize(NPR.Stations.Directions.EndLocation);
        map.Find(null, NPR.Stations.Directions.EndLocation, null, null, null, 10, false, false, false, false, NPR.Stations.Directions.FindEndLocationCallback);
    }
    else
    {
        // Found start and end addresses, get the directions
        map.m_vedirectionsmanager.HandleFailedGetDirections = function() { NPR.Stations.Directions.ResultsElement.innerHTML = NPR.Stations.Settings.DirectionsErrorMessage; };
        var locations = new Array(NPR.Stations.Directions.StartLocation.LatLong, NPR.Stations.Directions.EndLocation.LatLong);
        
        var options = new VERouteOptions();
        options.DistanceUnit = NPR.Stations.Settings.DistanceUnit;
        options.RouteCallback = NPR.Stations.Directions.GetDirectionsComplete;
        options.RouteColor = NPR.Stations.Settings.RouteColor;
        options.RouteWeight = NPR.Stations.Settings.RouteWeight;
        options.SetBestMapView = true;
        options.ShowDisambiguation = false;
        options.ShowErrorMessages = false;
        
        map.GetDirections(locations, options);
    }
}

NPR.Stations.Directions.GetResultsHtml = function(veRoute)
{
    var uniqueStations = [];
    var VEIndex = 0;
    var html = '<div class="directions">';
    
    // Header
    html += '<div class="header">';
    html += '<h2>Driving directions to ' + NPR.Stations.Directions.EndLocation.Name + '</h2>';
    html += '<h4>';
    html += veRoute.Distance.toFixed(1) + ' ' + GetDistanceUnitAbbreviation(NPR.Stations.Settings.DistanceUnit);
    html += ' | <a href="#" onclick="swap(document.getElementById(\'txtStartAddress\'), document.getElementById(\'txtEndAddress\')); NPR.Stations.Directions.Reverse(); return false;">Reverse</a>';
    html += ' | <a href="#" onclick="window.print(); return false;">Print</a>';
    html += '</h4>';
	html += '</div>';
	
	for(var i = 0; i < NPR.Stations.Directions.RouteSegments.length; i++)
	{
	    var routeSegment = NPR.Stations.Directions.RouteSegments[i];
	    
	    if (i == 0) {
	    	routeSegment.VERouteSegment.Shape.SetCustomIcon(NPR.Stations.Settings.StartImageURI);
	    }
	    if (i == NPR.Stations.Directions.RouteSegments.length - 1) {
	    	routeSegment.VERouteSegment.Shape.SetCustomIcon(NPR.Stations.Settings.EndImageURI);
	    }
	    
	    // See if the route segment is artificial
	    if(!routeSegment.IsArtificial)
	    {
	        html += '<div class="direction">';
	        html += '<div class="instruction">';
	        
	        if(VEIndex != 0)
	        {
	            html += VEIndex + '. ';
	        }

	        html += '<a href="#" onclick="NPR.Stations.Directions.ZoomToFit(\'' + routeSegment.VERouteSegment.Shape.GetID() + '\'); return false;">' + routeSegment.VERouteSegment.Text + '</a>';
	        html += '</div>';
	        
	        VEIndex++;
	        
	        // Are there any hints for this waypoint?
	        if(routeSegment.VERouteSegment.Hints)
	        {
	            for(var j = 0; j < routeSegment.VERouteSegment.Hints.length; j++)
	            {
	                html += '<div class="instruction hint">' + routeSegment.VERouteSegment.Hints[j].Text + '</div>';
	            }
	        }
	        
	        // Are there any warnings for this waypoint?
	        if(routeSegment.VERouteSegment.Warnings)
	        {
	            for(var j = 0; j < routeSegment.VERouteSegment.Warnings.length; j++)
	            {
	                //html += '<div class="instruction warning">' + routeSegment.VERouteSegment.Warnings[j].Text + '</div>';
	            }
	        }
	        
	        // Check to see if there is a distance assigned to this waypoint
	        if(routeSegment.VERouteSegment.Distance && routeSegment.VERouteSegment.Distance.toFixed(1) != 0)
	        {
	            html += '<span class="distance">' + routeSegment.VERouteSegment.Distance.toFixed(1) + ' ' + GetDistanceUnitAbbreviation(NPR.Stations.Settings.DistanceUnit) + '</span>';
	        }
	        
	        html += '</div>';
	    }
	    
        var newStations = false;
		for(var stationId in routeSegment.Stations)
        {
            // Check to make sure we haven't already included this station in the directions
            if(uniqueStations[stationId] == null)
            {
                // Ensure the station has a valid position
                if(stations[stationId] && stations[stationId].Position)				
                {
					if (!newStations)
					{
						// Artificial waypoint
						if (routeSegment.IsArtificial)
						{
							html += '<div class="direction">';
	                        html += '<div class="instruction">' + routeSegment.VERouteSegment.Text + '</div>';
	                        html += '</div>';
			        	}
					
						html += '<div class="stations">';
						html += '<h5>You can now listen to:</h5>';
						newStations = true;
					}				

                    html += stations[stationId].GetResultsHtml();
                    uniqueStations[stationId] = stations[stationId];
                }
            }
        }
		
		if(newStations)
		{
			html += '</div>';
		}
	}
					
	html += '</div>';

	return html;
}

NPR.Stations.Directions.NeedsArtificialWaypoints = function(routeSegments)
{
    for(var i = 0; i < routeSegments.length - 1; i++)
    {
    	if (routeSegments[i].ArtificialDistance > NPR.Stations.Settings.CreateArtificialWaypointsForDistancesOver)
    	{
    	    return true;
    	}
    }

    return false;
}

NPR.Stations.Directions.Reverse = function()
{
	// Visual Science
	//vsPageEvent("Reverse");
	 
    map.DeleteRoute();
    NPR.Stations.Directions.GetDirections(NPR.Stations.Directions.EndLocation.Name, NPR.Stations.Directions.StartLocation.Name, NPR.Stations.Directions.ResultsElement);
}

NPR.Stations.Directions.OnLoadCoverageComplete = function(station)
{
    if(++NPR.Stations.Directions.RouteStationsLoaded >= NPR.Stations.GetStationCount())
    {            
        for(var stationId in stations)
        {
            try
            {
                stations[stationId].ShowPushpin();
            }
            catch(e){}
        }
        
        // Once the stations for all the route segments have loaded, build the directions HTML
        NPR.Stations.Directions.ResultsElement.innerHTML = NPR.Stations.Directions.GetResultsHtml(NPR.Stations.Directions.VERoute);
    }
}

NPR.Stations.Directions.OnLoadRouteSegmentComplete = function()
{
    if(NPR.Stations.Directions.VERoute != null)
    {
        // Ensure the stations for all the route segments have loaded
        if(++NPR.Stations.Directions.RouteSegmentsLoaded >= NPR.Stations.Directions.RouteSegments.length)
        {            
            // Once all the stations for all the route segments have loaded, load the station coverage
            for(var i = 0; i < NPR.Stations.Directions.RouteSegments.length; i++)
            {
                for(var stationId in NPR.Stations.Directions.RouteSegments[i].Stations)
                {
                    // Ensure we don't load the coverage for the same station more than once
                    if(stations[stationId] == null)
                    {
                        var station = NPR.Stations.Directions.RouteSegments[i].Stations[stationId];
                        stations[stationId] = station;                        
                        station.LoadCoverage(NPR.Stations.Directions.OnLoadCoverageComplete);
                    }
                }
            }
        }
    }
}

NPR.Stations.Directions.ZoomToFit = function(shapeId)
{
    var shape = map.GetShapeByID(shapeId);
    shape.SetZIndex(zIndex++);
    
    map.SetAnimationEnabled(false);
    map.SetMapView(shape.GetPoints());
    map.ShowInfoBox(shape);
    map.SetAnimationEnabled(true);
}