﻿$(function() {
    var $map = $('#map');
    var $mapButtons = $('#mapButtons');

    // position map buttons so same in all browsers
    $mapButtons.css({ 'left': $map.width() - $mapButtons.width() - 10 + 'px' });
});

dojo.require("esri.map");
dojo.require("dijit.dijit"); // optimize: load dijit layer
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ComboBox");

var map = null;
var streetMap, imageryPrime, ngsTopoUS, waLEGMap, transportationMap;
var identifyTask, identifyParams;
var queryTask;
var startExtent = null;
var graphic;

function updateLocation() {
    //Get the current feature from the featureSet.
    //Feature is a graphic

    var highlightSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 3), new dojo.Color([125, 125, 125, 0.35]));

    graphic.setSymbol(highlightSymbol);
    map.graphics.add(graphic);

    // Show the flag

    showFlag();

    // Center the info window over the extent if there's no latitude and longitude.  Otherwise, show the info window on that point.

    var point;

    if (dojo.byId(longitudeFieldId).value == "" || dojo.byId(latitudeFieldId).value == "")
        point = map.toMap(new esri.geometry.Point(map.width / 2, map.height / 2, new esri.SpatialReference({ wkid: 4326 })));
    else
        point = esri.geometry.geographicToWebMercator(new esri.geometry.Point(parseFloat(dojo.byId(longitudeFieldId).value), parseFloat(dojo.byId(latitudeFieldId).value), new esri.SpatialReference({ wkid: 4326 })));

    map.centerAt(point);

    if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
        showInfoWindow(dojo.byId(districtFieldId).value, point);
    else
        showInfoWindow(dojo.byId(congressionalDistrictFieldId).value, point);
}

function init() {
    var extent;

    // Create the map

    map = new esri.Map("map");
    dojo.connect(map, "onLoad", map.disableScrollWheelZoom);

    // Set the map cursor

    map.setMapCursor("pointer");

    // Get the extent

    if (!startExtent)
        extent = new esri.geometry.Extent({ xmin: -13902955.37154134, ymin: 5682303.033590403, xmax: -12985711.032119472, ymax: 6348833.920236961, spatialReference: { wkid: 102100} });
    else {
        dojo.connect(map, "onLoad", updateLocation);
        extent = startExtent;
    }

    // Set the extent

    map.setExtent(extent, true);

    dojo.connect(map, "onLayerAdd", function(layer) {
        if (map.layerIds.length == 4) {
            waLEGMap = initLayerDynamic("http://maps.leg.wa.gov/ArcGIS/rest/services/LegDistricts/MapServer", "waLEGMap");

            if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
                waLEGMap.setVisibleLayers([1]);
            else
                waLEGMap.setVisibleLayers([0]);

            waLEGMap.setOpacity(0.8);
        }
    });

    // Init the map layers

    streetMap = initLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", "streetMap");
    imageryPrime = initLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", "imageryPrime");
    transportationMap = initLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", "transportationMap");
    ngsTopoUS = initLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer", "ngsTopoUS");

    dojo.connect(map, "onClick", doIdentify);

    identifyTask = new esri.tasks.IdentifyTask("http://maps.leg.wa.gov/ArcGIS/rest/services/LegDistricts/MapServer");
    identifyParams = new esri.tasks.IdentifyParameters();
    identifyParams.tolerance = 0;
    identifyParams.returnGeometry = true;
    identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;

    if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
        identifyParams.layerIds = [1];
    else
        identifyParams.layerIds = [0];
}

function preInit() {
    if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
        queryTask = new esri.tasks.QueryTask("http://maps.leg.wa.gov/ArcGIS/rest/services/LegDistricts/MapServer/1");
    else
        queryTask = new esri.tasks.QueryTask("http://maps.leg.wa.gov/ArcGIS/rest/services/LegDistricts/MapServer/0");

    if (dojo.byId(districtFieldId).value != "") {
        if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
            zoomLocation(dojo.byId(districtFieldId).value);
        else
            zoomLocation(dojo.byId(congressionalDistrictFieldId).value);
    }
    else
        init();
}

function showLayer(id, layer) {
    if (dojo.byId(mapTypeId).value == "Satellite") {
        if (id == "imageryPrime" || id == "transportationMap")
            layer.show();
        else
            layer.hide();
    }
    else if (dojo.byId(mapTypeId).value == "Terrain") {
        if (id == "ngsTopoUS")
            layer.show();
        else
            layer.hide();
    }
    else {
        if (id == "streetMap")
            layer.show();
        else
            layer.hide();
    }
}

function initLayer(url, id) {
    var layer = new esri.layers.ArcGISTiledMapServiceLayer(url, { id: id });
    if (layer.loaded) {
        map.addLayer(layer);
        showLayer(id, layer);
    } else {
        dojo.connect(layer, "onLoad", function() {
            map.addLayer(layer);
            showLayer(id, layer);
        });
    }
    return layer;
}

function changeMap(layers) {
    hideImageTiledLayers(layers);
    for (var i = 0; i < layers.length; i++) {
        // Set the map type

        if (layers[i] == streetMap)
            dojo.byId(mapTypeId).value = "Map";
        else if (layers[i] == imageryPrime)
            dojo.byId(mapTypeId).value = "Satellite";
        else if (layers[i] == ngsTopoUS)
            dojo.byId(mapTypeId).value = "Terrain";

        layers[i].show();
    }
}

function hideImageTiledLayers(layers) {
    for (var j = 0, jl = map.layerIds.length; j < jl; j++) {
        var layer = map.getLayer(map.layerIds[j]);
        if (dojo.indexOf(layers, layer) == -1) {
            layer.hide();
        }
    }
}

function initLayerDynamic(url, id) {
    var layer = new esri.layers.ArcGISDynamicMapServiceLayer(url, { id: id });
    if (layer.loaded) {
        map.addLayer(layer);
    } else {
        dojo.connect(layer, "onLoad", function() {
            map.addLayer(layer);
        });
    }
    return layer;
}

function zoomLocation(value) {
    var instQuery;
    instQuery = new esri.tasks.Query();
    instQuery.returnGeometry = true;
    instQuery.outSpatialReference = new esri.SpatialReference({ wkid: 102100 });

    if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked) {
        instQuery.outFields = ["DISTRICT", "SHAPE"];
        instQuery.where = "DISTRICT=" + value;
    }
    else {
        instQuery.outFields = ["CDFP", "SHAPE"];
        instQuery.where = "CDFP='" + value + "'";
    }

    queryTask.execute(instQuery, zoomLocationResults);
}

function showFlag() {
    // Exit if longitude and latitude aren't set

    if (dojo.byId(longitudeFieldId).value == "" && dojo.byId(latitudeFieldId).value == "")
        return;

    // Set up the picture marker

    var normalpictureMarkerSymbol = new esri.symbol.PictureMarkerSymbol('images/flagNormal.png', 30, 30);
    normalpictureMarkerSymbol.xoffset = 15;
    normalpictureMarkerSymbol.yoffset = 15;

    // Add graphic to the map graphics layer.

    var flagGraphic = new esri.Graphic(esri.geometry.geographicToWebMercator(new esri.geometry.Point(parseFloat(dojo.byId(longitudeFieldId).value), parseFloat(dojo.byId(latitudeFieldId).value), new esri.SpatialReference({ wkid: 4326 }))), normalpictureMarkerSymbol);
    map.graphics.add(flagGraphic);
}

//This function gets called when the combo box in the upper right of the application is changed.
//Specifically gets called from zoomNeighboorhood function above is executed and resultant polygon is found as a result
//Highlights the chosen neighborhood with a graphic on the map and zooms into it.
function zoomLocationResults(results) {
    //QueryTask returns a featureSet.  Loop through features in the featureSet and add them to the map.
    for (var i = 0, il = results.features.length; i < il; i++) {
        // Get the extent

        graphic = results.features[i];
        startExtent = graphic.geometry.getExtent().expand(1.5);

        // Init the map

        if (map) {
            map.setExtent(startExtent, true);
            updateLocation();
        }
        else
            init();
    }
}

function doIdentify(evt) {
    map.graphics.clear();
    showFlag();
    identifyParams.geometry = evt.mapPoint;
    identifyParams.mapExtent = map.extent;
    identifyTask.execute(identifyParams, function(idResults) { addToMap(idResults, evt); });
}

function addToMap(idResults, evt) {

    for (var i = 0, il = idResults.length; i < il; i++) {
        var idResult = idResults[i].feature;
        var highlightSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 3), new dojo.Color([125, 125, 125, 0.35]));
        idResult.setSymbol(highlightSymbol);
        map.graphics.add(idResult);

        if (evt != null) {
            if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
                showInfoWindow(idResult.attributes.DISTRICT, evt.mapPoint);
            else
                showInfoWindow(idResult.attributes.CDFP, evt.mapPoint);
        }
    }
}

function showInfoWindow(district, point) {
    // If we don't show the info window on load, set it to true and exit

    if (!showInfoWindowOnLoad) {
        showInfoWindowOnLoad = true;
        return;
    }

    var url;

    if (dojo.byId(legislativeLayerId) == null || dojo.byId(legislativeLayerId).checked)
        url = 'DistrictHandler.ashx?district=' + district;
    else
        url = 'CongressionalDistrictHandler.ashx?district=' + district;

    // Pop up the info window automatically

    dojo.xhrGet({
        // Location of the HTML content we want to grab
        url: url,

        // Called when the page loaded successfully
        load: function(data) {
            var title = appendNumericSuffix(district) + " District Legislators";
            map.infoWindow.setTitle(title);
            map.infoWindow.setContent(data);
            map.infoWindow.show(map.toScreen(point), map.getInfoWindowAnchor(map.toScreen(point)));
        }
    });
}

/// <summary>
/// Append the appropriate suffix to the integer
/// </summary>
/// <param name="number">number</param>
/// <returns>string with number and appropriate suffix</returns>
function appendNumericSuffix(number) {
    //  Add numeric suffix
    if (number > 10 && number < 20) {
        //  Numbers in the teens always end with th
        return number + "<sup>th</sup>";
    }
    else {
        //  Check remainder
        switch (number % 10) {
            case 1:
                return number + "<sup>st</sup>";
            case 2:
                return number + "<sup>nd</sup>";
            case 3:
                return number + "<sup>rd</sup>";
            default:
                return number + "<sup>th</sup>";
        }
    }
}

dojo.addOnLoad(preInit);

$(function() {
    $('body').attr('class', 'tundra');
});
