﻿var DIALOG_OPTS = { resizable: false, draggable: false, modal: true, closeOnEscape: true };

// String prototype for trim
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };

// Fake console for other browsers
if (typeof (console) === 'undefined') {
    console = { log: function() { } };
}

// Search Parameter Parser
jQuery.parseParams = function(s) {
    var r = {};
    //var q = s.substring(s.indexOf('?') + 1); // remove everything up to the ?
    var q = s;
    q = q.replace(/\&$/, ''); // remove the trailing &
    jQuery.each(q.split('&'), function() {
        var splitted = this.split('=');
        var key = splitted[0];
        var val = splitted[1];
        // convert floats
        if (/^[0-9.]+$/.test(val)) val = parseFloat(val);
        // ignore empty values
        if (typeof val == 'number' || val.length > 0) r[key] = val;
    });
    return r;

};

// Geocode calc stuff
var GeoCodeCalc = {};
GeoCodeCalc.EarthRadiusInMiles = 3956.0;
GeoCodeCalc.EarthRadiusInKilometers = 6367.0;
GeoCodeCalc.ToRadian = function(v) { return v * (Math.PI / 180); };
GeoCodeCalc.DiffRadian = function(v1, v2) {
    return GeoCodeCalc.ToRadian(v2) - GeoCodeCalc.ToRadian(v1);
};
GeoCodeCalc.CalcDistance = function(lat1, lng1, lat2, lng2, radius) {
    return radius * 2 * Math.asin(Math.min(1, Math.sqrt((Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.cos(GeoCodeCalc.ToRadian(lat1)) * Math.cos(GeoCodeCalc.ToRadian(lat2)) * Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lng1, lng2)) / 2.0), 2.0)))));
};

/* *************************************************************************** */
/* Written Chris Pietschmann (http://pietschsoft.com) */
/* This code is dependant on the GeoCodeCalc class found here: */
/* http://pietschsoft.com/Blog/Post.aspx?PostID=1453 */
/* *************************************************************************** */
/* This mathimatical code is a modified version of the code originally posted */
/* at the following location: *//* http://viavirtualearth.com/Wiki/Draw+a+circle.ashx */
/* *************************************************************************** */
GeoCodeCalc.ToDegrees = function(radians) { return radians * 180 / Math.PI; };
function CreateCircle(loc, radius, units) {
    var earthRadius = parseFloat(units);
    var lat = GeoCodeCalc.ToRadian(loc.Latitude); //radians
    var lon = GeoCodeCalc.ToRadian(loc.Longitude); //radians
    var d = parseFloat(radius) / earthRadius; // d = angular distance covered on earth's surface
    var locs = new Array();
    for (x = 0; x <= 360; x++) {
        var p2 = new VELatLong(0, 0)
        brng = GeoCodeCalc.ToRadian(x); //radians
        var latRadians = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));
        var lngRadians = lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(latRadians));
        locs.push(new VELatLong(GeoCodeCalc.ToDegrees(latRadians), GeoCodeCalc.ToDegrees(lngRadians)));
    }
    return new VEShape(VEShapeType.Polyline, locs);
}

var map = null;
var results = [];
var selected_result = null;
var curr_ajax = null;
var addressResults = [];
var addressResultId = 0;

function GetMapIconHtml(icon, color, classes, shape) {
    color = color || "#fff";
    classes = classes || "";
    var count = null;
    if (shape != null) {
        count = "(" + shape.count + ")";
    }
    else { count = ""; }
    
    //return '<span class="map-icon" style="background-color: ' + color + ';"><img src="/Content/' + icon + '.png" /><br/>(9)</span>';
    return '<span class="map-icon ' + classes + '" style="background-color: ' + color + ';"><img src="/Content/' + icon + '.png" /><br/>' + count + '</span>';

}

function GetLegendIconHtml(icon) {
    //return '<span class="map-icon" style="background-color: ' + color + ';"><img src="/Content/' + icon + '.png" /><br/>(9)</span>';
    return '<span class="legend-icon"><img src="/Content/' + icon + '.png" /></span>';

}


function GetMap() {
    map = new VEMap('map');
    //map.SetDashboardSize(VEDashboardSize.Normal);
    //http:msdn.microsoft.com/en-us/library/ee692181.aspx
    map.AttachEvent("oncredentialserror", MyHandleCredentialsError);
    map.AttachEvent("oncredentialsvalid", MyHandleCredentialsValid);

    map.SetCredentials("AgpeKdb9G-n7nPsXaP94LbHWqOtaBPd8PlFeWQoyfi2RIbNzIhzxzx4oUA5esRwU");

    map.LoadMap(new VELatLong(centerLat, centerLong), 13, VEMapStyle.Road, false);

    map.AttachEvent("onendpan", OnEndMapPan);

    DefaultMapZoom();
}

function MyHandleCredentialsError() {
    alert("The credentials are invalid.");
}

function MyHandleCredentialsValid() {
    //alert("The credentials are valid.");

}

var visibleResults = [];
function OnEndMapPan() {
    for (var i = 0; i < visibleResults.length; i++) {
        visibleResults[i].Show();
    }

    UpdateShowHideButtons();
}

function HideVisibleLayers() {
    visibleResults = [];
    for (var i = 0; i < results.length; i++) {
        if (results[i].layer.IsVisible()) {
            visibleResults.push(results[i].layer);
            results[i].layer.Hide();
        }
    }
}

function DefaultMapZoom() {
    //map.SetCenterAndZoom(new VELatLong(centerLat, centerLong), 13);

    var shape = CreateCircle(new VELatLong(centerLat, centerLong), viewArea, GeoCodeCalc.EarthRadiusInMiles);
    var fakeLayer = new VEShapeLayer();
    fakeLayer.AddShape(shape);

    // zoom to our radius
    map.SetMapView(fakeLayer.GetBoundingRectangle());
}

function GetTopLeft() {
    return map.PixelToLatLong(new VEPixel(0, 0));
}

function GetBottomRight() {
    var w = $('#map').width();
    var h = $('#map').height();
    return map.PixelToLatLong(new VEPixel(w, h));
}

function GetBounds() {
    alert("Top Left: " + GetTopLeft().toString() + "\nBottom Right: " + GetBottomRight().toString());
}

function showError(message, title) {
    title = title || 'An Error Occurred';

    $('<p>' + message + '</p>').dialog({ modal: true, title: title });
}

var mCustomLocation = null;
function FindLoc(query, params, replaceId) {

    try {
        var resultShape = new VEShapeLayer;
        map.Find(
            null,
            query,
            null,
            null,
            0,
            10,
            false, //showResults
            false, //createResults
            false, //useDefaultDisambiguation
            false, //setBestMapView
            function(shapeLayer, results, places, moreResults, errorMessage) {

                if (errorMessage != undefined) {
                    $('#formPerformSearch .indicator').hide();
                    showError(errorMessage);
                    return;
                }

                if (!places || places.length == 0) {
                    $('#formPerformSearch .indicator').hide();
                    showError('A match could not be found for the location. Please check your spelling, enter the complete address including country name and commas, and try again.');
                    return;
                }

                if (places.length > 1) {
                    // disambiguation
                    var str = "<table id='disambiguation' style='border: 0;'>";
                    for (var i = 0; i < places.length; i++) {
                        str += "<tr><td><span class='ui-icon' style='visibility: hidden;' /></td><td><a href='#" + i + "' class='place'>" + places[i].Name + "</a></td></tr>";
                    }
                    str += "</table>";

                    $('a.place').live('click', function(e) {
                        e.preventDefault();

                        $('#disambiguation .ui-icon').remove();
                        $(this).parent().prev().html('<span class="ui-icon ui-icon-circle-check" />');
                    });

                    $(str).dialog({
                        modal: true,
                        buttons: {
                            Ok: function() {
                                var idx = $('.ui-icon-circle-check').parent().next().find('a').attr('href').replace('#', '');

                                if (idx != undefined) {
                                    mCustomLocation = places[idx];
                                    $(this).dialog('close');
                                }
                            }
                        },
                        close: function(event, ui) {
                            if (mCustomLocation != null) {
                                PerformSearch(params, replaceId);
                            }
                            else {
                                //user cancelled
                                $('#formPerformSearch .indicator').hide();
                            }
                        }
                    });
                }
                else {
                    mCustomLocation = places[0];
                    PerformSearch(params, replaceId);
                }
            }
        );
    }
    catch (e) {
        //alert(e.message);
        $('<div title="Error">' + e.message + '</div>').dialog(DIALOG_OPTS);
    }

}

function ShowResultInfo(response) {
    var gridHeaders = ['Latitude', 'Longitude'];
    var gridModel = [
            { name: 'latitude', index: 'latitude', width: 139, align: "right" },
            { name: 'longitude', index: 'longitude', width: 139, align: "right" }
        ];

    var wLoc = 300;
    var wDate = 140;
    var wTime = 110;
    var wIncNum = 146;
    var wVio = 354;
    var wCfsNum = 146;
    var wType = 200;

    switch (response.ModuleId) {
        case 11: // Incident
        case 21: // Arrest
            gridHeaders = ['Primary Violation', 'Location', 'Incident #', 'Date', 'Time'];
            gridModel = [
                { name: 'Violation', index: 'PrimaryViolation', width: wVio },
                { name: 'Location', index: 'Location', width: wLoc },
                { name: 'IncidentNumber', index: 'IncidentNumber', width: wIncNum },
                { name: 'Date', index: 'Date', width: wDate, sorttype: "date", datefmt: "m/d/y" },
                { name: 'Time', index: 'Time', width: wTime, sortable: false }
            ];
            break;

        case 20: // Citation
            gridHeaders = ['Violation', 'Citation Type', 'Location', 'Incident #', 'Date', 'Time'];
            gridModel = [
                { name: 'Violation', index: 'PrimaryViolation', width: wVio },
                { name: 'CodeType', index: 'CodeType', width: wType },
                { name: 'Location', index: 'Location', width: wLoc },
                { name: 'IncidentNumber', index: 'IncidentNumber', width: wIncNum },
                { name: 'Date', index: 'Date', width: wDate, sorttype: "date", datefmt: "m/d/y" },
                { name: 'Time', index: 'Time', width: wTime, sortable: false }
            ];
            break;

        case 15: // Accident
            gridHeaders = ['Incident #', 'Location', 'Date', 'Time'];
            gridModel = [
                { name: 'IncidentNumber', index: 'IncidentNumber', width: wIncNum },
                { name: 'Location', index: 'Location', width: wLoc },
                { name: 'Date', index: 'Date', width: wDate, sorttype: "date", datefmt: "m/d/y" },
                { name: 'Time', index: 'Time', width: wTime, sortable: false }
            ];
            break;

        case 19: // CallForService
            gridHeaders = ['Call Reason', 'Location', 'Call #', 'Date', 'Time'];
            gridModel = [//
                {name: 'CallReason', index: 'CallReason', width: wVio },
                { name: 'Location', index: 'Location', width: wLoc },
                { name: 'CallNumber', index: 'CallNumber', width: wCfsNum },
                { name: 'Date', index: 'Date', width: wDate, sorttype: "date", datefmt: "m/d/y" },
                { name: 'Time', index: 'Time', width: wTime, sortable: false }
            ];
            break;
    }

    //gotsa unload the grid so the correct gridHeaders are used for 
    if ($("#divResultInfo").GridUnload !== undefined) {
        $("#divResultInfo").GridUnload()
    }

    $("#divResultInfo").jqGrid({
        datatype: "local",
        colNames: gridHeaders,
        colModel: gridModel,
        imgpath: "/Scripts/themes/steel/images",
        height: "500px",
        width: 570,
        viewrecords: true,
        onSelectRow: function(id) {
            var item = selected_result.results.Results[id - 1];
            var shape = item.shape;
            shape.SetTitle(GetItemTitle(item.ModuleId, item));
            shape.SetDescription(GetItemDescription(item.ModuleId, item));

            map.SetMapView(shape.GetPoints());
            map.HideInfoBox();
            map.ShowInfoBox(shape, new VELatLong(shape.Latitude, shape.Longitude), new VEPixel(30, 10));
        }
    });

    $("#divResultInfo").setCaption("Search Results (" + response.Results.length + ")");
    $("#divResultInfo").clearGridData();
    for (var i = 0; i < response.Results.length; i++) {
        response.Results[i]['id'] = i + 1;
        $("#divResultInfo").addRowData(i + 1, response.Results[i]);
    }
    
    //sort by location
    $('#divResultInfo').sortGrid('Location', false); //.sortGrid('Location', false);

    // display search info
    $('#selected-search-title').html(selected_result.title);
    $('#selected-search-info').html(selected_result.info);

    // hide close button
    $('a.ui-jqgrid-titlebar-close').hide();

    // HACK: this fixes row columns not lining up with header columns
    $('#jqgh_title').click();

    UpdateShowHideButtons();
}

function UpdateShowHideButtons() {
    // show the proper show/hide button
    if (selected_result && selected_result.layer.IsVisible()) {
        $('a.button.show').hide();
        $('a.button.hide').show();
    }
    else {
        $('a.button.show').show();
        $('a.button.hide').hide();
    }
}

function UpdateSelectedResults() {
    var selected = $('#selectResults option:selected').val();
    selected_result = results[selected];

    ShowResultInfo(selected_result.results)

    if (selected_result.results.Results.length > 0) {
        map.SetMapView(selected_result.layer.GetBoundingRectangle());
    }
}

function ShowHelp(button) {
    button = $(button);

    var message = "No help available.";
    if (button.hasClass("date")) {
        message = "Date fields accept the following formats:<ul><li>M/D/YY</li><li>M/D/YYYY</li><li>MM/DD/YY</li><li>MM/DD/YYYY</li></ul>";
    }
    else if (button.hasClass("time")) {
        message = "Time fields must be entered in 24-Hour format. The following are accepted:<ul><li>H:MM</li><li>HH:MM</li></ul>";
    }
    else if (button.hasClass("list")) {
        message = "List fields accept comma delimited values:<ul><li>Item1,Item2,Item3</li><li>Item 1, Item 2, Item 3</li></ul>";
    }

    $('<div title="Help">' + message + '</div>').dialog(DIALOG_OPTS);
}

function Validate() {
    var fail = false;
    $('#formPerformSearch :input:visible').each(function(i) {
        var valid = true;
        if ($(this).hasClass('date')) {
            valid = $(this).val().match(/^\d{1,2}\/\d{1,2}\/\d\d(\d\d)?$/);
            fail = !valid || fail;
        }
        else if ($(this).hasClass('time')) {
            valid = $(this).val().match(/^\d{1,2}:\d\d$/);
            fail = !valid || fail;
        }
        else {
            valid = $(this).val() !== '';
            fail = !valid || fail;
        }

        if (valid) {
            $(this).removeClass('ui-state-error');
        }
        else {
            $(this).addClass('ui-state-error');
        }
    });

    //    console.log('validates: ' + !fail);
    return !fail;
}

function PerformSearch(params, replaceId) {
    var form = $('#formPerformSearch');

    $('#formPerformSearch a.indicator').show();

    try {
        if ($('#predefinedArea').val() === 'c') {
            if (mCustomLocation == null) {
                var query = $('#predefinedAreaCustom input').val();
                FindLoc(query, params, replaceId);
                return;
            }
            else {
                var shape = CreateCircle(mCustomLocation.LatLong, 0.5, GeoCodeCalc.EarthRadiusInMiles);
                var layer = new VEShapeLayer();
                layer.AddShape(shape);

                var rect = layer.GetBoundingRectangle();
                //TODO: might need to urlencode this
                params += '&topLeft=' + rect.TopLeftLatLong.toString();
                params += '&btmRight=' + rect.BottomRightLatLong.toString();
            }
        }

        curr_ajax = $.ajax({
            url: form.attr('action'),
            type: form.attr('method'),
            dataType: "json",
            data: params,
            success: function(data) {
                if (data.Results.length === 0) {
                    showError("Nothing matches your selections. Please try again with different selections.", "No Results Found");
                    return;
                }

                var layer = new VEShapeLayer();
                //2010-10-15 (ryoe) OTB7889 performance issue with large data sets...
                //let's try adding the layer to the map AFTER all of the shapes are added to the layer
                //map.AddShapeLayer(layer);


                var idx = 1;
                for (var item in data.Results) {
                    item = data.Results[item];
                    item.ModuleId = data.ModuleId;

                    //alert("result");
                    //idx++;
                    var shape = GetExistingVEShape(layer, item);

                    if (shape == null) {
                        shape = new VEShape(VEShapeType.Pushpin, new VELatLong(item.Latitude, item.Longitude));
                        shape.count = 1;
                        shape.ModuleId = data.ModuleId;
                        //set title and description on first shape
                        //afterward... title and description must be set upon selection of the item in the grid
                        shape.SetTitle(ShapeTitleFromItem(item));
                        shape.SetDescription(GetItemDescription(item.ModuleId, item));
                        layer.AddShape(shape);
                    }

                    //every item must be linked to shape.
                    item.shape = shape;
                    
                    //always update the custom Icon HTML
                    //only update the html one-time...
                    //shape.SetCustomIcon(ShapeIconHtmlFromShape(shape,"",""));
                }

                var numShapes = layer.GetShapeCount();
                for (var i = 0; i < numShapes; i++) {
                    var shp = layer.GetShapeByIndex(i);
                    //only update the html one-time...
                    shp.SetCustomIcon(ShapeIconHtmlFromShape(shp, "", ""));
                }

                //2010-10-15 (ryoe) OTB7889 performance issue with large data sets...
                //let's try adding the layer to the map AFTER all of the shapes are added to the layer
                //map.ClearInfoBoxStyles();
                map.AddShapeLayer(layer);

                //store for later
                var search = {
                    title: $('#searches option:selected').text(),
                    info: data.Descriptor,
                    params: params,
                    results: data,
                    layer: layer
                };

                if (typeof (replaceId) === 'undefined') {
                    results.push(search);
                    replaceId = results.length - 1;

                    //update results pane
                    $("#selectResults").append('<option value="' + replaceId + '" selected="selected">' + $('#search option:selected').text() + ' (' + data.Results.length + ' results)</option>');
                    $("#divResults").show();

                }
                else {
                    results[replaceId] = search;
                    var text = $('#selectResults option:selected').text().replace(/\(\d+ results\)$/, "(" + data.Results.length + " results)");
                    $('#selectResults option:selected').text(text);
                }

                UpdateSelectedResults();

                $('#no-searches').hide();
                $('#old-searches').show();

                $('#search-tab').show().find('a').click();
                //$('#formPerformSearch :input').val('');
                //2010-10-15 (ryoe) OTB7830/OTB7529 stop hiding the search params!!!
                //$('#predefinedAreaCustom, #dateCustom').hide();
            },
            //        error: function(response) { console.log(response); },
            complete: function() {
                $('#old-searches *').removeAttr('disabled');
                $('#divPredefinedSearches *').removeAttr('disabled');
                $('#formPerformSearch a.indicator').hide();

                curr_ajax = null;

                $('#TB_closeWindowButton').click();
            }
        });
    } catch (err) {
        showError("An error occurred while searching. Please check your parameters and try again.");
        $('#formPerformSearch a.indicator').hide();
    }
}

function ShapeIconHtmlFromShape(shape,color,classes) {
    var html = GetMapIconHtml(GetIcon(shape.ModuleId),color,classes,shape);
    return html;

}

function ShapeTitleFromItem(item) {
    return GetItemTitle(item.ModuleId, item);
}

//Get an existing VEShape, return null otherwise
function GetExistingVEShape(veLayer,item) {
    //var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(item.Latitude, item.Longitude));
    var veLatLong = new VELatLong(item.Latitude, item.Longitude);
    var latLong = null;
    var numShapes = veLayer.GetShapeCount();
    var shape = null;

    for (var i = 0; i < numShapes; i++) {
        var s = veLayer.GetShapeByIndex(i);
        //yep, we're assuming we're a "PushPin" shape
        latLong = s.GetPoints()[0];

        if (veLatLong.Latitude == latLong.Latitude
                && veLatLong.Longitude == latLong.Longitude) {
            shape = s;
            shape.count = shape.count + 1;
            break;
        }
    }
    return shape;
}

//function GetSearchInfo(selector) {
//    selector = $(selector);
//    fake = selector.clone();

//    selector.find('select').each(function() {
//        $(fake).find('select[name=' + $(this).attr('name') + '] option:not([value=' + $(this).val() + '])').remove();
//    });

//    fake.find(':not(:input)').remove();
//    
//    // handle selects
//    var text = fake.find('option').val('').end() // blank the option values that remain so they don't show
//        .html();

//    console.log(text);

//    return text.replace(/<\/li>/g, "\n")
//        .replace(/value=\"(.*?)\"/g, '>$1 <') // handle values wrapped in double quotes
//        .replace(/value=\'(.*?)\'/g, '>$1 <') // handle values wrapped in single quotes
//        .replace(/<.*?>/g, ' ').replace(/ +/g, ' ').replace(/\s*\n\s*/g, "<br />").trim();
//}

function GetIcon(moduleId) {
    switch (moduleId) {
        case 11: // Incident
            return "Incident";
        case 20: // Citation
            return "Citation";
        case 21: // Arrest
            return "Arrest";
        case 15: // Accident
            return "Accident";
        case 19: // CallForService
            return "CallForService";
    }

    return "";
}

function GetItemTitle(moduleId, item) {
    switch (moduleId) {
        case 11: // Incident
        case 20: // Citation
        case 21: // Arrest
            return item.Violation;

        case 15: // Accident
            return item.IncidentNumber;

        case 19: // CallForService
            return item.CallNumber;
    }

    return item.Location;
}

function GetItemDescription(moduleId, item) {
    switch (moduleId) {
        case 11: // Incident
        case 21: // Arrest
            return "Incident Number: " + item.IncidentNumber + "<br />" +
                "Date: " + item.Date + "<br />" +
                "Time: " + item.Time + "<br />" +
                "Location: " + item.Location;
        case 20: // Citation
            return "Code Type: " + item.CodeType + "<br />" +
               "Incident Number: " + item.IncidentNumber + "<br />" +
                "Date: " + item.Date + "<br />" +
                "Time: " + item.Time + "<br />" +
                "Location: " + item.Location;

        case 15: // Accident
            return "Date: " + item.Date + "<br />" +
                "Time: " + item.Time + "<br />" +
                "Location: " + item.Location;
        case 19: // CallForService
            return "Call #: " + item.CallNumber + "<br />" +
                "Call Reason: " + item.CallReason + "<br />" +
                 "Date: " + item.Date + "<br />" +
                "Time: " + item.Time + "<br />" +
                "Location: " + item.Location;
    }

    return item.Location;
}

function PrintCurrentResults() {
    var newwindow2 = window.open('', 'results');
    var tmp = newwindow2.document;
    tmp.write('<html><head><title>' + selected_result.title + '</title>');
    //tmp.write('<link rel="stylesheet" href="Print.css">');
    tmp.write('</head><body><table></table></body></html>');

    $(tmp).find('table').append($('#divResultInfo').html().replace(/style=".*?"/ig, ""));
    tmp.close();
}

/*
function BindDynamicSearch() {
$('a.button.search').click(function(e) {
e.preventDefault();
if ($(this).attr('disabled') === "disabled") { return false; }
$(this).parent('form').submit();
});

$('#formPerformSearch').submit(function(e) {
e.preventDefault();

if (!Validate()) { return false; }

var form = $(this);
var params = form.serialize();

PerformSearch(params);
});
}
*/

$(function() {

    $('#city').change(function() {
        var that = $(this);
        if (that.val() == "") {
            //            $('#search2, #search3, #search4, #search5').hide();
        } else {

            //make ajax call to get predefined areas and searches
            $.ajax({
                url: '/Ajax/GetPredefinedAreas',
                type: 'get',
                data: { agencyId: that.val() },
                dataType: 'text',
                success: function(data) {
                    $('#divPredefinedAreas').html(data);
                    //                    $('#search2').show();
                }
            });

            $.ajax({
                url: '/Ajax/GetSearches',
                type: 'get',
                data: { agencyId: that.val() },
                dataType: 'text',
                success: function(data) {
                    $('#divPredefinedSearches').html(data);
                    //                    $('#search3').show();
                }
            });
        }
    });

    //    $('#predefinedArea').live('change', function() {
    //        var that = $(this);
    //        var agencyId = $('#city').val();
    //        if (that.val() == "") {
    //            //            $('#search3, #search4, #search5').hide();
    //        } else {

    //            //make ajax call to get predefined areas and searches
    //            $.ajax({
    //                url: '/Ajax/GetSearches',
    //                type: 'get',
    //                data: { agencyId: agencyId },
    //                dataType: 'text',
    //                success: function(data) {
    //                    $('#divPredefinedSearches').html(data);
    //                    //                    $('#search3').show();
    //                }
    //            });

    //        }
    //    });

    $('#search').live('change', function() {
        var that = $(this);
        var agencyId = $('#city').val();
        //        if (that.val() == "") {
        //            $('#search4, #search5').hide();
        //        } else {
        //            $('#search4').show();
        //        }
    });


    $('#date').live('change', function() {
        var that = $(this);
        var agencyId = $('#city').val();
        //        if (that.val() == "") {
        //            $('#search5').hide();
        //        } else {
        //            $('#search5').show();
        //        }
    });

    $('#formPerformSearch a.button.search').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }

        mCustomLocation = null; //blank the "find" location before searching again
        $('#formPerformSearch').submit();
    });

    $('#formPerformSearch').submit(function(e) {
        e.preventDefault();

        if (!Validate()) { return false; }

        var form = $(this);
        var params = form.serialize();

        PerformSearch(params);
    });

    $('a.indicator').live('click', function(e) {
        e.preventDefault();

        if (curr_ajax !== null) {
            curr_ajax.abort();
            curr_ajax = null;

            // TODO: a better way?
            // release controls
            $('[disabled]').removeAttr('disabled');

            //hide ourself
            $(this).hide();
        }
    });

    $('.ui-state-default.button').live('mouseover', function() {
        $(this).addClass('ui-state-hover');
        $(this).removeClass('ui-state-default');
    });

    $('.ui-state-hover.button').live('mouseout', function() {
        $(this).removeClass('ui-state-hover');
        $(this).addClass('ui-state-default');
    });

    $('a.button.help').live('click', function(e) {
        e.preventDefault();
        ShowHelp(this);
    });

    // initialize tabs
    $('#tabs').tabs();

    // set up toggle for sidebar headers
    /*$('#sidebar h3 > span').click(function() {
    $(this).parent().next().slideToggle('slow');
    return false;
    });*/
    $('#accordion').accordion({ fillSpace: true, active: 2 });

    $('#divPredefinedSearches a.button.refresh').live('click', function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }

        var that = this;
        $(that).hide();

        //$('#formSearchChange *').hide();
        $('#divPredefinedSearches a.indicator').show();

        $('#divPredefinedSearches select').remove();

        //$('#searchControls').html('');

        curr_ajax = $.ajax({
            url: '/Ajax/GetSearches',
            type: 'get',
            dataType: 'text',
            success: function(data) {
                $('#divPredefinedSearches *').remove();
                $('#divPredefinedSearches').prepend(data);

                //$('#formSearchChange *').show();
            },
            complete: function() {
                $(that).css('display', 'inline');
                $('#divPredefinedSearches a.indicator').hide();
                curr_ajax = null;
            }
        });
    });

    /*
    $('#divPredefinedSearches a.button.select').click(function(e) {
    e.preventDefault();
    if ($(this).attr('disabled') === "disabled") { return false; }
    $('#formSearchChange').submit();
    });
    */

    $('#tabs-searches a.button.select').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }
        UpdateSelectedResults();
    });

    $('#divAddressSearch a.button.find').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }
        $(this).closest('form').submit();
    });

    $('#divAddressSearch form').submit(function(e) {
        e.preventDefault();
        FindLoc();
    });

    /*
    $('#formSearchChange').submit(function(e) {
    e.preventDefault();

var form = $(this);
    var params = form.serialize();

$('#divSearchChange a.indicator').show();
    $('#divSearchChange *').attr('disabled', 'disabled');

$('#searchControls').html('');

curr_ajax = $.ajax({
    url: form.attr('action'),
    type: form.attr('method'),
    dataType: "text",
    data: params,
    success: function(data) {
    $('#searchControls').html(data);
    $('input.date').datepicker({ showAnim: 'slideDown' });

// zebra striping
    $('#searchControls li:even').addClass('alt');

BindDynamicSearch();
    },
    complete: function() {
    $('#divSearchChange *').removeAttr('disabled');
    $('#divSearchChange a.indicator').hide();

curr_ajax = null;
    }
    });
    });
    */

    /*
    $('#searches').change(function() {
    $(this).parent('form').submit();
    });
    */

    $('#selectResults').change(function() {
        $('#old-searches a.button.select').click();
    });

    // old searches toolbar
    $('#old-searches a.button.update').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }

        // prepare for searching
        map.DeleteShapeLayer(selected_result.layer);

        PerformSearch(selected_result.params, $.inArray(selected_result, results));
    });

    $('#old-searches a.button.show').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }
        selected_result.layer.Show();
        map.SetMapView(selected_result.layer.GetBoundingRectangle());

        UpdateShowHideButtons();
    });

    $('#old-searches a.button.hide').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }
        selected_result.layer.Hide();

        UpdateShowHideButtons();
    });

    $('#old-searches a.button.delete').click(function(e) {
        e.preventDefault();
        if ($(this).attr('disabled') === "disabled") { return false; }

        map.DeleteShapeLayer(selected_result.layer); //remove from map
        delete results[$.inArray(selected_result, results)]; //remove from completed searches

        $('#selectResults option:selected').remove(); //remove from select list of old searches

        if ($('#selectResults option').length === 0) {
            $('#no-searches').show();
            $('#old-searches').hide();
        }
        else {
            //need to press the select button to force refresh
            $('#old-searches > a.button.select').click();
        }
    });

    $('#old-searches a.button.print').click(function(e) {
        e.preventDefault();
        PrintCurrentResults();
    });

    $('a.defaultZoom').click(function(e) {
        e.preventDefault();
        DefaultMapZoom();
    });

    $('#divAddressSearch input').keydown(function(e) {
        if (e.keyCode === 13) { //enter press
            $('#divAddressSearch a.button.find').click();
        }
    });

    $('a.address.zoom').live('click', function(e) {
        e.preventDefault();

        var id = $(this).get(0).className.match(/\d+/);
        var row = $(this).closest('tr');

        map.SetMapView(addressResults[id].GetBoundingRectangle());
    });

    $('a.address.remove').live('click', function(e) {
        e.preventDefault();

        var row = $(this).closest('tr');
        var id = $(this).get(0).className.match(/\d+/);

        map.DeleteShapeLayer(addressResults[id]);
        delete addressResults[id]; // leave a "hole" so we dont have to reindex
        row.remove();
    });

    $('a.set.color').ColorPicker({
        onChange: function(hsl, hex, rgb) {
            var layer = selected_result.layer;
            for (var i = 0; i < layer.GetShapeCount(); i++) {
                var shape = layer.GetShapeByIndex(i);

                //shape.SetCustomIcon(GetMapIconHtml(GetIcon(selected_result.results.ModuleId), '#' + hex));
                shape.SetCustomIcon(ShapeIconHtmlFromShape(shape, '#' + hex, ""));
            }
        }
    });

    $('a.largeMap').click(function() {
        HideVisibleLayers();
        map.Resize(990, 590);

        $('a.smallMap').show();
        $(this).hide();
        $('#sidebar, #tabs-legend').hide();
    });

    $('a.smallMap').click(function() {
        HideVisibleLayers();
        map.Resize(400, 400);

        $('a.largeMap').show();
        $(this).hide();
        $('#sidebar, #tabs-legend').show();
    });

    $('select#date').change(function() {
        var that = $(this);
        var custom = $('#' + that.attr('id') + "Custom");
        if (that.val() == 'c') {
            custom.removeClass('hidden');
            custom.show();
        }
        else {
            custom.hide();
        }
    });

    GetMap();

    $('input.date').datepicker();

/*    // set map legend
    $('#tabs-legend').html('<p class="ui-widget-header ui-corner-top">Map Legend</p><div class="ui-widget-content ui-corner-bottom"><ul></ul></div>');
    $('#tabs-legend ul').append('<li>' + GetLegendIconHtml("Address") + ' Address</li>');
    $('#tabs-legend ul').append('<li>' + GetLegendIconHtml("Incident") + ' Incident</li>');
    //2010-04-16 (ryoe) Matt P. sez! No mas Arrest! (of course, he said it in English!)
    //$('#tabs-legend ul').append('<li>' + GetLegendIconHtml("Arrest") + ' Arrest</li>');
    $('#tabs-legend ul').append('<li>' + GetLegendIconHtml("Citation") + ' Citation</li>');
    $('#tabs-legend ul').append('<li>' + GetLegendIconHtml("Accident") + ' Accident</li>');
    $('#tabs-legend ul').append('<li>' + GetLegendIconHtml("CallForService") + ' Calls</li>');
*/
    //2010-04-19 (ryoe) why set the value of the city combo to blank?
    //$('#city').val('');
});

function bindAreaCustomSelect() {

    $('select#predefinedArea').change(function() {
        var that = $(this);
        var custom = $('#' + that.attr('id') + "Custom");
        if (that.val() == 'c') {
            custom.removeClass('hidden');
            custom.show();
        }
        else {
            custom.hide();
        }
    });
}
