﻿
// Define address to be used for pushpin description and title displayed at top of page.
var address, description, title;

// Define Bing pushpin for Streetview location.
var streetviewPushpin = null;
var streetviewLocation;


// Adds pushpin for requested location.
//
// TODO: Refactor with drawStreetviewPushpin().
//
function addShape() {
    if (veMap && veShapeLayers[0]) {
        var veShape = new VEShape(VEShapeType.Pushpin, initialMapCenter);
        veShape.SetTitle(title);
        veShape.SetDescription(description);
        veShape.SetCustomIcon('images/NeedleLeftYellow2.png');        
        veShapeLayers[0].AddShape(veShape);
    }
    else {
        var mapLoadTimer = function() { addShape(); };
        setTimeout(mapLoadTimer, mapLoadTimerInterval);
    }
}

function callBingLocator(address) {
    // Go back to the original extent to narrow the results geographically in case
    // this query follows a routing result for a location outside Richmond. 
    ZoomToLayer(0);
    veMap.Find(null, address, null, null, null, 20, null, null, true, false, onVEMapFind);
}

function drawRoute(locations) {
    var veRouteOptions = getVERouteOptions();

    veRouteOptions.DrawRoute = true;

    // Uncomment this to keep the map extent from updating.
    //veRouteOptions.SetBestMapView = false;

    // Show as miles.
    veRouteOptions.DistanceUnit = VERouteDistanceUnit.Mile;

    // Show the disambiguation dialog.
    veRouteOptions.ShowDisambiguation = true;

    // Set a callback.
    veRouteOptions.RouteCallback = onVERouteGeneration;

    // Turn off notifications.
    veMap.ShowMessageBox = false;

    veMap.GetDirections(locations, veRouteOptions);

    $(showRouteAnchorId).html("Hide");
}

function drawRouteFrom(startLatLong) {
    var latlons = new Array();
    latlons[0] = startLatLong;
    latlons[1] = initialMapCenter;
    drawRoute(latlons);
}

// Called from onPanoramaInitialized.
function drawStreetviewPushpin(lat, lon) {
    if (streetviewPushpin) {
        veMap.DeleteShape(streetviewPushpin);
    }

    streetviewLocation = new VELatLong(lat, lon);
    streetviewPushpin = new VEShape(VEShapeType.Pushpin, streetviewLocation);
    streetviewPushpin.SetCustomIcon("images/green_MarkerS.png");
    streetviewPushpin.SetTitle("Street View Location");
    streetviewPushpin.SetDescription("Double-click elsewhere on map or on a Street View road centerline to relocate the point of view.");
    
    veMap.AddShape(streetviewPushpin);

    // Update view extent if outside
    updateMapWithStreetview();
}

function getRouteMap() {
    if (veMap) {
        // Validate address value.
        var validatedFromAddress = handleSpecialCharacters(routeFromAddress);

        // Show progress bar.
        $(progressImageId).show();

        // Call handler to find location.
        // The callback then evaluates the response, calling either drawRouteFrom() or callBingLocator().
        InvokeAshx("GeocodeHandler.ashx?fromAddress=" + validatedFromAddress);
    }
}

function getVEMouseEventLatLon(e) {
    var latLong = e.latLong;
    if (!latLong) {

        // Map is 2D.
        var vePixel = new VEPixel(e.mapX, e.mapY);
        if (veMap.GetMapStyle() != "b") {
            return veMap.PixelToLatLong(vePixel);
        }
        else {
            // Return result of undocumented work-around for calculating Birdseye location.
            var be = veMap.GetBirdseyeScene();
            var centrePixel = be.LatLongToPixel(veMap.GetCenter(), veMap.GetZoomLevel());
            var currentPixelWidth = be.GetWidth();
            var currentPixelHeight = be.GetHeight();
            var mapDiv = $(mapDivId)[0];
            var mapDivPixelWidth = mapDiv.offsetWidth;
            var mapDivPixelHeight = mapDiv.offsetHeight;
            var xScreenPixel = centrePixel.x - (mapDivPixelWidth / 2) + vePixel.x;
            var yScreenPixel = centrePixel.y - (mapDivPixelHeight / 2) + vePixel.y;
            var position = be.PixelToLatLong(new VEPixel(xScreenPixel, yScreenPixel), veMap.GetZoomLevel())
            return (new _xy1).Decode(position);
        }
    }
    else {
        return latLong;
    } 
}

function getVERouteOptions() {
    var veRouteOptions = new VERouteOptions;

    // Set travel mode.
    if (routeMode == "walk") {
        // Set mode as walking and ignore other optimizations.
        veRouteOptions.RouteMode = VERouteMode.Walking;
    }
    else {
        // Set mode as driving.
        veRouteOptions.RouteMode = VERouteMode.Driving;

        // Set optimization.
        if (routeOptimize == "straight") {
            veRouteOptions.RouteOptimize = VERouteOptimize.MinimizeDistance;
        }
        else {
            veRouteOptions.RouteOptimize = VERouteOptimize.MinimizeTime;
        }

        // Set traffic.
        veRouteOptions.UseTraffic = routeUseTraffic;  //$(trafficCheckboxId).attr("checked");
    }
    return veRouteOptions;
}

function handleSpecialCharacters(value) {
    // Replace '&' with '@'
    return value.replace("&", "@");

    //    var iChars = "!@#$%^&*()+=-[]\\\';,./{}|\":<>?";
    // Replace '&' with '@'
    //var newValue = value.replace("&", "@");
    // Replace ''' with '\''
    //var newValue = value.replace("\'", "\\'");
}

function onVEMapClick(e) {
    hideMenus();
    
    // Continue normal Bing doubleclick behavior.
    return false;
}

function onVEMapDoubleClick(e) {
    if (streetviewOn) {
  
        // Get mouse click location.
        var latLong = getVEMouseEventLatLon(e);

        // Display Streetview panorama if available.
        showPanorama(latLong.Latitude, latLong.Longitude);
    }
    
    // Disable normal Bing doubleclick behavior.
    return true;    
}

// Handle results callback from VE.
function onVEMapFind(veShapeLayer, veFindResults, vePlaces, moreResults, errorString) {
    if (vePlaces != null && vePlaces.length > 0) {
        try {
            drawRouteFrom(vePlaces[0].LatLong);
            return;
        }
        catch (e) {
            alert(e.message);
        }
    }
    else {

        // No matches.
        alert('The location at "' + routeFromAddress + '" could not be found.   ');
    }

    // Hide progress bar.
    $(progressImageId).hide();
}

function onVERouteGeneration(veRoute) {

    // Hide progress bar.
    $(progressImageId).hide();

    // Re-enable messages in case of something unanticipated.
    veMap.ShowMessageBox = true;

    if (!veRoute || veRoute.Distance == 0) {
        alert('Directions from the requested starting location can not be displayed.');
    }
    else {
        hideMenus();
    }
}

function updateMapWithStreetview() {
    if (streetviewTracking) {
        var latlons = new Array();
        latlons[0] = streetviewLocation;
        latlons[1] = initialMapCenter;
        veMap.SetMapView(latlons);
    }
}
