﻿/*
 *  Initialise maps namespace
 */
ninemsn.mylocal.maps = function(){};

// initialise variables 
var map = null;
var whereSuffix = "Australia";
var lat =  "-30.287027";
var lon =  "133.59375";
var zoom = 2;
var zoomClose = 14;
var elMapContainer; // Element to contain the mapping component

/*---------------------------------------------------------------------------------------
    Method:			onMapScriptLoaded
    Inputs:			
    Outputs:		
    Description:    Render the map once the Virtual Earth Map API is loaded successfully
----------------------------------------------------------------------------------------*/
function onMapScriptLoaded()
{
	window.setTimeout('ninemsn.mylocal.maps.renderMap()', 2000);	
}
   
/*---------------------------------------------------------------------------------------
    Method:			initVEMaps
    Inputs:			
    Outputs:		
    Description:    Load the Virtual Earth Map API on demand
----------------------------------------------------------------------------------------*/
ninemsn.mylocal.maps.initVEMaps = function(elSource)
{
    try
    {    
        if (elMapContainer)
            return false;
                
        elMapContainer = elSource;
        var script = document.createElement('script');
        script.src = 'VEMapsJavascriptCache.ashx';
        //now this is being GZipped at Microsoft's end
        //script.src = 'http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1';
        script.type = 'text/javascript';
        script.defer = true;
        var head = document.getElementsByTagName('head').item(0);
        head.appendChild(script);
    }
    catch (err)
    {
        alert(err.message);
    }
    
    return false;
}

/*---------------------------------------------------------------------------------------
    Method:			renderMap
    Inputs:			
    Outputs:		
    Description:    Render the map, center and zoom to Australia by default
----------------------------------------------------------------------------------------*/ 
ninemsn.mylocal.maps.renderMap = function()
{  
    map = new VEMap('VEMapControl');
        
    /*
     *  SetDashboardSize must be called before calling LoadMap    
     */
    map.SetDashboardSize(VEDashboardSize.Small);
    MapControl.Features.ScaleBarKilometers = true;
    
    /*
     *  Wire up onload event handler
     */
    map.onLoadMap = ninemsn.mylocal.maps.completeLoadMap;
    map.LoadMap(new VELatLong(lat,lon), zoom, VEMapStyle.Road, false);
      
}

/*---------------------------------------------------------------------------------------
    Method:			completeLoadMap
    Inputs:			
    Outputs:		
    Description:    After the map is rendered, perform a lookup if parameters are passed
                    in the url (this is for shared links)
----------------------------------------------------------------------------------------*/ 
ninemsn.mylocal.maps.completeLoadMap = function()
{      
    try
    {   
        var success = false;

        /*
         * Display Route (Directions)
         * g_mapDirections is injected into the page dynamically
         * See Directions.aspx.cs
         */ 
        if (window.g_mapDirections)
        {          
            ninemsn.mylocal.maps.getDirections();
            return;
        }  
        
        /*
         *  Construct collections used for mapping
         *  Collections output by .net application
         *  Collections dependant upon the existance of the VEMaps object
         */
        if (window.buildMapCollections)
            window.buildMapCollections();
      
        /*
         *  If pins exists, then push them into the map
         *  and center around them
         */
        if (window.g_geoArray && window.g_geoArray.length)
        {
            ninemsn.mylocal.maps.pushPinsIntoMap();
            return;
        }      
        
        /*
         *  Display Single Business (Details)
         *  No pins to push in, so zoom into the suburb geocode
         *  allow g_lat to be zero
         */
        if (window.g_mapBusiness & !ninemsn.mylocal.util.IsNullOrEmpty(window.g_lat))
        {           
            ninemsn.mylocal.maps.mapSuburbGeocode();
            return;
        }   
                            
        /*
         *  Set the position of the map view based on where field (Search)
         */
        var where = ninemsn.mylocal.util.getQueryParam("where");
        if (where)
        {
            map.Find(null, where + ' ' + whereSuffix, null, null, null, null, true, true, false, true, null); 
            return;
        }
    }
    catch(ex)
    {
        /*
         *  Write out excetions to debug panel
         */
         utl.debout("** EXCEPTION ** ninemsn.mylocal.maps.completeLoadMap : {0}".format(ex.description));
    }
};

/*
 *  pushPinsIntoMap
 *  Find the shapes array, and push the pins into the map.
 *  Set center and zoom over the shape
 *  Returns boolean success value
 */
ninemsn.mylocal.maps.pushPinsIntoMap = function()
{
    try
    {            
         /*
          *  Pins should be created, now center the map
          *  JavaScript variable 'whereSuffix' is defined in ninemsn.mylocal.maps.js
          */
        for (var i in window.g_shapeArray)
        {
            var shape = window.g_shapeArray[i].shape;
            map.AddShape(shape);
            
            shape = window.g_shapeArray[i].highlightedshape;
            map.AddShape(shape);
        }                
        
        /*
         *  Set the position of the map view based on geocode array
         */
        if (window.g_geoArray && window.g_geoArray.length)
            map.SetMapView(window.g_geoArray); 
            
    }
    catch (ex)
    {
        utl.debout("** EXCEPTION ** ninemsn.mylocal.maps.pushPinsIntoMap : {0}".format(ex.description));
    }
    return false;                  
};

ninemsn.mylocal.maps.mapSuburbGeocode = function()
{
    try
    {
        /*
         *  Create our locations array that will be used to center our map
         */
        var location = new VELatLong(window.g_lat, window.g_lon);
        map.SetCenterAndZoom(location, zoomClose); 
          
    }
    catch (ex)
    {
        utl.debout("** EXCEPTION ** ninemsn.mylocal.maps.mapSuburbGeocode : {0}".format(ex.description));
    }
    
    return false;	
}

/*---------------------------------------------------------------------------------------
    Method:			GetDirections
    Inputs:			
    Outputs:		
    Description:    
    global variables referenced eg "windows.g_address", should be created by the .net 
    application at run time
----------------------------------------------------------------------------------------*/ 
ninemsn.mylocal.maps.getDirections = function()
{  
    try
    {
        var fromAddress = "{0} {1} {2} {3} {4}".format(window.g_formStreet, window.g_formSuburb, window.g_formState, window.g_formPostcode,whereSuffix);
        
        /*
         *  Set up map options
         */
        var options = new VERouteOptions();
        options.DistanceUnit = VERouteDistanceUnit.Kilometer;
        options.RouteMode  = window.g_formRoute == 'radio_quickestByFoot' ? VERouteMode.Walking : VERouteMode.Driving;
        options.RouteCallback = ninemsn.mylocal.maps.completeGotRoute;
        
        /* 
         *  Set up location to map route
         */
        var locations = new Array(fromAddress, "{0} {1}".format(window.g_address, whereSuffix));
        
        /* 
         *  Initiate find
         */
        map.GetDirections(locations, options);
        
        return false;
    }
    catch (ex)
    {
        /*
         *  Write out excetions to debug panel
         */
         utl.debout("** EXCEPTION ** ninemsn.mylocal.maps.getDirections : {0}".format(ex.description));
    }    
}

/*---------------------------------------------------------------------------------------
    Method:			onGotRoute
    Inputs:			
    Outputs:		
    Description:    Callback function if the GetDirections() function executes successfully
                    This function is responsible for listing the directions and plotting
                    the route on the map
----------------------------------------------------------------------------------------*/ 
ninemsn.mylocal.maps.completeGotRoute = function(route)
{
    /*
     *  Unroll route
     */
    var legs     = route.RouteLegs;
    var routeInfo = [];
    var turns    = [];
    var numTurns = 0;
    var leg      = null;
    
    /*
     *  Get intermediate legs
     */
    for(var i = 0; i < legs.length; i++)
    {
        /*
         *  Get the VERouteLeg object
         */
        leg = legs[i];  
        
        var turn = null;
        for(var j = 0; j < leg.Itinerary.Items.length; j ++)
        {   
            /*
             *  Turn is a VERouteItineraryItem object
             */
            turn = leg.Itinerary.Items[j];  
            numTurns++;
            turns.push("<li><div>" + turn.Text + " <br/>(" + turn.Distance.toFixed(1) + " km)</div>");
        }
    }
    
    routeInfo.push("<span class=\"direction_heading\">Directions</span>");
    routeInfo.push("<ul>" + turns.join('') + "</ul>");
    routeInfo.push("<span class=\"direction_heading\">Total distance:</span> {0} km <br/>".format((Math.round(route.Distance * 100)) / 100));
    routeInfo.push("<span class=\"direction_heading\">Estimate walking time:</span> {0} mins <br/>".format(Math.round((60/4) * route.Distance)));
    routeInfo.push("<span class=\"direction_heading\">Estimate driving time:</span> {0} mins".format(Math.round((60/30) * route.Distance)));

    document.getElementById('directions_route').innerHTML = routeInfo.join('');
};

function addShim(el,id) //creates the required 3D shim for an element. Used espcially with the DoAlert() function
{
    var shim = document.getElementById('alertshim');
    if (!shim) 
        shim = document.createElement("iframe"); 
    shim.id = id;         
    shim.frameBorder = "0"; 
    shim.style.position = "absolute";
    shim.style.zIndex = "1";
    shim.style.top  = el.offsetTop + "px";
    shim.style.left = el.offsetLeft + "px";
    shim.style.width  = el.offsetWidth + "px";
    var h = parseInt(document.getElementById("alerttitle").offsetHeight) +
        parseInt(document.getElementById("alerttext").offsetHeight);
    if (h > 0)
	    shim.style.height = h + "px";
	else
	    shim.style.height = parseInt(document.getElementById("alerttitle").style.height) +
            parseInt(document.getElementById("alerttext").style.height) + "px";


    el.shimElement = shim; 
    el.parentNode.insertBefore(shim, el);
}
