﻿//cosgis namespace
var cosgis = {};

//Google maps
cosgis.map = null;
cosgis.polyline = null;
cosgis.geocoder = null;
cosgis.marker;
//Map servers
//cosgis.map_server = "198.1.35.115";
cosgis.map_server = window.cosgis_map_server;
//Dynamic map
cosgis.dynamic_map_overaly = null;
cosgis.dynamic_map = null;
cosgis.dynamic_map_name = "COS_Crime_WM";
cosgis.dynamic_url = "http://" + cosgis.map_server + "/ArcGIS/rest/services/" + cosgis.dynamic_map_name + "/MapServer";
cosgis.dynamic_service_url = "http://" + cosgis.map_server + "/arcgis/services/" + cosgis.dynamic_map_name + "/MapServer";

cosgis.dynamic_map2 = null;
cosgis.dynamic_map_name2 = "COS_CrimeDensity_WM";
cosgis.dynamic_url2 = "http://" + cosgis.map_server + "/ArcGIS/rest/services/" + cosgis.dynamic_map_name2 + "/MapServer";

cosgis.geometry_service_url = "http://" + cosgis.map_server + "/ArcGIS/rest/services/Geometry/GeometryServer";
cosgis.geometry_service = null;

cosgis.dynamic_opacity = 1.0;
//Map Start Coords
cosgis.LAT = 47.676;
cosgis.LNG = -117.424;
//Zoom level
cosgis.zoom_level = 12;
//Form data
cosgis.form_data = [];
cosgis.form_data["crimeType"] = "All Crimes";

//Identify
cosgis.identify_layer_name = "";
cosgis.identify_layer_id = 16;
cosgis.id_task = null;
cosgis.id_point = null;
cosgis.id_overlays = [];

//Buffer
cosgis.buffer_distance_miles = 0;
cosgis.buffer_distance_feet = 0;
cosgis.buffer_overlays = [];
cosgis.buffer_range = "Month";
cosgis.buffer_radius = 0;

//Overlays
cosgis.map_extension = null;

function load() {
    if (GBrowserIsCompatible()) {
        //
        resizeApp();
        
        //Gmap object
        cosgis.map = new GMap2(document.getElementById("map"));

        //Customize gmap object
        var customUI = cosgis.map.getDefaultUI();
        customUI.controls.scalecontrol = true; //Scale
        customUI.controls.largemapcontrol3d = true; //Zoom
        customUI.controls.maptypecontrol = false; //Default map type control
        customUI.controls.menumaptypecontrol = false; //Menu map type control
        customUI.zoom.scrollwheel = true;  //Scroll zoom
        cosgis.map.setUI(customUI);

        //Map type control
        var mapControl = new GHierarchicalMapTypeControl();
        cosgis.map.addControl(mapControl);

        //Create MapExtension utility class
        cosgis.map_extension = new esri.arcgis.gmaps.MapExtension(cosgis.map);

        //Geocoder
        cosgis.geocoder = new GClientGeocoder();

        //Set Map Center
        var center = new GLatLng(cosgis.LAT, cosgis.LNG);
        cosgis.map.setCenter(center, cosgis.zoom_level);

        //Add dynamic maps
        addDynamicMap2(cosgis.dynamic_url2);
        addDynamicMap(cosgis.dynamic_url);

        //Set up Identify
        GEvent.addListener(cosgis.map, "click", function(overlay, point) {
            doIdentify(overlay, point);
        });

        //Layers active
        GEvent.addListener(cosgis.map, "zoomend", function() {
            if (cosgis.map.getZoom() > 13)
                e("leftLayers").style.color = '#000';
            else
                e("leftLayers").style.color = '#aaa';

        });

        //GeometryService
        cosgis.geometry_service = new esri.arcgis.gmaps.Geometry(cosgis.geometry_service_url);

        //Get Last Data Update
        getLastUpdate();
    }
}

//------------------------------------------------------------//
//--Address Search--//
//------------------------------------------------------------//

//Geocode
function geocodeAddress(address) {
    address = address + " Spokane, WA";
    cosgis.geocoder.getLocations(address, addAddressToMap);
}


//Add structured address to map
function addAddressToMap(response) {
    //cosgis.map.clearOverlays();
    if (!response || response.Status.code != 200) {
        alert("Address not found");
        cosgis.search_new = false;
    } else {
        var place = response.Placemark[0];
        var addr = place.address.split(","); html += "  <br />";
        var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);

        //Write html
        var html = "<div id=\"divResultsWindow\" ><h3>Address:</h3><p>" + addr[0] + "<br>" + addr[1] + ", " + addr[2] + "</p></div>";
        html += "<h3>Crime Stats:</h3>";
        html += "<div style='padding-top:0px; width:100%;'>";
        html += "  <span style='font-size:1.2em;'>Find Crimes Within:</span>";
        html += "  <select id='selectRadius' onchange='searchByRadius();'>";
        html += "    <option value='0.50' selected='selected'>1/2 Mile Radius</option>";
        html += "    <option value='1.0'>1 Mile Radius</option>";
        html += "    <option value='2.0'>2 Mile Radius</option>";
        html += "    <option value='3.0'>3 Mile Radius</option>";
        html += "  </select>";
        html += "  <br />";
        html += "  <br />";
        html += "  <span><input id='btnBufferSearch' type='button' onclick='searchByRadius();' value='Find' /></span>";
        html += "  <span><input id='btnBufferClear' type='button' onclick='clearBuffer();' value='Clear' /></span>";
        html += "</div>";

        //Add points to map
        addMarker(point, html);
        cosgis.id_point = point;

        //
        e('txtSearch').value = addr[0];
    }
}


//Add point and info window to map
function addMarker(pnt, html) {
    //Remove other markers
    removeMarker();
    //Set zoom
    cosgis.map.setZoom(15);
    //Center
    cosgis.map.setCenter(pnt);
    //Create marker and add to map
    cosgis.marker = new GMarker(pnt);
    cosgis.map.addOverlay(cosgis.marker);
    //Info windows options
    var opts = { maxWidth: 250 };
    //Open info window
    cosgis.marker.openInfoWindowHtml(html, opts);
    //Open onclick
    GEvent.addListener(cosgis.marker, "click", function() {
        cosgis.marker.openInfoWindowHtml(html, opts);
    });
}

function removeMarker() {
    if (typeof (cosgis.marker) != 'undefined')
        cosgis.map.removeOverlay(cosgis.marker);
}

//------------------------------------------------------------//
//--BUFFER SEARCH--//
//------------------------------------------------------------//
function searchByRadius() {
    //Buffer radius
    var obj = e('selectRadius');
    if (obj != null) {
        cosgis.buffer_radius = parseFloat(obj.options[obj.selectedIndex].value);
        cosgis.buffer_distance_miles = cosgis.buffer_radius;
        cosgis.buffer_distance_feet = cosgis.buffer_radius * 5280;

        //Date range
        obj = e('selectDate');
        cosgis.buffer_range = obj.options[obj.selectedIndex].value;

        //Buffer parameters
        var buffParams = new esri.arcgis.gmaps.BufferParameters();
        buffParams.unit = esri.arcgis.gmaps.SRUnitType.SURVEY_FOOT;
        buffParams.unionResults = true;  //union results.  The default is false
        buffParams.distances = [cosgis.buffer_distance_feet];
        buffParams.geometries = [cosgis.id_point];

        //Buffer
        cosgis.geometry_service.buffer(buffParams, searchByRadiusCallback);
    }
}

function searchByRadiusCallback(results) {
    //Remove overlay
    cosgis.map_extension.removeFromMap(cosgis.buffer_overlays);
    //Add buffer to map
    cosgis.buffer_overlays = cosgis.map_extension.addToMap(results);
    //Zoom
    if (cosgis.buffer_radius >= 2)
        cosgis.map.setCenter(cosgis.id_point, 14);
    else
        cosgis.map.setCenter(cosgis.id_point, 15);
    //Array of buffer polys
    var bufferPolys = [];
    for (var x = 0; x < results.geometries.length; x++) {
        for (var y = 0; y < results.geometries[x].length; y++) {
            bufferPolys.push(results.geometries[x][y]);
        }
    }
    //Crime Stats
    getCrimeStats(cosgis.id_point);
}

function showCrimeReport() {
    e("divCrimeReport").style.visibility = 'visible';
    e("divCrimeChartWorking").style.display = '';
}
function hideCrimeReport() {
    e("divCrimeReport").style.visibility = 'hidden';
}

function getCrimeStats(pnt) {
    showCrimeReport();
    
    cosgis.ajax_req = getXmlHttpRequestObject();
    if (cosgis.ajax_req.readyState == 4 || cosgis.ajax_req.readyState == 0) {
        cosgis.ajax_req.open("GET", 'callback.ashx?get=cs&lat=' + pnt.lat() + '&lng=' + pnt.lng() + '&miles=' + cosgis.buffer_distance_miles + '&range=' + cosgis.buffer_range, true);
        cosgis.ajax_req.onreadystatechange = displayCrimeStats;
        cosgis.ajax_req.send(null);
    }
}

function displayCrimeStats() {
    if (cosgis.ajax_req.readyState == 4) {
        if (cosgis.ajax_req.responseText.length > 0) {
            var crimeStats = eval('(' + cosgis.ajax_req.responseText + ')');
            //
            var chartData = [];
            var chartLabels = [];
            var barLabels = [];
            var cnt = 0;

            for (cs in crimeStats) {
                chartData.push(crimeStats[cs].Count);
                chartLabels.push(crimeStats[cs].CrimeType);
                barLabels.push('t' + crimeStats[cs].Count + ' (' + crimeStats[cs].Percent + '%),' + '000000,0,' + cnt + ',12');
                cnt++;
            }

            var maxCnt = findMaxInArray(chartData);

            var content = 'http://chart.apis.google.com/chart?cht=bhg&chs=360x360&chd=t:' + chartData.join() + '&chds=0,' + maxCnt + '&chtt=Crimes Within ' + cosgis.buffer_radius + ' Mile(s) - Past ' + cosgis.buffer_range + '&chts=000000,13&chxt=x,y,x&chxl=1:|' + chartLabels.reverse().join("|") + '|2:||Number of Incidents (' + crimeStats[0].Total + ')|&chco=BCC3D7&chbh=20,0,5&chg=8.33,0,5,5&chxr=0,0,' + maxCnt + '&chm=' + barLabels.join("|");
            e("imgCrimeChart").src = content;

            e("divCrimeChartWorking").style.display = 'none';
        }
        cosgis.ajax_req = null;
    }

    
}


function clearBuffer() {
    cosgis.map_extension.removeFromMap(cosgis.buffer_overlays);
}

//------------------------------------------------------------//
//--IDENTIFY--//
//------------------------------------------------------------//
function doIdentify(overlay, point) {
    if (overlay) {
        return;
    }
    var layerid = cosgis.identify_layer_id;
    cosgis.id_task = new esri.arcgis.gmaps.IdentifyTask(cosgis.dynamic_url);
    cosgis.id_point = point;
    var dim = cosgis.map.getSize();

    var idparams = new esri.arcgis.gmaps.IdentifyParameters();
    idparams.geometry = point;
    idparams.tolerance = 5;
    idparams.bounds = cosgis.map.getBounds();
    idparams.width = dim.width;
    idparams.height = dim.height;
    idparams.layerIds = [layerid];
    idparams.layerOption = "all";
    idparams.returnGeometry = true;

    cosgis.id_task.execute(idparams, idCallBack);
}

function idCallBack(idresults) {
    //alert(idresults.toSource());
    if (typeof (idresults.identifyResults[0]) != 'undefined') {
        //Remove overlay
        cosgis.map_extension.removeFromMap(cosgis.buffer_overlays);
        //Attributes for record 0
        var attributes = idresults.identifyResults[0].feature.attributes;
        //Info window
        var html = "<h3>Incident: " + attributes.OFFGEN + "</h3>";
        //var html = "<h3>Incident</h3>";
        html += "<table border=\"0\" cellspacing=\"2\">";
        html += "  <tr class=\"tabCell1\"><td>Crime Code:</td><td>" + attributes.OFFENSE + "</td></tr>";
        html += "  <tr class=\"tabCell2\"><td>Location:</td><td>" + attributes.LOCATION + "</td></tr>";
        html += "  <tr class=\"tabCell1\"><td>When:</td><td>" + attributes.BEGINDATE + "</td></tr>";
        html += "  <tr class=\"tabCell2\"><td>Day of Week:</td><td>" + attributes.DAY_ + "</td></tr>";
        html += "</table>";
        html += "<h3>Crime Stats</h3>";
        html += "<div style='padding-top:0px; width:100%;'>";
        html += "  <span style='font-size:1.2em;'>Find Crimes Within:</span>";
        html += "  <select id='selectRadius' onchange='searchByRadius();'>";
	    html += "    <option value='0.50' selected='selected'>1/2 Mile Radius</option>";
	    html += "    <option value='1.0'>1 Mile Radius</option>";
	    html += "    <option value='2.0'>2 Mile Radius</option>";
	    html += "    <option value='3.0'>3 Mile Radius</option>";
	    html += "  </select>";
	    html += "  <br />";
	    html += "  <br />";
	    html += "  <span><input id='btnBufferSearch' type='button' onclick='searchByRadius();' value='Find' /></span>";
	    html += "  <span><input id='btnBufferClear' type='button' onclick='clearBuffer();' value='Clear' /></span>";
		html += "</div>";
			
        //Add to map
        cosgis.map.openInfoWindow(cosgis.id_point, html);
    }
}


//------------------------------------------------------------//
//--ESRI REST API--//
//------------------------------------------------------------//
//Dynamic layer opacity
function setOp() {
    var val = parseFloat(document.getElementById("divHorizontalSlider").value);
    val = val / 100;
    cosgis.dynamic_map2.setOpacity(val);
}

//Dynamic map
function addDynamicMap(service) {
    var imageParams = new esri.arcgis.gmaps.ImageParameters();
    imageParams.format = "png24";
    imageParams.layerOption = "include";
    cosgis.dynamic_map = new esri.arcgis.gmaps.DynamicMapServiceLayer(service, imageParams, cosgis.dynamic_opacity, dynMapCallBack);
}

function dynMapCallBack(groundov) {
    cosgis.map.addOverlay(groundov);
    cosgis.dynamic_map_overaly = groundov;
}

function addDynamicMap2(service) {
    var imageParams = new esri.arcgis.gmaps.ImageParameters();
    imageParams.format = "png24";
    imageParams.layerOption = "show";
    cosgis.dynamic_map2 = new esri.arcgis.gmaps.DynamicMapServiceLayer(service, imageParams, 0.5, dynMapCallBack2);
}

function dynMapCallBack2(groundov) {
    cosgis.map.addOverlay(groundov);
    cosgis.dynamic_map_overaly = groundov;
}

//Layers
function showLayer(obj) {
    //Highlight selected crime type
    var element = obj.parentNode;
    if (element.hasChildNodes()) {
        for (node in element.childNodes) {
            if (element.childNodes[node].tagName == 'LI') {
                element.childNodes[node].className = "";
            }
        }
    }
    obj.className = "selectedCrime";
    
    //Save selected crime type
    saveFormData("crimeType", obj.id);

    //Date range
    var dateE = e("selectDate");
    var dateRange = dateE.options[dateE.selectedIndex].value;

    //Set visible layers
    cosgis.identify_layer_name = obj.id + " - " + dateRange;
    var layerName = cosgis.identify_layer_name;
    var layerID = findLayerIdByName(cosgis.dynamic_map, layerName);
    cosgis.identify_layer_id = layerID;
    cosgis.dynamic_map.setVisibleLayers([layerID]);

    //Crime density grids
//    if (obj.id == "Arson" || obj.id == "Murder" || obj.id == "Rape") {
//        e("chkHotSpot").disabled = true;
//    } else {
//        e("chkHotSpot").disabled = false;
//    }

    if (e("chkHotSpot").checked) {
        layerName = obj.id + " - " + dateRange;
        layerID = findLayerIdByName(cosgis.dynamic_map2, layerName);
        cosgis.dynamic_map2.setVisibleLayers([layerID]);
    } else {
        cosgis.dynamic_map2.setVisibleLayers([-1]);
    }

    //Regenerate crime stats
    if (e("divCrimeReport").style.visibility == 'visible') {
        searchByRadius();
    }
}

function findLayerIdByName(mapObj, layerName) {
    var layerID = -1;
    var mapLayers = mapObj.layerInfos;
    for (lyr in mapLayers) {
        if (mapLayers[lyr].name == layerName) {
            layerID = mapLayers[lyr].id;
        }
    }
    return layerID;
}

function updateLayers() {
    var crimeType = getFormData("crimeType");
    var selectedLI = e(crimeType);
    showLayer(e(crimeType));
}


//Legend
function GetLegendImage(img) {
    var imageSrc = GetSimpleLegendImage(20, 1.0);
    if (img.src != imageSrc) {
        img.src = imageSrc;
    }
}

function GetSimpleLegendImage(layerID, legOpacity) {
    //legend.ashx?type=single&layerID=19&op=1.0&url=http://198.1.35.115/arcgis/services/COS_Crime_WM/MapServer
    return 'legend.ashx?type=single&layerID=' + layerID + '&op=' + legOpacity + '&url=' + cosgis.dynamic_service_url;
}

//Clear
function clearMap() {
    cosgis.map_extension.removeFromMap(cosgis.buffer_overlays);
    cosgis.map.closeInfoWindow();
    hideCrimeReport();
}

//------------------------------------------------------------//
//--GENERAL PAGE FUNCTIONS--//
//------------------------------------------------------------//
//Resizes map
function resizeApp() {
    var offsetTop = 0;
    var mapElem = e("map");
    var leftElem = e("leftColumn");
    var offsetBottom = 10;

    for (var elem = mapElem; elem != null; elem = elem.offsetParent) {
        offsetTop += elem.offsetTop;
    }

    var height = getWindowHeight() - offsetTop - offsetBottom;
    if (height >= 0) {
        mapElem.style.height = height - 0 + "px";
        leftElem.style.height = height + "px";
    }

    if (cosgis.map) {
        cosgis.map.checkResize();
        cosgis.dynamic_map.refresh();
    }

}

//Get Height
function getWindowHeight() {
    if (window.self && self.innerHeight) {
        return self.innerHeight;
    }
    if (document.documentElement && document.documentElement.clientHeight) {
        return document.documentElement.clientHeight;
    }
    return 0;
}

//Get Element ID
function e(id) { return document.getElementById(id); }

//Save Key Value Pairs
function saveFormData(key, val) {
    cosgis.form_data[key] = val;
}
function getFormData(key) {
    var val = cosgis.form_data[key];
    if (typeof (val) == 'undefined') { val = ''; }
    return val;
}

//Max value
function findMaxInString(s,sep) {
    var max = 0;
    var list = s.split(sep);
    for (i = 0; i < list.length; i++) {
        var val = parseInt(list[i]);
        if (max < val) {
            max = val;
        }
    }
    return max;
}

function findMaxInArray(list) {
    var max = 0;
    for (i = 0; i < list.length; i++) {
        var val = parseInt(list[i]);
        if (max < val) {
            max = val;
        }
    }
    return max;
}

//------------------------------------------------------------//
//---AJAX---//
//------------------------------------------------------------//
function getXmlHttpRequestObject() {
    if (window.XMLHttpRequest) {
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        return new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        alert("This function is not supported by your browser");
    }
}

//------------------------------------------------------------//
//---Last Update---//
//------------------------------------------------------------//

function getLastUpdate() {
    cosgis.ajax_req = getXmlHttpRequestObject();
    if (cosgis.ajax_req.readyState == 4 || cosgis.ajax_req.readyState == 0) {
        cosgis.ajax_req.open("GET", 'callback.ashx?get=dt', true);
        cosgis.ajax_req.onreadystatechange = parseLastUpdate;
        cosgis.ajax_req.send(null);
    }
}

//Build the toc
function parseLastUpdate() {
    if (cosgis.ajax_req.readyState == 4) {
        if (cosgis.ajax_req.responseText.length > 0) {
            //alert(cosgis.ajax_req.responseText);
            e("divMapUpdated").innerHTML = "<strong>Updated:</strong>&nbsp;" + cosgis.ajax_req.responseText;
        }
        cosgis.ajax_req = null;
    }
}




//--Save--//

//function queryWithinBuffer(bufferPolys) {
//    //alert(bufferPolys.toSource());
//    var qtask = new esri.arcgis.gmaps.QueryTask("http://198.1.35.115/ArcGIS/rest/services/COS_Crime_WM/MapServer/3");
//    var query = new esri.arcgis.gmaps.Query();
//    query.returnGeometry = false;
//    query.queryGeometry = bufferPolys;
//    query.outFields = ["OFFGEN"];
//    qtask.execute(query, false, queryCallback);
//}


//function idCallBack1(idresults) {
//    //alert(idresults.toSource());
//    if (typeof (idresults.identifyResults[0]) != 'undefined') {
//        //Attributes for record 0
//        var attributes = idresults.identifyResults[0].feature.attributes;
//        //
//        var tabs = [];
//        //Info window
//        //Tab 1
//        var html = "<h3>" + attributes.OFFGEN + "</h3>";
//        html += "<table border=\"0\" cellspacing=\"2\">";
//        html += "  <tr class=\"tabCell1\"><td>Crime Code:</td><td>" + attributes.OFFENSE + "</td></tr>";
//        html += "  <tr class=\"tabCell2\"><td>Location:</td><td>" + attributes.LOCATION + "</td></tr>";
//        html += "  <tr class=\"tabCell1\"><td>When:</td><td>" + attributes.BEGINDATE + "</td></tr>";
//        html += "  <tr class=\"tabCell2\"><td>Day of Week:</td><td>" + attributes.DAY_ + "</td></tr>";
//        html += "</table>";

//        tabs.push(new GInfoWindowTab("Incident", html));

//        //Tab 2
//        html = "<h3>Buffer Search</h3>";
//        html += "<div style='padding-top:0px;'>";
//        html += "  <span style='font-size:1.2em;'>Find Crimes Within:</span>";
//        html += "  <select id='selectRadius' onchange='searchByRadius();'>";
//        html += "    <option value='0.25' selected='selected'>1/4 Mile Radius</option>";
//        html += "    <option value='0.50'>1/2 Mile Radius</option>";
//        html += "    <option value='1.0'>1 Mile Radius</option>";
//        html += "  </select>";
//        html += "  <br />";
//        html += "  <br />";
//        html += "  <input id='btnBufferSearch' type='button' onclick='searchByRadius();' value='Find' />";
//        html += "</div>";
//        html += "<div id='divCrimeStatsChart' style='width:300px; 300px;'><img src='_images\blank.gif' width='200px' height='300px' /></div>";

//        tabs.push(new GInfoWindowTab("Stats", html));

//        //Add to map
//        cosgis.map.openInfoWindowTabsHtml(cosgis.id_point, tabs);
//    }
//}


//Buffer complete event
//        GEvent.addListener(cosgis.geometry_service, "buffercomplete", function(results) {
//            //Add buffer to map
//            cosgis.map_extension.addToMap(results);

//            //Zoom
//            cosgis.map.setCenter(cosgis.id_point, 15);

//            //Array of buffer polys
//            var bufferPolys = [];
//            for (var x = 0; x < results.geometries.length; x++) {
//                for (var y = 0; y < results.geometries[x].length; y++) {
//                    bufferPolys.push(results.geometries[x][y]);
//                }
//            }

//            queryWithinBuffer(bufferPolys);

//        });

