var map;
var markerManager;
var geocoder;
var infowindow;
var markers;
var marker;
var markersArray = [];

///	<summary>
/// Initializes script styles.
/// <summary>
function initializeStyles() {

    //Adjust the navigation menu styles.
    $("#navigation a[href$='geoprogramsearch.aspx']").removeAttr("onmouseover").removeAttr("onmouseout")
            .children("img").attr("src", "images/nav_maps-h.gif");

    //Layout the filter options into toggle panels.           
    $("#filters").addClass("ui-accordion ui-widget ui-helper-reset")
                .find("h3")
                .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
			    .prepend('<span class="ui-icon ui-icon-triangle-1-e"/>')
			    .click(function () {

			        $(this).toggleClass("ui-accordion-header-active").toggleClass("ui-state-active")
					    .toggleClass("ui-state-default").toggleClass("ui-corner-bottom")
				        .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e").toggleClass("ui-icon-triangle-1-s")
				        .end().next().toggleClass("ui-accordion-content-active").toggle();

			        return false;
			    }).next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide();

    //Select the fitst filter toggle panel (Filter by Topic).
    $("#filters h3:first").click();

    $(".majorAgencyFilter").each(function () {
        $(this).next().attr("for", $(this).attr("id"));
    });

    $(".topicFilter").each(function () {
        $(this).next().attr("for", $(this).attr("id"));
    });

    //Enable filter tools for Filter by Topic.
    $("#selectAllTopicFilters").click(function () {
        $(".topicFilter").each(function () { $(this).attr('checked', true) });

        return false;
    });

    $("#deselectAllTopicFilters").click(function () {
        $(".topicFilter").each(function () { $(this).attr('checked', false) });

        return false;
    });

    //Enable filter tools for Filter by Agency.
    $("#selectAllMajorAgencyFilters").click(function () {
        $(".majorAgencyFilter").each(function () { $(this).attr('checked', true) });

        return false;
    });

    $("#deselectAllMajorAgencyFilters").click(function () {
        $(".majorAgencyFilter").each(function () { $(this).attr('checked', false) });

        return false;
    });

    //Add hover styles for command buttons.
    $(".command").hover(function () {
        $(this).addClass("ui-state-hover");
    }, function () {
        $(this).removeClass("ui-state-hover");
    });

}

function blockMain() {

    $('#mapCanvas').block({ message: $('#blockMainMessage'),
        overlyCSS: { backgroundColor: '#F1F2F7' }
    });

}

function unblockMain() {

    $('#mapCanvas').unblock({ fadeOut: 0 });

}

///	<summary>
/// Initialization method to be called once all supporting scripts have been downloaded.
/// <summary>
function initialize() {

    $("#dialog").dialog("destroy");

    initializeStyles();

    textBoxAddress = $("[id$='textBoxAddress']");

    var myLatlng = new google.maps.LatLng(40, -98);
    var mapOptions = {
        zoom: 4,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map($("#mapCanvas")[0], mapOptions);

    //Attach click event.
    $("#findPrograms").click(findPrograms);

    $("#aPrintPrograms").click(function () {
        $.blockUI({
            message: $('#question'),
            css: {
                width: '450px',
                '-moz-opacity': '1',
                opacity: '1',
                left: '30%'
            },
            overlayCSS: { opacity: 0.5 }
        });
    });

    $('#ok').click(function () {
        $.unblockUI();
        var found = $("body").find("[id$='formPrint']");

        if (found.length > 0) {
            $("body").remove("[id$='formPrint']");
            $("[id$='formPrint']").remove();
        }

        var rno = Math.random();

        $("body").append("<form id=\"formPrint\" target=\"_blank\" method=\"post\" action=\"geoProgramPrint.aspx?rno=" + rno + "\">"
                            + "<input type=\"hidden\" name=\"Address\" runat=\"server\" value=\"" + $("[id$='textBoxAddress']").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"Radius\" runat=\"server\" value=\"" + $("[id$='dropDownListAddressRadius'] :selected").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"RecipientId\" runat=\"server\" value=\"" + $("[id$='textRecipientId']").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"XCord\" runat=\"server\" value=\"" + $("[id$='textX']").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"YCord\" runat=\"server\" value=\"" + $("[id$='textY']").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"TopicFilters\" runat=\"server\" value=\"" + getTopicFilters().join(',') + "\" \>"
                            + "<input type=\"hidden\" name=\"MajorAgencyFilters\" runat=\"server\" value=\"" + getMajorAgencyFilters().join(',') + "\" \>"
                            + "</form>")
             .find("#formPrint").submit();
    });

    //Attach enter key event.
    textBoxAddress.keypress(function (e) {
        keyCode = e.which ? e.which : e.keyCode;

        if (keyCode == 13) {
            $(this).blur();
            $("#findPrograms").focus().click();
            e.preventDefault();
        }
    });

    $(".textOnlyVersion").click(function () {
        $("body").append("<form id=\"formTextOnlyVersion\" method=\"post\" action=\"geoprogramsearchLight.aspx\">"
                            + "<input type=\"hidden\" name=\"Address\" value=\"" + $("[id$='textBoxAddress']").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"Radius\" value=\"" + $("[id$='dropDownListAddressRadius'] :selected").val() + "\" \>"
                            + "<input type=\"hidden\" name=\"TopicFilters\" value=\"" + getTopicFilters().join(',') + "\" \>"
                            + "<input type=\"hidden\" name=\"MajorAgencyFilters\" value=\"" + getMajorAgencyFilters().join(',') + "\" \>"
                            + "</form>")
            .find("#formTextOnlyVersion").submit();
    });

    //Handle form posts from other pages.
    if (textBoxAddress.val() != "") {
        findPrograms();
    }

}

function newPrintWindow() {

    var querystring = "?Address=" + $("[id$='textBoxAddress']").val()
    querystring += "&Radius=" + $("[id$='dropDownListAddressRadius'] :selected").val()
    querystring += "&RecipientId=" + $("[id$='textRecipientId']").val()
    querystring += "&XCord=" + $("[id$='textX']").val()
    querystring += "&YCord=" + $("[id$='textY']").val()
    querystring += "&TopicFilters=" + getTopicFilters().join(',')
    querystring += "&MajorAgencyFilters=" + getMajorAgencyFilters().join(',')
    var wopen = window.open("geoProgramPrint.aspx" + querystring, "mywindow", "toolbar=yes,menubar=yes,location=yes,status=yes,scrollbars=yes,resizable=yes");

}

function findPrograms() {

    clearInfo();
    var textBoxAddress = $("[id$='textBoxAddress']");
    var requiredValidatorAddress = $("[id$='requiredValidatorAddress']")[0];
    ValidatorEnable(requiredValidatorAddress, true);

    if (requiredValidatorAddress.isvalid) {
        blockMain();
        var viewData = new Object();
        viewData.Address = textBoxAddress.val();
        $.ajax({
            type: "POST",
            url: "geoprogramsearch.aspx/GetLatLng",
            data: "{'viewData':" + JSON.stringify(viewData) + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (latLng) {
                if (!latLng.d) {
                    unblockMain();
                    updateInfo("<span style='color:#A90901;'>Unable to locate the address provided.</span>");
                    textBoxAddress.focus();
                }
                else {
                    $.ajax({
                        type: "POST",
                        url: "geoprogramsearch.aspx/FindProgramsByAddress",
                        data: "{'viewData':" + JSON.stringify(getFindProgramsByAddressViewData(latLng.d)) + "}",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        success: markMapCoordinates
                    });
                }
            }
        });
    } else {
        textBoxAddress.focus();
    }

    return false;
}

function findSubAwardees(fai) {

    clearInfo();
    var viewData = new Object();
    viewData.FederalAwardId = fai;

    $.ajax({
        type: "POST",
        url: "geoprogramsearch.aspx/GetSubAwardees",
        data: "{'viewData':" + JSON.stringify(viewData) + "}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: markMapCoordinates
    });

}

function findPrimeAwardee(fai) {

    clearInfo();
    var viewData = new Object();
    viewData.FederalAwardId = fai;

    $.ajax({
        type: "POST",
        url: "geoprogramsearch.aspx/GetPrimeAwardees",
        data: "{'viewData':" + JSON.stringify(viewData) + "}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: markMapCoordinates
    });

}

// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {

    if (infowindow) infowindow.close();

    if (markersArray) {
        for (i in markersArray) {
            markersArray[i].setMap(null);
        }
    }

}

function attachMessageInfoWindow(marker, number) {
    google.maps.event.addListener(marker, 'click', function () {
        var latLng = new google.maps.LatLng(marker.Y, marker.X);
        marker.position = latLng;
        showRecipientInfo(marker.RecipientId, marker.RecordType, marker);
    });
}

function markMapCoordinates(coordinates) {
    
    clearOverlays(); //TODO: Determine if this call to clearOverlays() is indeed needed.

    if (coordinates.d.length == 0) {
        unblockMain();
        updateInfo("No programs were found for the search criteria you provided.");

        return;
    }

    var bounds = new google.maps.LatLngBounds();
    markers = new Array();

    //Add Markers.
    for (var i = 0; i < coordinates.d.length; i++) {
        var latLng = new google.maps.LatLng(coordinates.d[i].Y, coordinates.d[i].X);

        marker = new google.maps.Marker({
            position: latLng,
            map: map,
            clickable: true,
            icon: 'markers/default.gif'
        });

        markersArray.push(marker);
        marker.setTitle(coordinates.d[i].PTA);
        marker.RecipientId = coordinates.d[i].Id;
        marker.RecordType = coordinates.d[i].RT;
        marker.Y = coordinates.d[i].Y;
        marker.X = coordinates.d[i].X;
        attachMessageInfoWindow(marker, i);
        bounds.extend(latLng);
    }

    map.fitBounds(bounds);
    var zoomLevel = map.getZoom();

    if (zoomLevel > 18)
    { map.setZoom(18); }
    else
    { map.setZoom(map.getZoom()); }

    coordinates = null;
    markers = null;
    unblockMain();
}

/// <summary>
/// Returns the view data to facilitate finding programs by state.
/// </summary>
/// <returns type="Object">
function getFindProgramsByAddressViewData(point) {

    var viewData = new Object();
    viewData.Latitude = point.Lat;
    viewData.Longitude = point.Lng;
    viewData.Radius = $("[id$='dropDownListAddressRadius'] :selected").val();
    viewData.TopicFilters = getTopicFilters();
    viewData.MajorAgencyFilters = getMajorAgencyFilters();
    viewData.ZipCode = point.ZipCode;
    viewData.RecipientZipCodeLatitude = point.RecipientZipCodeLatitude;
    viewData.RecipientZipCodeLongitude = point.RecipientZipCodeLongitude;

    return viewData;
}

function getTextOnlyVersionViewData() {

    var viewData = new Object();
    viewData.Address = $("[id$='textBoxAddress']").val();
    viewData.Radius = $("[id$='dropDownListAddressRadius'] :selected").val();
    viewData.TopicFilters = getTopicFilters();
    viewData.MajorAgencyFilters = getMajorAgencyFilters();
    viewData.ZipCode = point.ZipCode;
    viewData.RecipientZipCodeLatitude = point.RecipientZipCodeLatitude;
    viewData.RecipientZipCodeLongitude = point.RecipientZipCodeLongitude;

    return viewData; 
}

function showRecipientInfo(id, recordType, marker) {

    $.ajax({
        type: "POST",
        url: "geoprogramsearch.aspx/GetRecipientInfo",
        data: "{'viewData': {'RecipientId':'" + id + "', 'RecordType':'" + recordType + "'}}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (recipientInfo) {
            $("[id$='textRecipientId']")[0].value = id;

            if (infowindow) infowindow.close();

            infowindow = new google.maps.InfoWindow(
            {
                content: formatRecipientInfo(recipientInfo),
                size: new google.maps.Size(50, 50)
            });

            infowindow.open(map, marker);
        }
    });
}

//Formats the recipient info to be displayed in the bubble.
function formatRecipientInfo(recipientInfo) {

    var formatString = "No result found";

    if (recipientInfo != null && recipientInfo.d.length > 0) {

        if (recipientInfo.d.length > 1) {
            return formatMultipleRecipientInfo(recipientInfo);
        }
        else {
            return formatSingleRecipientInfo(recipientInfo);
        }
    }
    else {
        formatString = "No result found";
    }

    return formatString;
}

function formatSingleRecipientInfo(recipientInfo) {

    var formatString = "";

    formatString += "<p style='font-size:8pt;'>";

    if (recipientInfo.d[0].RT == 1) {

        if (recipientInfo.d[0].T)
            formatString += "<br /><strong>" + recipientInfo.d[0].T + "</strong>";

        if (recipientInfo.d[0].PD)
            formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfo.d[0].PD;

        if (recipientInfo.d[0].PN)
            formatString += "<br /><strong><i>CFDA Program Number:</i></strong> " + recipientInfo.d[0].PN;

        if (recipientInfo.d[0].MAN)
            formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfo.d[0].MAN;

        if (recipientInfo.d[0].AN)
            formatString += "<br /><strong><i>Funding Agency:</i></strong> " + recipientInfo.d[0].AN;

        if (recipientInfo.d[0].N)
            formatString += "<br /><strong><i>Recipient:</i></strong> " + recipientInfo.d[0].N;

        if (recipientInfo.d[0].A)
            formatString += "<br /><strong><i>Recipient Address:</i></strong> <br />" + recipientInfo.d[0].A;

        //check if this primary award recipient has sub-awards.
        if (recipientInfo.d[0].HS > 0)
            formatString += "<br /><i>Show <a href=\"javascript:findSubAwardees('" + recipientInfo.d[0].FAI + "')\">sub-award recipients</a> in this state.</i> <br />";
    }
    else if (recipientInfo.d[0].RT == 2) {

        if (recipientInfo.d[0].T)
            formatString += "<br /><strong>" + recipientInfo.d[0].T + "</strong>";

        if (recipientInfo.d[0].PD)
            formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfo.d[0].PD;

        if (recipientInfo.d[0].PN)
            formatString += "<br /><strong><i>CFDA Program Number:</i></strong> " + recipientInfo.d[0].PN;

        if (recipientInfo.d[0].MAN)
            formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfo.d[0].MAN;

        if (recipientInfo.d[0].AN)
            formatString += "<br /><strong><i>Funding Agency:</i></strong> " + recipientInfo.d[0].AN;

        formatString += "<br /><strong><i>Sub-Award Number:</i></strong> " + recipientInfo.d[0].FAI;

        if (recipientInfo.d[0].N)
            formatString += "<br /><strong><i>Sub-Award Grantee:</i></strong> " + recipientInfo.d[0].N;

        if (recipientInfo.d[0].A)
            formatString += "<br /><strong><i>Sub-Award Grantee Address:</i></strong> <br />" + recipientInfo.d[0].A;

        formatString += "<br /><i>Show <a href=\"javascript:findPrimeAwardee('" + recipientInfo.d[0].FAI + "')\">prime award recipient</a>.</i> <br />";
    }
    else {

        if (recipientInfo.d[0].N)
            formatString += "<strong>" + recipientInfo.d[0].N + "</strong>";

        if (recipientInfo.d[0].PD)
            formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfo.d[0].PD;

        formatString += "<br /><strong><i>CFDA Program Number:</i></strong> n/a"

        if (recipientInfo.d[0].MAN)
            formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfo.d[0].MAN;

        formatString += "<br /><strong><i>Funding Agency:</i></strong> n/a"

        if (recipientInfo.d[0].N)
            formatString += "<br /><strong><i>Recipient:</i></strong> " + recipientInfo.d[0].N;

        if (recipientInfo.d[0].A)
            formatString += "<br /><strong><i>Recipient Address:</i></strong> <br />" + recipientInfo.d[0].A;
    }

    formatString += "</p>";

    return formatString;
}

function formatMultipleRecipientInfo(recipientInfos) {

    var formatString = "";

    for (var i = 0; i < recipientInfos.d.length; i++) {

        if (i > 0)
        { formatString += "<hr />" }

        formatString += "<p style='font-size:8pt;'>"

        if (recipientInfos.d[i].RT == 1) {

            if (recipientInfos.d[i].T)
                formatString += "<strong>" + recipientInfos.d[i].T + "</strong>";

            if (recipientInfos.d[i].PD)
                formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfos.d[i].PD;

            if (recipientInfos.d[i].PN)
                formatString += "<br /><strong><i>CFDA Program Number:</i></strong> " + recipientInfos.d[i].PN;

            if (recipientInfos.d[i].MAN)
                formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfos.d[i].MAN;

            if (recipientInfos.d[i].AN)
                formatString += "<br /><strong><i>Funding Agency:</i></strong> " + recipientInfos.d[i].AN;

            if (recipientInfos.d[i].N)
                formatString += "<br /><strong><i>Recipient:</i></strong> " + recipientInfos.d[i].N;

            if (recipientInfos.d[i].A)
                formatString += "<br /><strong><i>Recipient Address:</i></strong> <br />" + recipientInfos.d[i].A;

            //check if this primary award recipient has sub-awards.
            if (recipientInfos.d[i].HS > 0)
                formatString += "<br /><i>Show <a href=\"javascript:findSubAwardees('" + recipientInfos.d[i].FAI + "')\">sub-award recipients</a> in this state.</i> <br />";
        }
        else if (recipientInfos.d[i].RT == 2) {

            if (recipientInfos.d[i].T)
                formatString += "<br /><strong>" + recipientInfos.d[i].T + "</strong>";

            if (recipientInfos.d[i].PD)
                formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfos.d[i].PD;

            if (recipientInfos.d[i].PN)
                formatString += "<br /><strong><i>CFDA Program Number:</i></strong> " + recipientInfos.d[i].PN;

            if (recipientInfos.d[i].MAN)
                formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfos.d[i].MAN;

            if (recipientInfos.d[i].AN)
                formatString += "<br /><strong><i>Funding Agency:</i></strong> " + recipientInfos.d[i].AN;

            formatString += "<br /><strong><i>Sub-Award Number:</i></strong> " + recipientInfos.d[i].FAI;

            if (recipientInfos.d[i].N)
                formatString += "<br /><strong><i>Sub-Award Grantee:</i></strong> " + recipientInfos.d[i].N;

            if (recipientInfos.d[i].A)
                formatString += "<br /><strong><i>Sub-Award Grantee Address:</i></strong> <br />" + recipientInfos.d[i].A;

            formatString += "<br /><i>Show <a href=\"javascript:findPrimeAwardee('" + recipientInfos.d[i].FAI + "')\">prime award recipient</a>.</i> <br />";
        }
        else {

            if (recipientInfos.d[i].N)
                formatString += "<strong>" + recipientInfo.d[0].N + "</strong>";

            if (recipientInfos.d[i].PD)
                formatString += "<br /><strong><i>Description:</i></strong> " + recipientInfos.d[i].PD;

            formatString += "<br /><strong><i>CFDA Program Number:</i></strong> n/a"

            if (recipientInfos.d[i].MAN)
                formatString += "<br /><strong><i>Department:</i></strong> " + recipientInfos.d[i].MAN;

            formatString += "<br /><strong><i>Funding Agency:</i></strong> n/a"

            if (recipientInfos.d[i].N)
                formatString += "<br /><strong><i>Recipient:</i></strong> " + recipientInfos.d[i].N;

            if (recipientInfos.d[i].A)
                formatString += "<br /><strong><i>Recipient Address:</i></strong> <br />" + recipientInfos.d[i].A;
        }

        formatString += "</p>";
    }

    return formatString;
}

function getProgramFilters() {
    var filters = [];

    $(".programFilter:checked").each(function () {
        filters.push($(this).val());
    });

    return filters;
}

function getTopicFilters() {
    var filters = [];

    $(".topicFilter:checked").each(function () {
        filters.push($(this).val());
    });

    return filters;
}

function getMajorAgencyFilters() {
    var filters = [];

    $(".majorAgencyFilter:checked").each(function () {
        filters.push($(this).val());
    });

    return filters;
}

function updateInfo(info) {
    $("#info").html(info).scrollTo(500).effect("highlight", {}, 2000);
}

function clearInfo() {
    $("#info").html("");
}

//Register event to begin intialization once google's CDN has provided scripts.
google.setOnLoadCallback(initialize);
