﻿var map;
var hashedMarkers = new Hash();
var clickZOrder = 0;
var swLat = 0;
var swLng = 0;
var neLat = 0;
var neLng = 0;
var navigationArea;
var polygon;
var centerMarker;
var polylines = new Array();
var navigationBufferEnabled = true;
var aggregationMode = false;
var geocoder;
var addressMarker;
var tabAccuracy = new Array(2, 4, 6, 10, 12, 13, 15, 15, 15);
var searchButtonID;
var timer = null;
var killedTimer = null;

function initialize(buttonID)
{
    if (GBrowserIsCompatible())
    {
        if (map == undefined)   //Initialize map only once
        {
            //Get button unique ID
            searchButtonID = buttonID;
            //Create global geocoder
            geocoder = new GClientGeocoder();
            geocoder.setBaseCountryCode("ca");
            map = new GMap2(document.getElementById("map_canvas"), { draggableCursor: 'auto', backgroundColor: '#A5BFDD' });
            var centerAndZoom = getCenterAndZoom();
            if (typeof (centerAndZoom) != "undefined")
            {
                //Set user's region center and zoom.
                map.setCenter(centerAndZoom[0], centerAndZoom[1], G_NORMAL_MAP);
            }
            else
            {
                //Set default.
                map.setCenter(new GLatLng(55.578344672182055, -97.734375), 3, G_NORMAL_MAP);
            }
            //Default UI changed to custom UI to be able to fix scroll wheel zoom bug
            var customUI = map.getDefaultUI();
            customUI.zoom.scrollwheel = false;
            customUI.controls.smallzoomcontrol3d = false;
            customUI.controls.largemapcontrol3d = false;
            customUI.controls.scalecontrol = false;
            customUI.controls.maptypecontrol = false;
            customUI.controls.menumaptypecontrol = false;
            customUI.controls.hierarchicalmaptypecontrol = false;
            //disable keyboard support
            customUI.keyboard = false
            map.setUI(customUI);

            var smallMapControlPosition = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10));
            var menuMapTypeControlPosition = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(70, 10));
            map.addControl(new GSmallMapControl(), smallMapControlPosition);
            map.addControl(new GMenuMapTypeControl(), menuMapTypeControlPosition);
            //GEvent.addListener(map, "move", function(overlay)
            //{
            //centerMarker.setLatLng(map.getCenter());
            //});
            GEvent.addListener(map, "zoomend", function(oldZoom, newZoom)
            {
                if (!aggregationMode)
                {
                    storeSwNe();
                    DoSearchButtonPostBack(searchButtonID);
                }
                drawNavigationArea();
            });
            GEvent.addListener(map, "dragstart", function()
            {
                if (timer)
                {
                    clearTimeout(timer);
                    timer = null;
                    killedTimer = "yes";
                }
            });
            GEvent.addListener(map, "dragend", function()
            {
                try
                {
                    if (!navigationArea.containsLatLng(map.getCenter()) || killedTimer)
                    {
                        if (navigationBufferEnabled)
                        {
                            storeSwNe();
                            DoSearchButtonPostBack(searchButtonID);
                        }
                        drawNavigationArea();
                        killedTimer = null;
                    }
                }
                catch (Error)
                {
                    //alert(Error);
                }
            });
            storeSwNe();
            drawNavigationArea();
            DoSearchButtonPostBack(searchButtonID);
            //Center Marker
            //            var position = map.getCenter();
            //            var icon = new GIcon();
            //            icon.image = "../images/Markers/crosshair.png";
            //            icon.iconSize = new GSize(50.0, 50.0);
            //            icon.iconAnchor = new GPoint(25.0, 25.0);
            //            centerMarker = new GMarker(position, icon);
            //map.addOverlay(centerMarker);
        }
    }
}

function getMarkersByGeography(pageNumber)
{
    //HSW.Map.Services.GeoPointsService.GetMarkersByGeography(swLat, swLng, neLat, neLng, pageNumber, MarkersServiceComplete, OnMarkersServiceError);
    if (typeof (jsonMarkers) != "undefined")
    {
        if (jsonMarkers.length != 0)
        {
            MarkersServiceComplete(jsonMarkers.pop(), "");
        }
    }
}

function storeSwNe()
{
    //Get sw and ne points
    swLat = map.getBounds().getSouthWest().lat();
    swLng = map.getBounds().getSouthWest().lng();
    neLat = map.getBounds().getNorthEast().lat();
    neLng = map.getBounds().getNorthEast().lng();
    //Use default hemisphere values if zoom is too far.
    if (map.getZoom() <= 4)
    {
        swLat = -89;
        swLng = -179;
        neLat = 89;
        neLng = -1;
        navigationBufferEnabled = false;
    }
    else
    {
        if (!aggregationMode)
        {
            navigationBufferEnabled = true;
        }
    }

    //Store them in the fields
    $("input[id$='swLat']").val(swLat);
    $("input[id$='swLng']").val(swLng);
    $("input[id$='neLat']").val(neLat);
    $("input[id$='neLng']").val(neLng)

}

function MarkersServiceComplete(result, userContext)
{
    clearPolylines();
    if (!navigationBufferEnabled)
    {
        navigationBufferEnabled = true;
        aggregationMode = false;
    }
    hashedMarkers.each(function(value, key) { map.removeOverlay(value) });
    //Empty the hash
    hashedMarkers.empty();
    //map.clearOverlays();
    for (var i = 0; i < result.length; i++)
    {
        //Add markers to the global array
        hashedMarkers.set(result[i].ID, createMarkerV2(result[i]));
    }
    hideLoader();
    //Display them
    //var mydata = hashedMarkers.getValues();
    //var markerCluster = new MarkerClusterer(map, mydata, { maxZoom: 8, gridSize: 40 });
}

function OnMarkersServiceError(result)
{
    //alert("Error: " + result.get_message());
    //Need to log errors
}

function createMarkerV2(newMarker)
{
    var position = new GLatLng(newMarker.Latitude, newMarker.Longitude);
    var iconImage = createIcon(newMarker.IconUrl, newMarker.IconShadowUrl);
    var marker = new GMarker(position, {
        title: newMarker.Title,
        icon: iconImage,
        zIndexProcess: importanceOrder
    });
    marker.ID = newMarker.ID;
    marker.EventID = newMarker.EventID;
    marker.Type = newMarker.Type;
    GEvent.addListener(marker, "click", function()
    {
        openInfoWindow(marker.ID);
    });
    GEvent.addListener(marker, "mouseover", function()
    {
        highlightMarker(marker.ID);
    });
    GEvent.addListener(marker, "mouseout", function()
    {
        deHighlightMarker(marker.ID);
    });
    GEvent.addListener(marker, "infowindowopen", function()
    {
        exposureRouteSelected(marker.ID);
    });
    GEvent.addListener(marker, "infowindowclose", function()
    {
        exposureRouteDeselected(marker.ID);
    });
    map.addOverlay(marker);
    return marker;
}

function openInfoWindow(markerID)
{
    clickZOrder += 10;
    var marker = hashedMarkers.get(markerID);
    if (marker)
    {
        if (marker.Type == "restaurant")
        {
            HSW.Map.Services.GeoPointsService.GetInfoWindowTextByFacilityID(marker.EventID, InfoWindowTextByMarkerIDComplete, OnMarkersServiceError, marker.ID);

        }
        else
        {
            HSW.Map.Services.GeoPointsService.GetInfoWindowTextByMarkerID(marker.EventID, marker.ID, InfoWindowTextByMarkerIDComplete, OnMarkersServiceError, marker.ID);

        }
    }

}

function importanceOrder(marker, b)
{
    var zOrder = GOverlay.getZIndex(marker.getPoint().lat()) + clickZOrder * 1000000;
    return zOrder;
}

function createIcon(iconUrl, iconShadowUrl)
{
    var icon = new GIcon();
    icon.image = iconUrl;
    icon.shadow = iconShadowUrl;
    icon.iconSize = new GSize(32.0, 37.0);
    icon.shadowSize = new GSize(51.0, 37.0);
    icon.iconAnchor = new GPoint(16.0, 37.0);
    icon.infoWindowAnchor = new GPoint(16.0, 18.0);
    return icon;
}

function InfoWindowTextByMarkerIDComplete(result, markerID)
{
    var tabs = [];
    for (var i = 0; i < result.length; i++)
    {
        //Add tabs to the array
        tabs.push(new GInfoWindowTab(result[i].TabName, result[i].TabContent));
    }
    hashedMarkers.get(markerID).openInfoWindowTabsHtml(tabs, { maxWidth: 370, maxHeight: 120, autoScroll: true });
}

function highlightMarker(markerID)
{
    try
    {
        var marker = hashedMarkers.get(markerID);
        if (markerID == 'A98E54C7-8DCA-4F5D-A666-CFC5728F90CB')
        {
            marker = addressMarker;
        }
        var iconPath = marker.getIcon().image;
        iconPath = iconPath.substring(0, iconPath.indexOf('.png')) + 'Highlighted.png';
        marker.setImage(iconPath);
    }
    catch (Error) { }
}

function deHighlightMarker(markerID)
{
    try
    {
        var marker = hashedMarkers.get(markerID);
        if (markerID == 'A98E54C7-8DCA-4F5D-A666-CFC5728F90CB')
        {
            marker = addressMarker;
        }
        var iconPath = marker.getIcon().image;
        marker.setImage(iconPath);
    }
    catch (Error) { }
}

function drawNavigationArea()
{
    if (polygon)
    {
        map.removeOverlay(polygon);
    }

    var offsetX = 0.1 * Math.abs(swLat - neLat);
    var offsetY = 0.1 * Math.abs(swLng - neLng);
    var navigationAreaSw = new GLatLng(swLat + offsetX, swLng + offsetY);
    var navigationAreaNe = new GLatLng(neLat - offsetX, neLng - offsetY);
    navigationArea = new GLatLngBounds(navigationAreaSw, navigationAreaNe);

    //    var points = [];
    //    points.push(new GLatLng(navigationAreaSw.lat(), navigationAreaSw.lng()));
    //    points.push(new GLatLng(navigationAreaNe.lat(), navigationAreaSw.lng()));
    //    points.push(new GLatLng(navigationAreaNe.lat(), navigationAreaNe.lng()));
    //    points.push(new GLatLng(navigationAreaSw.lat(), navigationAreaNe.lng()));
    //    points.push(new GLatLng(navigationAreaSw.lat(), navigationAreaSw.lng()));
    //    polygon = new GPolygon(points, "#f33f00", 5, 1, "#ff0000", 0.2);

    //map.addOverlay(polygon);
}

function GetUserRegionByUserID(userID)
{
    //Load regions from webservice
    //HSW.Map.Services.PolygonService.GetUserRegionByUserID(userID, PolygonServiceComplete, OnPolygonServiceError);
}

function GetUserRegionByCityID(cityID)
{
    //Load regions from webservice
    //HSW.Map.Services.PolygonService.GetUserRegionByCityID(cityID, PolygonServiceComplete, OnPolygonServiceError);
}

function GetProvinceByProvinceID(provinceID)
{
    //Load regions from webservice
    //HSW.Map.Services.PolygonService.GetProvinceByProvinceID(provinceID, PolygonServiceComplete, OnPolygonServiceError);
}

function GetCountryByCountryID(countryID)
{
    //Load regions from webservice
    //HSW.Map.Services.PolygonService.GetCountryByCountryID(countryID, PolygonServiceComplete, OnPolygonServiceError);
}

function LoadPolygons()
{
    if (typeof (jsonPolygons) != "undefined")
    {
        if (jsonPolygons.length != 0)
        {
            PolygonServiceComplete(jsonPolygons.pop(), "");
        }
    }
}

function LoadPolygonsMapWidget()
{
    if (typeof (jsonPolygons) != "undefined")
    {
        if (jsonPolygons.length != 0)
        {
            PolygonServiceCompleteWithoutZoomPostback(jsonPolygons.pop(), "");
        }
    }
}

function PolygonServiceCompleteWithoutZoomPostback(result, userContext)
{
    clearPolylines();
    polylines = [];
    for (var i = 0; i < result.length; i++)
    {
        //Add polylines to the global array
        for (var j = 0; j < result[i].polylines.length; j++)
        {
            polylines.push(createPolyline(result[i].polylines[j]));
        }
    }
    //Display polylines right away if map is initialized.
    if (map != undefined)
    {
        for (var j = 0; j < polylines.length; j++)
        {
            map.addOverlay(polylines[j]);
        }
        //turn off zoom event so it will not call marker's search button postback
        if (!aggregationMode)
        {
            aggregationMode = true;
        }
        autoZoomPolygons();
        //Turn it back on so if user uses zoom it will call search
        aggregationMode = false;
        //Get markers
        storeSwNe();
        DoSearchButtonPostBack(searchButtonID);
    }

}

function clearPolylines()
{
    //Clear all old polylines
    if (polylines.length != 0 && map)
    {
        for (var i = 0; i < polylines.length; i++)
        {
            map.removeOverlay(polylines[i]);
        }
    }
}

function PolygonServiceComplete(result, userContext)
{
    clearPolylines();
    polylines = [];
    for (var i = 0; i < result.length; i++)
    {
        //Add polylines to the global array
        for (var j = 0; j < result[i].polylines.length; j++)
        {
            polylines.push(createPolyline(result[i].polylines[j]));
        }
    }
    //Display polylines right away if map is initialized.
    if (map != undefined)
    {
        for (var j = 0; j < polylines.length; j++)
        {
            map.addOverlay(polylines[j]);
        }
        autoZoomPolygons();
    }

}

function OnPolygonServiceError(result)
{
    //alert("Error: " + result.get_message());
    //Need to log errors
}

//Creates encoded polygons
function createPolygon(encodedPolylines, htmlColor, polygonOpacity, categoryName)
{
    var encodedPolygon = new GPolygon.fromEncoded({
        polylines: encodedPolylines,
        fill: true,
        color: htmlColor,
        opacity: polygonOpacity,
        outline: true
    });
    encodedPolygon.category = categoryName;
    return encodedPolygon;
}

//Creates encoded polyline
function createPolyline(polyline)
{
    var encodedPolyline = new GPolyline.fromEncoded({
        color: polyline.color,
        weight: polyline.weight,
        opacity: polyline.opacity,
        points: polyline.points,
        levels: polyline.levels,
        zoomFactor: polyline.zoomFactor,
        numLevels: polyline.numLevels
    });
    return encodedPolyline;
}

//Auto centers and auto zooming map canvas
function autoZoomPolygons()
{
    //Check if the map div element has changed and we need to resize it
    map.checkResize();
    if (polylines.length != 0)
    {
        var bounds = new GLatLngBounds();
        for (var i = 0; i < polylines.length; i++)
        {
            bounds.extend(polylines[i].getBounds().getSouthWest());
            bounds.extend(polylines[i].getBounds().getNorthEast());
        }
        map.setCenter(bounds.getCenter());
        map.setZoom(map.getBoundsZoomLevel(bounds));
    }
}

//Returns center and zoom level for polyline array.
function getCenterAndZoom()
{
    if (polylines.length != 0)
    {
        var bounds = new GLatLngBounds();
        for (var i = 0; i < polylines.length; i++)
        {
            bounds.extend(polylines[i].getBounds().getSouthWest());
            bounds.extend(polylines[i].getBounds().getNorthEast());
        }
        var centerAndZoom = new Array(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
        return centerAndZoom;
    }
    return undefined;
}

function aggregateByHealthRegion()
{
    //HSW.Map.Services.GeoPointsService.AggregateByHealthRegion(AggregationServiceComplete, OnMarkersServiceError);
    if (typeof (jsonMarkers) != "undefined")
    {
        if (jsonMarkers.length != 0)
        {
            AggregationServiceComplete(jsonMarkers.pop(), "");
        }
    }
}

function aggregateByProvince()
{
    //HSW.Map.Services.GeoPointsService.AggregateByProvince(AggregationServiceComplete, OnMarkersServiceError);
    if (typeof (jsonMarkers) != "undefined")
    {
        if (jsonMarkers.length != 0)
        {
            AggregationServiceComplete(jsonMarkers.pop(), "");
        }
    }
}

function AggregationServiceComplete(result, userContext)
{
    clearPolylines();
    if (navigationBufferEnabled)
    {
        navigationBufferEnabled = false;
        aggregationMode = true;
    }
    hashedMarkers.each(function(value, key)
    {
        map.removeOverlay(value)
    });
    //Empty the hash
    hashedMarkers.empty();
    for (var i = 0; i < result.length; i++)
    {
        //Add markers to the global array
        hashedMarkers.set(result[i].ID, createHSWCluster(result[i]));
    }
}


function createHSWCluster(newMarker)
{
    var position = new GLatLng(newMarker.Latitude, newMarker.Longitude);
    var hswCluster = new HSWCluster(position, newMarker.EventsCount, newMarker.Title, hswClusterClick, newMarker.ID, newMarker.SeverityID);
    map.addOverlay(hswCluster);
    return hswCluster;
}

function hswClusterClick(id)
{
    var cluster = hashedMarkers.get(id);
    var html = "<b>@province - @cout</b>";
    //Load health region from webservice
    HSW.Map.Services.PolygonService.GetHealthRegionByLocationID(cluster.ID_, PolygonServiceComplete, OnPolygonServiceError);
    html = html.replace("@province", cluster.title_);
    html = html.replace("@cout", cluster.clusterValue_);
    map.openInfoWindowHtml(cluster.point_, html);
}

function geocodeAddress(address)
{
    if (address)
    {
        geocoder.getLocations(address, addAddressToMap);
    }
}

function addAddressToMap(response)
{
    if (!response || response.Status.code != 200)
    {
        alert("\"" + response.name + "\" not found");
    } else
    {
        var place = response.Placemark[0];
        var point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
        clearAddressMarker();
        navigationBufferEnabled = false;
        aggregationMode = true;
        map.setCenter(point, tabAccuracy[place.AddressDetails.Accuracy]);
        var iconImage = createIcon("./images/Markers/villa.png", "./images/Markers/shadow.png");
        addressMarker = new GMarker(point, {
            title: place.address,
            icon: iconImage,
            zIndexProcess: importanceOrder
        });
        addressMarker.ID = 'A98E54C7-8DCA-4F5D-A666-CFC5728F90CB';
        GEvent.addListener(addressMarker, "click", function()
        {
            addressMarker.openInfoWindow(document.createTextNode(place.address));
        });
        GEvent.addListener(addressMarker, "mouseover", function()
        {
            highlightMarker(addressMarker.ID);
        });
        GEvent.addListener(addressMarker, "mouseout", function()
        {
            deHighlightMarker(addressMarker.ID);
        });
        map.addOverlay(addressMarker);
        // As this is user-generated content, we display it as
        // text rather than HTML to reduce XSS vulnerabilities.
        addressMarker.openInfoWindow(document.createTextNode(place.address));
        storeSwNe();
        drawNavigationArea();
        DoSearchButtonPostBack(searchButtonID);
        navigationBufferEnabled = true;
        aggregationMode = false;
    }
}


function clearAddressMarker()
{
    if (addressMarker)
    {
        map.removeOverlay(addressMarker);
    }
}

function DoSearchButtonPostBack(searchButtonID)
{
    showLoader();
    if (!timer)
    {
        timer = setTimeout("searchButtonClick()", 2000);
    }
    else
    {
        clearTimeout(timer);
        timer = setTimeout("searchButtonClick()", 2000);
    }
}

function searchButtonClick()
{
    timer = null;
    setTimeout("__doPostBack(searchButtonID, '')", 0)
}

function exposureRouteSelected(markerID)
{
    var exposureRouteLink = $("#MapSummaryResultsList a[eventid='" + markerID + "']");
    if (exposureRouteLink.length)
    {
        var shortTitleCell = exposureRouteLink.closest('td');
        var severityCell = $('td:first', exposureRouteLink.closest('tr'));
        shortTitleCell.css("background", "url('../images/EventCell/HighlightedCell/selected-map-cell.png') no-repeat");
        HighlightBasedOnSeverity(severityCell);
        exposureRouteLink.css("color", "Blue");
        var topOffset = exposureRouteLink.closest('.EventSummaryViewItem').position().top;
        if (!isScrolledIntoView(exposureRouteLink.closest('.EventSummaryViewItem'), $("#MapSummaryResultsList")))
        {
            $("#MapSummaryResultsList").scrollTo(exposureRouteLink.closest('.EventSummaryViewItem'), 300);
        }
    }
}

function exposureRouteDeselected(markerID)
{
    var exposureRouteLink = $("#MapSummaryResultsList a[eventid='" + markerID + "']");
    if (exposureRouteLink.length)
    {
        exposureRouteLink.css("color", "Black");
        var shortTitleCell = exposureRouteLink.closest('td');
        var severityCell = $('td:first', exposureRouteLink.closest('tr'));
        shortTitleCell.css("background", "url('../images/EventCell/cell-bg-gradient.png') repeat-x scroll 0 0 transparent");
        DehighlightBasedOnSeverity(severityCell);
    }
}

function isScrolledIntoView(elem, container)
{
    var docViewTop = $(container).offset().top;
    var docViewBottom = docViewTop + $(container).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemTop >= docViewTop) && (elemBottom <= docViewBottom));
}

function showLoader()
{
    $("#pager").hide();
    $("#MapSummaryResultsList").hide();
    $("#spin").show();
}

function hideLoader()
{
    $("#spin").hide();
    $("#pager").show();
    $("#MapSummaryResultsList").show();
}

function HighlightBasedOnSeverity(cell)
{
    var severityID = cell.attr('severityID');
    if (severityID == 'a14435d1-e934-4510-97a6-929b196f9908') //Red
    {
        cell.css("background", 'url("../images/EventCell/HighlightedCell/red.png") no-repeat');
    }
    else if (severityID == 'f9877760-06aa-427a-a9d0-40c2b06c9206') //Green
    {
        cell.css("background", 'url("../images/EventCell/HighlightedCell/green.png") no-repeat');
    }
    else if (severityID == 'b3e13456-7abc-4eb6-8056-3872edaaf1aa') //Yellow
    {
        cell.css("background", 'url("../images/EventCell/HighlightedCell/yellow.png") no-repeat');
    }
}

function DehighlightBasedOnSeverity(cell)
{
    var severityID = cell.attr('severityID');
    if (severityID == 'a14435d1-e934-4510-97a6-929b196f9908') //Red
    {
        cell.css("background", '#c10808');
    }
    else if (severityID == 'f9877760-06aa-427a-a9d0-40c2b06c9206') //Green
    {
        cell.css("background", '#089018');
    }
    else if (severityID == 'b3e13456-7abc-4eb6-8056-3872edaaf1aa') //Yellow
    {
        cell.css("background", '#FFAE00');
    }
}
