// FireFox 2.0 Fix : http://forums.microsoft.com/msdn/showpost.aspx?postid=852512
// This shouldn't be necessary once Microsoft updates their .js libraries for FF 2.0.
// ** Start of FireFox 2.0 fix **
var ffv = 0;
var ffn = "Firefox/"
var ffp = navigator.userAgent.indexOf(ffn);
if (ffp != -1) { ffv = parseFloat(navigator.userAgent.substring(ffp + ffn.length)); }
if (ffv >= 1.5) { Msn.Drawing.Graphic.CreateGraphic = function(f, b) { return new Msn.Drawing.SVGGraphic(f, b) } }
// ** End of FireFox 2.0 fix **


// Objects we need to access globally
var map = null;
var trapShapeLayer = null;
var locationFound = false;
var objLatLong = null;
var strAddress = "";
var layerID = null;
var LA = new VELatLong(geoip_latitude(), geoip_longitude());
var mode = 0;
var pin = null;
var addresscode = null;
var citycode = null;
var statecode = null;
var zipcode = null;
var country = null;
var tileSource = null;
var tileSourceSpec = null;
var weathercheck = null;


//Run Onload Event in Javascript
function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        window.onload = function() {
            oldonload();
            func();
        }
    }
}
addLoadEvent(GetMap);

// Create and initialize the map object
function GetMap() {
    map = new VEMap('myMap');
    // map.SetDashboardSize(VEDashboardSize.Small);
    map.LoadMap(LA, 10, VEMapStyle.Hybrid, false, VEMapMode.Mode2D, true, 1);
    // map.ShowMiniMap(575,0); 
    AddMessageBox();
    ShowMessageBox("Loading " + geoip_city() + ", " + geoip_region() + ". If there are speed traps that you know about but are missing, please add them.");
    LoadTraps();
    // attachMouseClicks(map);
    prepMenu()

    // zoom to cursor and center
    map.SetMouseWheelZoomToCenter(false);

    //these events will allow auto guessing of place names, and ensure that the geoRSS is reloaded when the map is panned or zoomed:

    if (map.AttachEvent) {
        map.AttachEvent("onchangeview", LoadTraps);
        map.AttachEvent("onclick", onMapClick);
        map.AttachEvent("onmousemove", onMapMouseMove);
        map.AttachEvent("onmousedown", onMapMouseDown);
        map.AttachEvent("onmouseup", onMapMouseUp);
    }
}

//Make Crosshair Movable
function onMapMouseDown(e) {
    if (e.leftMouseButton && e.elementID) {
        mode = 1;
        map.vemapcontrol.EnableGeoCommunity(true);
    }
}

function onMapMouseMove(e) {
    var loc = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
    var latlong = round5dec(loc.Latitude) + ", " + round5dec(loc.Longitude);
    if (mode == 1) {
        SetPin(loc);
    }
}

function onMapMouseUp(e) {
    if (mode == 1 && e.leftMouseButton) {

        map.vemapcontrol.EnableGeoCommunity(false);
        mode = 0;
        loc = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        SetPin(loc);

        //Guess Locaiton of Crosshair
        // GuessLocationName();
        map.FindLocations(loc, GetResults);
    }
}

function onMapClick(e) {
    if (e.rightMouseButton) {
        var loc = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        SetPin(loc);

        //Guess Locaiton of Crosshair
        // GuessLocationName();
        map.FindLocations(loc, GetResults);
        showPopupMenu(e)
    } else {
        hidePopupMenu(e);

    }
}

function GetResults(locations) {

    if (locations) {
        for (var i = 0; i < locations.length; i++) {
            s = locations[i].Name;
            //
            var addressSplit = s.split(", ");
            addresscode = addressSplit[0]
            citycode = addressSplit[1]
            statezip = addressSplit[2]
            country = addressSplit[3]
            var statezipSplit = statezip.split(" ");
            statecode = statezipSplit[0];
            zipcode = statezipSplit[1];
            var loc_array = new Array();
            loc_array[0] = addresscode;
            loc_array[1] = citycode;
            loc_array[2] = statecode;
            loc_array[3] = zipcode;
            window.locationArray = loc_array;
        }
    }
    else {
        s = 'Oops, I can not find that address. You may want to look in a different area.';
        alert(s)
        addresscode = "";
        citycode = "";
        statecode = null;
    }
}


function SetPin(loc) {
    if (pin) {
        //relocate
        pin.SetPoints(loc);


    }
    else {
        //create
        pin = new VEShape(VEShapeType.Pushpin, loc);
        pin.SetCustomIcon("images/crosshair.png");
        map.AddShape(pin);

    }
}

function onMapMouseOver(e) {
    if (e.elementID) {
        return true;
    }
}

function round5dec(value) {
    return Math.floor(value * 1e8) / 1e8;
}

//Clean up all objects
function Page_Unload() {
    if (map != null) {
        map.Dispose();
        map = null;
    }
}

function SetCenterAndZoom() {
    map.SetCenterAndZoom(latLong, zoomLevel);
}

function SetCenter() {
    map.SetCenter(latLong);
}

function SetZoom() {
    map.SetZoomLevel(zoomLevel);
}

function ZoomIn() {
    //Increase zoom level by a factor of 1
    map.ZoomIn();
}

function ZoomOut() {
    //Decrease zoom level by a factor of 1
    map.ZoomOut();
}

function RefreshMap() {
    map.LoadMap(map.GetCenter(), map.GetZoomLevel(), map.GetMapStyle(), false, map.GetMapMode(), true);
    LoadTraps();
    pin = null;
}

function LoadTraps() {
    if (trapShapeLayer != null) {
        map.DeleteShapeLayer(trapShapeLayer);
        trapShapeLayer = null;
    }
    if (layerID != null) {
        map.DeleteTileLayer(layerID);
        layerID = null;
    }
    if (document.getElementById("checkWeather").checked) {
        weathercheck = true
    } else { weathercheck = false }

    if (document.getElementById("mapoverlay1").checked) {
        layerID = "AccidentHeatMap";
        tileSource = "../speedtrap/AccidentTileServer.aspx/?id=%4&wc=" + weathercheck + "&hr=true";
        tileSourceSpec = new VETileSourceSpecification(layerID, tileSource);
        tileSourceSpec.NumServers = 1;
        tileSourceSpec.Opacity = 1;
        tileSourceSpec.ZIndex = 1000

        map.AddTileLayer(tileSourceSpec, true);
        map.ShowTileLayer(layerID);
    }
    if (document.getElementById("mapoverlay2").checked) {
        layerID = "AccidentHeatMap";
        tileSource = "../speedtrap/AccidentTileServer.aspx/?id=%4&wc=" + weathercheck + "&hr=false";
        tileSourceSpec = new VETileSourceSpecification(layerID, tileSource);
        tileSourceSpec.NumServers = 1;
        tileSourceSpec.Opacity = 1;
        tileSourceSpec.ZIndex = 1000

        map.AddTileLayer(tileSourceSpec, true);
        map.ShowTileLayer(layerID);
    }
    if (document.getElementById("mapoverlay3").checked) {
        var zoomlevel = map.GetZoomLevel()
        if (zoomlevel > 8) {
            map.ImportShapeLayerData(GetMapPoints(), setTrapLayer, false);
        }
        if (zoomlevel < 9) {
            layerID = "HotspotHeatMap";
            tileSource = "../speedtrap/HotSpotTileServer.aspx/?id=%4";
            tileSourceSpec = new VETileSourceSpecification(layerID, tileSource);
            tileSourceSpec.NumServers = 1;
            tileSourceSpec.Opacity = 1;
            tileSourceSpec.ZIndex = 1000

            map.AddTileLayer(tileSourceSpec, true);
            map.ShowTileLayer(layerID);
        }
    }
}

function setTrapLayer(callbackTrapLayer) {
    //store a global reference to the shape layer so it can be deleted/updated
    trapShapeLayer = callbackTrapLayer;

    //we also need to iterate through the shape and add a custom icon to each point since MS has eliminated support for the
    //<icon> tag in the GeoRSS feed.
    var numShapes = callbackTrapLayer.GetShapeCount();
    var shape;
    for (var i = 0; i < numShapes; ++i) {
        shape = callbackTrapLayer.GetShapeByIndex(i);
        shape.SetCustomIcon("<img src='" + shape.IconId + "'/>");
    }
}

// Load all existing map points (in GeoRSS format) and display as new layer
function GetMapPoints() {
    var urlGeoRSS = "GeoRSS.ashx";
    var currWidth = 750;
    var currHeight = 500;
    pixTopLeft = new VEPixel(0, 0);
    pixBotRight = new VEPixel(currWidth, currHeight);
    var mapTop = map.PixelToLatLong(pixTopLeft).Latitude;
    var mapLeft = map.PixelToLatLong(pixTopLeft).Longitude;
    var mapBot = map.PixelToLatLong(pixBotRight).Latitude;
    var mapRight = map.PixelToLatLong(pixBotRight).Longitude;
    urlGeoRSS += "?w=" + currWidth + "&h=" + currHeight + "&t=" + mapTop + "&l=" + mapLeft + "&b=" + mapBot + "&r=" + mapRight + "&z=" + map.GetZoomLevel();
    var shapeLayer = new VEShapeLayer();
    var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, urlGeoRSS, shapeLayer);
    return veLayerSpec;
}

function traffic(cb) {
    if (cb.checked) {
        map.LoadTraffic(true);
        map.ShowTrafficLegend(50, 50);
        map.SetTrafficLegendText("Traffic legend");
    }
    map.ClearTraffic();
}

function submitonEnter(evt) {
    var charCode = (evt.which) ? evt.which : event.keyCode
    if (charCode == "13") {
        FindLocation(document.getElementById('txtAddress').value);
    }
}

// Find the requested location on the map
function FindLocation(Address) {
    map.Find(null, Address);
    strAddress = Address;
}

// Add a new pin to the center of the map
function UpdateMap() {
    if (null == pin) {
        $.prompt('Please click Shift + Left Mouse Click to set a Speed Trap to mark.');
    }
    else
        if (document.getElementById("txtStreet").value == "") {
        $.prompt('Please enter a street location.');
    }
    else
        if (document.getElementById("txtCity").value == "") {
        $.prompt('Please enter a city.');
    }
    else
        if (document.getElementById("txtSpeed").value == "") {
        $.prompt('Please enter in a speed. If it is a Red Light Camera, Input 0.');
    }
    else
        if (document.getElementById("txtDescription").value == "") {
        $.prompt('Please write a brief description.');
    }
    else {
        var loc = pin;
        objLatLong = loc;
        UpdateData(objLatLong);
        RefreshMap();
    }
}

// Add or Edit a user's pin in the database
function UpdateData(objLatLong) {
    // Show update status
    // ShowMessageBox("Updating. Please wait ...");



    //Build the url to call the server
    var url = "UpdateMapData.ashx";
    url += "?lat=" + objLatLong.Latitude;
    url += "&lon=" + objLatLong.Longitude;
    url += "&speed=" + encodeURIComponent(document.getElementById("txtSpeed").value);
    url += "&street=" + encodeURIComponent(document.getElementById("txtStreet").value);
    url += "&city=" + encodeURIComponent(document.getElementById("txtCity").value);
    var stateIndex = document.getElementById("txtState").selectedIndex
    url += "&state=" + encodeURIComponent(document.getElementById("txtState")[stateIndex].value);
    url += "&country=" + encodeURIComponent(document.getElementById("txtCountry").value);
    var levelIndex = document.getElementById("levelEnforcement").selectedIndex;
    url += "&levelEnforcement=" + encodeURIComponent(document.getElementById("levelEnforcement")[levelIndex].value);
    url += "&radar=" + encodeURIComponent(document.getElementById("checkRadar").checked);
    url += "&laser=" + encodeURIComponent(document.getElementById("checkLaser").checked);
    url += "&pace=" + encodeURIComponent(document.getElementById("checkPace").checked);
    url += "&plane=" + encodeURIComponent(document.getElementById("checkPlane").checked);
    url += "&photo=" + encodeURIComponent(document.getElementById("checkPhoto").checked);
    url += "&redlight=" + encodeURIComponent(document.getElementById("checkRedlight").checked);
    url += "&description=" + encodeURIComponent(document.getElementById("txtDescription").value);
    url += "&update=false";

    //Start by getting the appropriate XMLHTTP object for the browser
    var xmlhttp = GetXmlHttp();

    //If we have a valid xmlhttp object
    if (xmlhttp) {
        xmlhttp.open("GET", url, true);
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4)  //4 is a success
            {
                //ShowMessageBox("Done! Speed Trap Added. Remember to tell others about the site. Reloading...\n");
                $.prompt('Done! Speed Trap Added. Remember to tell others about the site.');
                LoadTraps();
            }
        }
        xmlhttp.send(null);
    }
}

// Determine which xmlhttp object to use depending on browser
function GetXmlHttp() {
    var x = null;
    try {
        x = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e) {
        try {
            x = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (e) {
            x = null;
        }
    }
    if (!x && typeof XMLHttpRequest != "undefined") {
        x = new XMLHttpRequest();
    }
    return x;
}

function castVote(GeoDataID, vote) {
    var url = "CastVote.ashx?ID=" + GeoDataID + "&v=" + vote;
    var xmlhttp = GetXmlHttp();

    if (xmlhttp) {
        xmlhttp.open("GET", url, true);
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4)  //4 is a success
            {
                ShowMessageBox("Your vote has been recorded. Votes will be recalulated every minute. Thank you.\n");
                LoadTraps();
            }
        }
        xmlhttp.send(null);
    }
}

//Search for Directions
function GetRouteMap() {
    var locations;
    locations = new Array(document.getElementById('txtdrivingfrom').value, document.getElementById('txtdrivingto').value);
    var options = new VERouteOptions;

    // Otherwise what's the point?
    options.DrawRoute = true;

    // So the map doesn't change:
    options.SetBestMapView = true;

    // Call this function when map route is determined:
    options.RouteCallback = ShowTurns;

    // Show as miles
    options.DistanceUnit = VERouteDistanceUnit.Mile;

    // Show the disambiguation dialog
    options.ShowDisambiguation = true;

    map.GetDirections(locations, options);
}

function ShowTurns(route) {
    var turns = "<h3>Turn-by-Turn Directions</h3>(rounding errors are possible)";
    var warnings = "<h3>Caution Areas in Route</h3>(coming soon)"

    // Unroll route and populate DIV
    var legs = route.RouteLegs;
    var leg = null;
    var turnNum = 0;  // The turn #

    // Get intermediate legs
    for (var i = 0; i < legs.length; i++) {
        // Get this leg so we don't have to derefernce multiple times
        leg = legs[i];  // Leg is a VERouteLeg object

        var legNum = i + 1;
        turns += "<br/><b>Distance :</b> " + leg.Distance.toFixed(1) + " miles" +
                           "<br/><b>Time :</b> " + GetTime(leg.Time) + "<br/><br/>";

        // Unroll each intermediate leg
        var turn = null;  // The itinerary leg
        var legDistance = null;  // The distance for this leg

        for (var j = 0; j < leg.Itinerary.Items.length; j++) {
            turnNum++;

            turn = leg.Itinerary.Items[j];  // turn is a VERouteItineraryItem object

            turns += "<b>" + turnNum + "</b>\t" + turn.Text;

            legDistance = turn.Distance;

            // So we don't show 0.0 for the arrival
            if (legDistance > 0) {
                // Round distances to 1/10ths
                turns += " (" + legDistance.toFixed(1) + " miles";

                // Append time if found
                if (turn.Time != null) {
                    turns += "; " + GetTime(turn.Time);
                }

                turns += ")<br/>";
            }
        }

        turns += "<br/>";
    }

    // Populate DIV with directions
    SetDirections(turns);
    SetWarnings(warnings);
}

function SetDirections(s) {
    var d = document.getElementById("directions");
    d.innerHTML = s;
}
function SetWarnings(s) {
    var d = document.getElementById("warnings");
    d.innerHTML = s;
}
// time is an integer representing seconds
// returns a formatted string
function GetTime(time) {
    if (time == null) {
        return ("");
    }

    if (time > 60) {                                 // if time == 100
        var seconds = time % 60;       // seconds == 40
        var minutes = time - seconds;  // minutes == 60
        minutes = minutes / 60;    // minutes == 1


        if (minutes > 60) {                                     // if minutes == 100
            var minLeft = minutes % 60;        // minLeft    == 40
            var hours = minutes - minLeft;   // hours      == 60
            hours = hours / 60;          // hours      == 1

            return (hours + " hour(s), " + minLeft + " minute(s), " + seconds + " second(s)");
        }
        else {
            return (minutes + " minutes, " + seconds + " seconds");
        }
    }
    else {
        return (time + " seconds");
    }
}


// Add a message box to the center of the map
function AddMessageBox() {
    var el = document.createElement("div");
    el.id = "statusmessage";
    el.style.display = "none";
    el.style.padding = "12px 8px 12px 8px";
    el.style.margin = "0px";
    el.style.width = "320px";
    el.style.border = "3px solid #EF9B0F";
    el.style.background = "#EEDC82";
    el.style.pixelTop = (document.getElementById('myMap').clientHeight / 4);
    el.style.pixelLeft = (document.getElementById('myMap').clientWidth / 2) - 200;
    el.innerHTML = "";
    map.AddControl(el);
}

// Show message box with some text
function ShowMessageBox(text) {
    var d = document.getElementById("statusmessage");
    d.style.display = "inline";
    d.innerHTML = text;
    setTimeout(function() { d.style.display = "none"; }, 5000);
}

function hidePopupMenu() {
    var menu = document.getElementById('popupmenu').style.display = 'none';

}

function showPopupMenu(e) {
    if (e.rightMouseButton) {
        var x = map.GetLeft();
        var y = map.GetTop();
        var menu = document.getElementById('popupmenu');
        menu.style.display = 'block'; //Showing the menu
        menu.style.left = e.mapX + x + "px"; //Positioning the menu
        menu.style.top = e.mapY + y + "px";
    }
}

function prepMenu() {
    navRoot = document.getElementById("popupmenu");
    var items = navRoot.getElementsByTagName('li');
    for (i = 0; i < items.length; i++) {
        node = items[i];
        if (node.nodeName == "LI") {
            node.onmouseover = function() {
                this.className += " over"; //Show the submenu
            }
            node.onmouseout = function() {
                if (this.className.indexOf('pmenu') > 0) {
                    this.className = "pmenu";
                }
                else {
                    this.className = "";
                }
            }
        }
    }
}

$(function() {
    $('#st').click(function(e) {
        e.preventDefault();
        jsvar1 = addresscode;
        jsvar2 = citycode;
        jsvar3 = statecode;
        jsvar16 = country;
        var loc = pin;
        objLatLong = loc;
        jarv4 = objLatLong.Latitude;
        jarv5 = objLatLong.Longitude;
        var url1 = '../speedtrap/addtrap.aspx?add=' + jsvar1 + '&city=' + jsvar2 + '&state=' + jsvar3 + '&country=' + jsvar16 + '&lat=' + jarv4 + '&lon=' + jarv5 + '&lvl=1'

        $.nyroModalManual({
            url: url1,
            forceType: 'iframe',
            from: true
        });
        return false;
    });
    $('#rlc').click(function(e) {
        e.preventDefault();
        jsvar6 = addresscode;
        jsvar7 = citycode;
        jsvar8 = statecode;
        jsvar17 = country;
        var loc = pin;
        objLatLong = loc;
        jarv9 = objLatLong.Latitude;
        jarv10 = objLatLong.Longitude;
        var url2 = '../speedtrap/addtrap.aspx?add=' + jsvar6 + '&city=' + jsvar7 + '&state=' + jsvar8 + '&country=' + jsvar17 + '&lat=' + jarv9 + '&lon=' + jarv10 + '&lvl=2'

        $.nyroModalManual({
            url: url2,
            forceType: 'iframe',
            from: true
        });
        return false;
    });
    $('#sc').click(function(e) {
        e.preventDefault();
        jsvar11 = addresscode;
        jsvar12 = citycode;
        jsvar13 = statecode;
        jsvar18 = country;
        var loc = pin;
        objLatLong = loc;
        jarv14 = objLatLong.Latitude;
        jarv15 = objLatLong.Longitude;
        var url3 = '../speedtrap/addtrap.aspx?add=' + jsvar11 + '&city=' + jsvar12 + '&state=' + jsvar13 + '&country=' + jsvar18 + '&lat=' + jarv14 + '&lon=' + jarv15 + '&lvl=3'

        $.nyroModalManual({
            url: url3,
            forceType: 'iframe',
            from: true
        });
        return false;
    });
});