﻿var arraypaths = ['/Content/images/pin_blue.png', '/Content/images/pin_lightorange.png', '/Content/images/pin_darkorange.png'];
var map;
var baselat = 68.9;  //Our baseline for statute miles per latitude degree change.
var baselong = 58.1; //ditto for longitude degree change.
var minbase = 60; //Constant for minutes in a degree to convert d(miles) to d(minutes). 
var izlevel = 14; //iz = individual zoom
var center;
var thebox;
var pinarr = new Microsoft.Maps.EntityCollection();
var restrictZoom = function () {
    if (map.getZoom() <= map.getZoomRange().min) {
        map.setView({
            'zoom': map.getZoomRange().min,
            'animate': false
        });
    }
    else if (map.getZoom() >= map.getZoomRange().max) {
        map.setView({
            'zoom': map.getZoomRange().max,
            'animate': false
        });
    }
};
//This small class essentially gives us a box to constrain entities and entity searches into.
//the cardinality is from a "birds eye" point of view instead of driving directions 
function BoundingBox(cp, r) {
    //Get our multiplier wrt our base
    var mlat = (r / baselat);
    var mlong = (r / baselong);
    this.NorthExtreme = cp.latitude + mlat;
    this.EastExtreme = cp.longitude - mlong;
    this.SouthExtreme = cp.latitude - mlat;
    this.WestExtreme = cp.longitude + mlong;
}
//Primary for casting user opt in position into Bing maps object
function castAndQuery(pos) {
    var msft = new Microsoft.Maps.Location(pos.coords.latitude, pos.coords.longitude);
    var gcs = performGeoSpatialQuery(msft);
    return gcs;
}
function directionsError(responseCode, message) {
    hideFunctionsPane();
    $('#resultspane').html('<h3>Error Processing Your Request</h3><p>Sorry, but we\'re unable to give you directions at this time' +
                            '</p><p>Error Message: ' + message + '</p>');
}
function reportError(jqxhr, textstatus, errorthrown) {
    responsetext = jqxhr.responseText;
    hideFunctionsPane();
    $('#maincontent').html("<span style='color: Red'>Failure retreiving from server: " + textstatus + "</span>" + "<p>" + responsetext + " </p>");
    //More error reporting here.
}
function placeEntity(e) {
    map.setView({ center: e, zoom: 11 });
    var p = new Microsoft.Maps.Pushpin(e);
    map.entities.push(p);
}
function fillto(par) {
    (!$('#resultspane').hasClass('panehide')) ? hideResultsPane() : null;
    $('#to').val(par);
}
//Basically uses a template to create the html for the list of results
function getResultContent(ent, n) {
    var eldiv = "#rdiv" + n;
    var rawfull = ent["address"] + ", " + ent["city"] + ", AZ " + ent["zipcode"];
    var fulladdr = ent["address"] + ",<br /> " + ent["city"] + ", AZ " + ent["zipcode"];
    $(eldiv).append("<div><strong>" + n + ".</strong>&nbsp;<strong>" + ent["name"] + "</strong>");
    $(eldiv).append("<div style='float:right'>" + ent["cvalue"] + " miles</div></div>");
    $(eldiv).append("<p>" + fulladdr + "</p>");
    $(eldiv).append("<p>" + ent["hours"] + "</p>");
    $(eldiv).append('<p>' + ent["description"] + '</p>');
    return $(eldiv).html();
}
function getContent(ent) {
    var rawfull = ent["address"] + ", " + ent["city"] + ", AZ " + ent["zipcode"];
    var fulladdr = ent["address"] + ",<br /> " + ent["city"] + ", AZ " + ent["zipcode"];
    $('#locationname').html("<h2>" + ent["name"] + "</h2>");
    $("#closebox").text(l('%close'));
    $("#fulladdress").html(fulladdr);
    $("#hours").html(ent["hours"]);
    $("#description").html(ent["description"]);
    $("#dirlink").attr('href', "javascript:fillto('" + rawfull + "')");
    var thecontent = $('#popboxtemp').html();
    return thecontent;
}
//parse through nodes and look at the ID.
function getEntityById(id, cb) {
    for (var i = 0; i < nodes.length; i++) {
        //We've also validated the nodes lat longs are ok before we initialized them.
        if (nodes[i]["id"] == id) {
            return nodes[i];
        }
    }
}
//c = comparison object we're comparing to
function getEntityByLocation(c) {
    if (c.latitude !== undefined) {
        complat = c.latitude;
        complong = c.longitude;
    }
    else {
        complat = c['latitude'];
        complong = c['longitude'];
    }
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i]["latitude"] === complat && nodes[i]["longitude"] === complong) {
            return nodes[i];
        }
    }
}
function getPCLocation(e) {
    if (e.targetType == 'pushpin' && nodes != null) {
        //indicates we have the right box
        var targloc = e.target.getLocation();
        zoomToPayCenter(targloc);
    }
}

function zoomToPayCenter(loc) {
    var entity = null;
    if (typeof loc === 'number') {
        entity = getEntityById(loc);
    }
    else {
        entity = getEntityByLocation(loc);
    }
    var zoomcenter = new Microsoft.Maps.Location(entity["latitude"], entity["longitude"]);
    map.setView({ zoom: izlevel, center: zoomcenter });
    thebox != null ? map.entities.remove(thebox) : null;
    var boxcontent = getContent(entity);
    var offs = new Microsoft.Maps.Point(10, 30);
    thebox = new Microsoft.Maps.Infobox(zoomcenter, { offset: offs });
    thebox.setHtmlContent("<div class='popbox'>" + boxcontent + "</div>");
    map.entities.push(thebox);
}
//Similar to method above just uses hard coded coords.
function pushEntities(results) {
    //clear the map if its not null
    map != null ? map.entities.clear() : null;
    thebox != null ? map.entities.remove(thebox) : null;
    nodes != null ? nodes = results : null;
    //For starters lets just load them and populate them into pinarray
    for (var i = 0; i < results.length; i++) {
        rowobject = results[i];
        if (rowobject !== null) {
            lat = rowobject['latitude'];
            longi = rowobject['longitude'];
            testtext = rowobject['id'];
            if (typeof lat === 'number' && typeof longi === 'number') {
                var loca = new Microsoft.Maps.Location(lat, longi);
                var ico;
                if (rowobject['status'] == 1) {
                    ico = green;
                }
                else if (rowobject['status'] == 2) {
                    ico = yellow;
                }
                else if (rowobject['status'] == 3) {
                    ico = red;
                }
                else {
                    ico = unknown;
                }
                var p = new Microsoft.Maps.Pushpin(loca, { icon: ico });
                Microsoft.Maps.Events.addHandler(p, 'click', getPCLocation);
                map.entities.push(p);
                //end if
            }
            //end if
        }
        //end for
    }
}
function populateCSO(csnodes) {
    nodes == null ? nodes = csnodes : null; //in case of a first run we populate the dataset
    csonodes = new Array();
    for (var i = 0; i < csnodes.length; i++) {
        var rowobject = csnodes[i];
        if (rowobject !== null) {
            var iscso = rowobject["isOffice"];
            if (iscso) {
                csonodes.push(rowobject);
            }
        }
    }
    pushEntities(csonodes);
}
//Get the CSO offices from our existing nodes object
function getCSONodes() {
    nodes == null ? getAllNodes(populateCSO) : populateCSO(nodes);
}
//Get the data/status nodes from the server.
function getAllNodes(cb) {
    var tmpdata = $.ajax({
        url: paycenterurl,
        cache: false,
        datatype: 'json',
        data: { locale: String.locale },
        error: reportError,
        success: [pushEntities, function (data) { cb !== undefined ? cb(data) : null; } ]
    });
   
}
function getMap(center, paneID, theNodes) {
    var options = {
        credentials: cred,
        enableClickableLogo: false,
        center: center,
        enableClickableLogo: false,
        enableSearchLogo: false,
        zoom: 10
    };
    map = new Microsoft.Maps.Map(document.getElementById(paneID), options);
    Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: initializeDM });
    Microsoft.Maps.Events.addHandler(map, 'viewchangestart', restrictZoom);
    // Set your min/max zoom levels here
    map.getZoomRange = function () {
        return {
            max: 19,
            min: 9
        };
    };

    //callback function
    theNodes !== undefined ? theNodes() : null;
    return map;
}

//initializes Directions Manager
function initializeDM() {
    directionsmanager = new Microsoft.Maps.Directions.DirectionsManager(map);
    Microsoft.Maps.Events.addHandler(directionsmanager, 'directionsError', directionsError);
}
//Initial call to the database.
function loadMapDefaults() {
    $('#returntomain').addClass('hidelink');
    //hide the return to main link
    hideResultsPane();
    center = new Microsoft.Maps.Location(33.45779703535474, -111.96304321289062);
    //Until after the map has been loaded on the browser
    nodes = getAllNodes;
    getMap(center, 'mappane', nodes);
    //load defaults if there is no locnb to get
    mapcallback = function () { loadMapDefaults(); };
}
//Grab only the CSOs
function loadCSOMap() {
    center = new Microsoft.Maps.Location(33.45779703535474, -111.96304321289062);
    hideResultsPane();
    map === undefined ? getMap(center, 'mappane') : null; //initialize the map, if necessary.
    getCSONodes();
    mapcallback = function () { loadCSOMap; };
}
function loadSingleEntity() {
    $('#returntomain').removeClass('hidelink');
    var rawdat = $.getJSON(paycenterurl, { locale: String.locale }, function (data) {
        nodes = data;
        var en = getEntityById(getlocnb);
        if (en !== undefined) {
            var encenter = new Microsoft.Maps.Location(en["latitude"], en["longitude"]);
            getMap(encenter, 'mappane');
            pushEntities(data);
            zoomToPayCenter(encenter);
            getlocnb = 0;
        }
        else {
            getlocnb = 0;
            setHIDefaults();
        }
    });
    mapcallback = function () { loadSingleEntity(); };
}
function getDirections(t, f) {
    thebox != null ? map.entities.remove(thebox) : null;
    directionsmanager.resetDirections();
    var startway = new Microsoft.Maps.Directions.Waypoint({ address: f });
    var toway = new Microsoft.Maps.Directions.Waypoint({ address: t });
    directionsmanager.addWaypoint(startway);
    directionsmanager.addWaypoint(toway);
    directionsmanager.setRenderOptions({ itineraryContainer: document.getElementById("resultspane") });
    directionsmanager.calculateDirections();
}
