﻿/*

Object (function) for SkyGolf Microsoft Map functions
This object provides the ability to get, set, zoom, and pan the map.
This object also allows a user to add pushpins to the map.  
The addPushPins method requires the jsonT template with an array of json items.

Finally - this method is written to have 1 instance on a page.  If you must have more than 1 instance,
move all the methods and properties outside of the function object and make them prototypes instead.

///////////////////////////////////////////////////////////////////////////
Settings parameters:
    mapID - the html element ID where the map should be loaded.  Usually a div.
    veMap - a pre-existing, initialized map object.  (NOT Fully Tested Yet)
    json - any JSON data that needs to be used by the pushpin method
    itemTemplate - a single item template for pushpins
    onLoadFunction - a function to call during onload
///////////////////////////////////////////////////////////////////////////    
*/
function SkyGolfMap(settings)
{
    // private variables
    var myMapID = (!SG.IsUndefinedOrNull(settings) && !SG.IsUndefinedOrNull(settings.mapID)) ? settings.mapID : null;
    var myMap = (!SG.IsUndefinedOrNull(settings) && !SG.IsUndefinedOrNull(settings.veMap)) ? settings.veMap : null;
    var json = (!SG.IsUndefinedOrNull(settings) && !SG.IsUndefinedOrNull(settings.json)) ? settings.json : null;
    var itemTemplate = (!SG.IsUndefinedOrNull(settings) && !SG.IsUndefinedOrNull(settings.itemTemplate)) ? settings.itemTemplate : null;
    var onLoadFunction = (!SG.IsUndefinedOrNull(settings) && !SG.IsUndefinedOrNull(settings.onLoadFunction)) ? settings.onLoadFunction : null;
    
    // Public properties
    this.getData = function() { return json; }
    this.getTemplate = function() { return itemTemplate; }
    
    // Private Methods with their Public Accessors
    function _getLocale() {
        // set map market
        var locale = SG.getCookie("LocaleSetting");
        if (!(!!locale))
            locale = "en-us";
        // New Zealand is currently not supported by VE Map Control 6.2.  Therefore, set the map control to the USA.
        if (locale === "en-nz")
            locale = "en-us";
        return locale;
    }
    this.getLocale = _getLocale;
    
    function _setPushPinData(data, template)
    {
        _clearMap();
        if (!SG.IsUndefinedOrNull(data) && !SG.IsUndefinedOrNull(template))
        {
            json = data;
            itemTemplate = template;
        }
    };
    this.setPushPinData = _setPushPinData;

    function _getMap()
    {
        return myMap;
    }
    this.getMap = _getMap;

    function _onLoad()
    {
        if (!!myMap && !SG.IsUndefinedOrNull(onLoadFunction) && typeof onLoadFunction == 'function')
        {
            myMap.onLoadMap = onLoadFunction;
        }
    };
    this.onLoad = _onLoad;

    function _handleTokenError() {
        // insert code here to handle token expiration
    }
    this.handleTokenError = _handleTokenError;

    function _handleTokenExpire() {
        // insert code here to handle token errors
    }
    this.handleTokenExpire = _handleTokenExpire;

    /// Create map function.  
    /// Get an ID for an element in the dom and create a map if that dom element is found
    function _setMap()
    {
        // if myMapID is not null/undefined, and jquery element can be located by that ID
        if (!SG.IsUndefinedOrNull(myMapID) && $('#' + myMapID).length > 0)
        {
            var $map = $('#' + myMapID);
            
            // set a nice animated gif to show the map is loading
            $map.addClass("maploading");
            if (!($.browser.msie))
            {
                // work around for non ie
                getScript("https://dev.virtualearth.net/mapcontrol/v6.2/js/atlascompat.js", "", true);
            }
            getScript("https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&mkt=" + _getLocale(), _ScriptLoaded, true);
            $map = null;
        }
        else
        {
            myMap = null;
            myMapID = null;
        }
    };
    this.setMap = _setMap;

    function _ScriptLoaded()
    {
        // get rid of our load animation
        $('#' + myMapID).removeClass("maploading");

        // Verify no map was passed into settings and its a valid map object
        if (SG.IsUndefinedOrNull(myMap))
        {
            myMap = new VEMap(myMapID);
            // Attach Events
            _onLoad();
            myMap.AttachEvent("ontokenerror", _handleTokenError);
            myMap.AttachEvent("ontokenexpire", _handleTokenExpire);  
            // Set Map Client Token
            SG._sendRequest({
                url: '/services/facilitysearchservice.svc/GetClientToken',
                data: '{}',
                success: function(d, s)
                {
                    if (d.d && d.d.length > 0)
                    {
                        myMap.SetClientToken(d.d);
                        switch (_getLocale().toUpperCase()) {
                            case "EN-CA":   // Canada
                                myMap.LoadMap(new VELatLong(62.833, -95.914), 4, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "DE-DE":   // Germany
                                myMap.LoadMap(new VELatLong(51.1656910, 10.4515260), 7, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "IT-IT":   // Italy
                                myMap.LoadMap(new VELatLong(41.8719400, 12.5673800), 6, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "JA-JP":   // Japan
                                myMap.LoadMap(new VELatLong(36.2048240, 138.2529240), 5, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "EN-NZ":   // New Zealand
                                myMap.LoadMap(new VELatLong(-40.9005570, 174.8859710), 6, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "EN-GB":   // United Kingdom
                                myMap.LoadMap(new VELatLong(55.3780510, -3.4359730), 6, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            case "EN-US":   // United States of America
                                myMap.LoadMap(new VELatLong(37.0902400, -95.7128910), 4, 'h', false, VEMapMode.Mode2D, false);
                                break;
                            default:        // United States of America
                                myMap.LoadMap(new VELatLong(37.0902400, -95.7128910), 4, 'h', false, VEMapMode.Mode2D, false);
                                break;
                        }
                    }
                },
                error: function(x, s, e)
                {
                    var error = s;
                }
            });
        }
        else
        {
            _clearMap();
        }
    };
    this.ScriptLoad = _ScriptLoaded;

    function _clearMap()
    {
        // Delete all shapes from map
        if (!!myMap && !!myMap["DeleteAllShapes"])
        {
            myMap.DeleteAllShapes();
        }
    };
    this.clearMap = _clearMap;

    /// Add push pins to map
    /// json is expected to have a collection of items that match the provided jsonT template
    /// Sample json: {items: [{Title: '', Latitude: xx.xxxx, Longitude: xx.xxxx, ....},{}]}
    function _addPushPin()
    {
        // Verify none of these are null or undefined, verify that map has property DeleteAllShapes
        if (!!myMap && !!json && !!json.items && !!itemTemplate && !!myMap["DeleteAllShapes"])
        {
            var shape = null;
            var pushpinCenterPoint = null;
            var description = null;
            var icon = "/images/icons/256_nomatte.png";

            // Loop through the array
            for (var i = 0; i < json.items.length; i++)
            {
                var item = json.items[i];
                if (!!item["Latitude"] && !!item["Longitude"] && !!item["Title"])
                {
                    shape = new VEShape(VEShapeType.Pushpin, new VELatLong(item.Latitude, item.Longitude));
                    shape.SetTitle("<div class=\"strong\">" + item.Title + "</div>");
                    shape.SetCustomIcon(icon);
                    description = jsonT(item, itemTemplate);
                    shape.SetDescription(description);
                    shape.SetZIndex(2000);
                    myMap.AddShape(shape);
                }
            }
        }
    };
    this.addPushPin = _addPushPin;

    function _addPushPins() {
        // Verify none of these are null or undefined, verify that map has property DeleteAllShapes
        if (!!myMap && !!json && !!itemTemplate && !!myMap["DeleteAllShapes"]) {
            var shape = null;
            var description = null;
            var icon = "/images/icons/256_nomatte.png";
        }
        // Loop through the array
        for (var i = 0; i < json.length; i++) {
            // set center point Latitude & Longitude on first course which should be the closest to requested location
            if (i === 0) {
                pushpinCenterPoint = new VELatLong(json[i].Latitude, json[i].Longitude);
            }
            // set the maxDistance to the last item within the array
            if (i === (json.length - 1)) {
                maxDistance = json[i].Distance;
            }
            shape = new VEShape(VEShapeType.Pushpin, new VELatLong(json[i].Latitude, json[i].Longitude));
            shape.SetTitle("<div class=\"strong\">" + json[i].FacilityName + "</div>");
            shape.SetCustomIcon(icon);
            shape.SetDescription(jsonT(json[i], itemTemplate));
            shape.SetZIndex(2000);
            myMap.AddShape(shape);
        }
    };
    this.addPushPins = _addPushPins;

    // Pan Map to requested location center point
    function _pan(lat, lon)
    {
        if (!!myMap && !!lat && !!lon && !!myMap["PanToLatLong"])
        {
            var latLong = new VELatLong(lat, lon)
            myMap.PanToLatLong(latLong);
        }
    };
    this.pan = _pan;

    // Pan Map to requested location center point with a specific zoom level
    function _centerAndZoom(lat, lon, maxDistance) {
        if (!!myMap && !!myMap["SetCenterAndZoom"]) {
            var zoomLevel;
            if (maxDistance === 0)
                zoomLevel = 1;
            else if (maxDistance === 1)
                zoomLevel = 14;
            else if (maxDistance <= 5)
                zoomLevel = 12;
            else if (maxDistance > 5 && maxDistance <= 10)
                zoomLevel = 10;
            else if (maxDistance > 10 && maxDistance <= 30)
                zoomLevel = 9;
            else if (maxDistance > 30 && maxDistance <= 50)
                zoomLevel = 8;
            else if (maxDistance > 50)
                zoomLevel = 7;
            else
                zoomLevel = 7;

            var latLong = new VELatLong(lat, lon)
            myMap.SetCenterAndZoom(latLong, zoomLevel);
        }
    };
    this.centerAndZoom = _centerAndZoom;
    
    //jquery 1.2.6 doesn't provide support to getScript from the local cache
    //we need to add this ourselves currently
    function getScript(url, callback, cache)
    {
        $.ajax
        ({
            type: "GET",
            url: url,
            success: callback,
            dataType: "script",
            cache: cache
        });
    };

    // call set map to instantiate this instance.
    _setMap();
};