﻿var schoolHash = new Object();
var schoolLocationHash = new Object();
var schoolTypeHash = new Object();
var initialZoomLevel;
var currentLocation = null;
var schoolMap;
var geocoder;
var currentSchoolId = null;


function ShowAttendanceBoundary(schoolId) {    
    schoolMap.closeInfoWindow();
    HideAttendanceBoundaries();
    
    var school = GetSchoolById(schoolId);
    var legendBuffer = [];
    legendBuffer[legendBuffer.length] = '<div>';
   
        for (var i = 0; i < school.Regions.length; i++) {
            var region = school.Regions[i];
            schoolMap.addOverlay(region.Overlay);
            region.Visible = true;
            if (school.Regions.length > 1) {
                legendBuffer[legendBuffer.length] = '<div class="legendItem">';
                legendBuffer[legendBuffer.length] = '<div class="legendBlock" style="background-color:' + region.Color + ';"></div>';
                legendBuffer[legendBuffer.length] = '<span class="boundaryName">' + region.Name + '</span>';
                legendBuffer[legendBuffer.length] = '</div>';
            }
        }
    
    legendBuffer[legendBuffer.length] = '<div style="clear:both;height:1px;"></div></div>';
    SetMapBestFitRegions(school.Regions);//TODO: Adjust to calculate for both boundaries
    ShowBoundaryLegend(school, legendBuffer.join(''));

    currentSchoolId = schoolId;
    markerHover(currentSchoolId);
}
function HideAttendanceBoundaries() {

    if (currentSchoolId != null) {
        var oldSchoolId = currentSchoolId;
        currentSchoolId = null;
        markerHoverEnd(oldSchoolId);
    }
    
    for (var i = 0; i < allSchools.length; i++) {
        var school = allSchools[i];
        var regions = school.Regions;
        for (var j = 0; j < regions.length; j++) {
            var region = regions[j];
            if (region.Visible) {
                schoolMap.removeOverlay(region.Overlay);
                region.Visible = false;
            }
        }
    }
}

function CreateAttendanceBoundaries() {
    $.each(allSchools, function(index, value) {
        var school = value;
            for (var i = 0; i < school.Regions.length; i++) {
                var region = school.Regions[i];
                var color = genHexColor(i);
                CreateOverlay(region, color);
                region.Visible = false;
            }        
    });
}

function CreateOverlay(region, color) {
    var points = region.Points;
    var polygons = new Array();
    var str = "";
    for (var i = 0; i < points.length; i++) {
        polygons[polygons.length] = new GLatLng(points[i].Lat, points[i].Lon);
    }
    var polygon = new GPolygon(polygons, color, 3, 0.8, color, 0.2);
    region.Overlay = polygon;
    region.Color = color;
    return region;
}

function genHexColor(index) {
    switch (index) {
        case 0: return "#478DFF";
        case 1: return "#FF6919";
        default: return "#6919FF";
    }
    var colors = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f");
    var digit = new Array(5);
    var color = [];
    for (var i = 0; i < 6; i++) {
        digit[i] = colors[Math.round(Math.random() * 14)];
        color[color.length] = digit[i];
    }
    return color.join('');
}

$(document).ready(function() {
    $("[href=#fbMapWrapper]").fancybox({
        'speedIn': 400,
        'speedOut': 200,
        'scrolling' : 'no',
        'titlePosition': 'inside',
        'overlayShow': true,
        'showCloseButton': true,
        'autoScale': false,
        'onComplete': fbOnComplete,
        'onClosed': SetDefaultView,
        'centerOnScroll':false,
        'padding':0,
        'margin':5
    });
    $("#mapAddress").keydown(function(event) {
        if (event.keyCode == 13) {
            showAddress();
        }
    });
    BuildSchoolHash();
});

var initMap = false;
function fbOnComplete() {
    if (!initMap) {
        initMap = true;
        initializeMap();
        geocoder = new GClientGeocoder();
    }
    $('#mapAddress').val('').watermark('Enter a location (address, town, postal code)', {className:'watermark', useNative:false});
}

function removeMapAddress() {
    if (currentLocation != null && currentLocation.Visible) {
        schoolMap.removeOverlay(currentLocation.Marker);
        currentLocation.Visible = false;
        currentLocation = null;
        $("#mapAddressRemove").attr('disabled', true);
    }
}

function disambiguationSelected(address, lat, lng) {
    setCurrentLocation(address, lat, lng);
    $("#disambiguation").hide();
}

function showDisambiguation(placemarkers) {
    var sbuffer = [];
    sbuffer[sbuffer.length] = "<ul>";
    for (var i = 0; i < placemarkers.length; i++) {
        var placemarker = placemarkers[i];
        sbuffer[sbuffer.length] = '<li><a href="javascript:disambiguationSelected(\''
            + placemarker.address + '\','
            + placemarker.Point.coordinates[0] + ' ,'
            + placemarker.Point.coordinates[1] + ');">'
            + placemarker.address + "</a>"
                + '</li>';
    }
    sbuffer[sbuffer.length] = "</ul>";
    var html = sbuffer.join('');
    var position = $("#myMap").offset(); // position = { left: 42..., top: 567... }
    //var height = $("#mapAddress").height();
    $("#disambiguation").html(html).css(position).show();
}

function showDroppedAddress(response) {
    if (!response || response.Status.code != 200) {
        //alert("Status Code:" + response.Status.code);
    } else {
        var place = response.Placemark[0];
        $("#mapAddress").val(place.address);
        $("#mapAddress").effect("highlight", {}, 3000);
        currentLocation.Address = place.address;
    }
}

function getAddress(latlng) {
    if (latlng != null) {
        geocoder.getLocations(latlng, showDroppedAddress);
    }
}

function setCurrentLocation(address, lat, lng) {
    $("#mapAddressRemove").attr('disabled', false);
    $("#mapAddress").val(address);
    var point = new GLatLng(lng, lat);
    currentLocation = new Object();
    currentLocation.Address = address;
    currentLocation.Point = point;
    var marker = new GMarker(point, { draggable: true });
    currentLocation.Marker = marker;

    schoolMap.addOverlay(marker);
    currentLocation.Visible = true;

    schoolMap.setCenter(point, 13);
    //SetMapBestFit(allSchools);
    marker.openInfoWindowHtml(address);

    GEvent.addListener(marker, "dragstart", function() {
        schoolMap.closeInfoWindow();
    });

    GEvent.addListener(marker, "dragend", function() {
        var newPoint = marker.getLatLng();
        getAddress(newPoint);
        currentLocation.Point = newPoint;
    });

    GEvent.addListener(marker, "click", function() {
        schoolMap.openInfoWindowHtml(currentLocation.Point, '<div class="schoolPopup">Your location:<br/>' + currentLocation.Address+'</div>');
    });
}

function getLocationsReturn(response) {
    if (response != null && response.Placemark != null) {
        if (response.Placemark.length == 1) {
            setCurrentLocation(response.Placemark[0].address, response.Placemark[0].Point.coordinates[0], response.Placemark[0].Point.coordinates[1]);
        }
        else if (response.Placemark.length > 1) {
            showDisambiguation(response.Placemark);
            //disambiguate
        }
    }
}
function trim(stringToTrim) {
    return stringToTrim.replace(/^\s+|\s+$/g, "");
}
function showAddress() {
    if (currentLocation != null && currentLocation.Visible) {
        schoolMap.removeOverlay(currentLocation.Marker);
        currentLocation = null;
    }
    $("#disambiguation").hide();
    var address = $("#mapAddress").val();
    if (trim(address) == "") {
        return;
    }
    
    if (address.toLowerCase().indexOf("canada") < 0) {
        address += ", Canada";
    }
    geocoder.getLocations(address, getLocationsReturn);
}

function GetLetter(index) {
    var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    return alphabet.substr(index, 1);
}

function GetIcon(school) {
    var pinIcon = new GIcon(G_DEFAULT_ICON);
    var letter = GetLetter(school.Index);
    var markerUrl = "/_layouts/Psd/Internet/Images/Icons/Markers/";
    pinIcon.image = markerUrl + "blue_Marker" + letter + ".png";
    school.IconImage = markerUrl + "blue_Marker" + letter + ".png";
    school.IconImageHl = markerUrl + "orange_Marker" + letter + ".png";
    return pinIcon;
}

function initializeMap() {
    schoolMap = new google.maps.Map2(document.getElementById("myMap"));
    schoolMap.setCenter(new GLatLng(53.528880618043246, -114.00375366210936), 13);
    schoolMap.addControl(new GMapTypeControl());
    schoolMap.addControl(new GLargeMapControl3D());
    schoolMap.enableScrollWheelZoom();
    schoolMap.enableContinuousZoom();


    BuildFilterHashes();

    CreateMarkers(allSchools);
    CreateAttendanceBoundaries();
    SetDefaultView();
}

function BuildSchoolHash() {
    for (var i = 0; i < allSchools.length; i++) {
        var school = allSchools[i];
        schoolHash[school.Id] = school;
    }
}

function BuildFilterHashes() {
    for (var i = 0; i < schoolLocations.length; i++) {
        var schoolLocation = schoolLocations[i];
        schoolLocationHash[schoolLocation.Value] = schoolLocation;
    }
    for (var i = 0; i < schoolTypes.length; i++) {
        var schoolType = schoolTypes[i];
        schoolTypeHash[schoolType.Value] = schoolType;
    }
}

function SetDefaultView() {
    SetFiltersToValue(true);
    RenderFilters();
    RenderView();
}

function ClearAllFilters() {
    SetFiltersToValue(false);
    RenderFilters();
    RenderView();
}

function SetFiltersToValue(enabled) {
    for (var i = 0; i < schoolLocations.length; i++) {
        schoolLocations[i].Enabled = enabled;
    }
    for (var i = 0; i < schoolTypes.length; i++) {
        schoolTypes[i].Enabled = enabled;
    }
}


function RenderFilterOptions(selectId, filterList, type) {
    $("#" + selectId).html("");
    var sbuffer = [];
    sbuffer[sbuffer.length] = '<option value="all" selected>Select your '+type+'</option>';
    sbuffer[sbuffer.length] = '<option value="all">All</option>';
    for (var i = 0; i < filterList.length; i++) {
        var option = filterList[i];
        sbuffer[sbuffer.length] = '<option value="' + option.Id + '">' + option.Value + '</option>';
    }
    var html = sbuffer.join('');
    $("#" + selectId).append(html);
}

function RenderFilters() {
    RenderFilterOptions("schoolLocationSelect", schoolLocations, 'area');
    $("#schoolLocationSelect").change(function() {
        var selectedItem = $(this).val();
        selectedItem == "all" ? EnableAllLocationFilters() : SetLocationFilterEnabled(selectedItem);
        RenderView();
    });

    RenderFilterOptions("schoolTypeSelect", schoolTypes, 'grade level');
    $("#schoolTypeSelect").change(function() {
        var selectedItem = $(this).val();
        selectedItem == "all" ? EnableAllTypeFilters() : SetTypeFilterEnabled(selectedItem);
        RenderView();
    });
}

function ClearMap() {
    schoolMap.clearOverlays();
}

function RenderView() {
    ClearMap();
    FilterSchools(allSchools);
    RenderMarkers(allSchools);
    RenderSchoolList(allSchools);
    RenderCurrentLocation();
    SetMapBestFit(allSchools);
}

function RenderCurrentLocation() {
    if (currentLocation != null && currentLocation.Visible) {
        schoolMap.addOverlay(currentLocation.Marker);
    }
}

function CheckLocationMatchesFilter(school) {
    var filterValue = $("#schoolLocationSelect").val();
    if (filterValue == "all")
        return true;
        
    for (var i = 0; i < school.CitiesServed.length; i++) {
        var location = school.CitiesServed[i];
        var matchingFilter = schoolLocationHash[location];
        if (matchingFilter != undefined) {
            if (matchingFilter.Enabled)
                return true;
        }
    }
    return false;
}

function CheckTypeMatchesFilter(school) {
    var filterValue = $("#schoolTypeSelect").val();
    if (filterValue == "all")
        return true;
        
    var grades = school.GradesServed;
    var matchingFilter = schoolTypeHash[grades];
    if (matchingFilter != undefined) {
        if (matchingFilter.Enabled)
            return true;
    }
    return false;
}

function MatchesFilters(school) {
    //add filter logic here
    if (!CheckLocationMatchesFilter(school))
        return false;
    if (!CheckTypeMatchesFilter(school))
        return false;
    return true;
}

//add all schools to the filter list
//add change handler to filter list
//add all school markers to the map
function CreateMarkers(schools) {
    for (var i = 0; i < schools.length; i++) {
        var school = schools[i];
        school.Index = i;
        AddSchoolMarker(school);
    }
}


function EnableAllLocationFilters() {
    for (var i = 0; i < schoolLocations.length; i++) {
        var filter = schoolLocations[i];
        filter.Enabled = true;
    }
}

function SetLocationFilterEnabled(id) {
    for (var i = 0; i < schoolLocations.length; i++) {
        var filter = schoolLocations[i];
        filter.Enabled = (filter.Id == id);
    }
}

function EnableAllTypeFilters() {
    for (var i = 0; i < schoolTypes.length; i++) {
        var filter = schoolTypes[i];
        filter.Enabled = true;
    }
}

function SetTypeFilterEnabled(id) {
    for (var i = 0; i < schoolTypes.length; i++) {
        var filter = schoolTypes[i];
        filter.Enabled = (filter.Id == id);
    }
}

function GetSchoolPopupHtml(schoolId) {
    var school = GetSchoolById(schoolId);
    var sbuffer = [];
    sbuffer[sbuffer.length] = '<div class="schoolPopup">'
                    + '<div class="schoolPopupHeader">' + school.Name + '</div>'
                    + '<div class="schoolPopupDetails">'
                    + '<div class="schoolPopupAddress">'
                    + school.Address
                    + '</div>';
    sbuffer[sbuffer.length] = '<span class="schoolPopupLabel">Principal:</span><span class="schoolPopupPhone">' + school.Principal + '</span>';
    sbuffer[sbuffer.length] = '<span class="schoolPopupLabel">Phone:</span><span class="schoolPopupPhone">' + school.PhoneNumber+'</span>'
                    + '<span class="schoolPopupLabel">Fax:</span><span class="schoolPopupFax">' + school.FaxNumber + '</span>'
                    + '<div style="clear:both"></div>'
                    + '</div>' //end details
                    + '<div class="schoolPopupFooter">';

    if (school.Regions.length > 0) {
        sbuffer[sbuffer.length] = '<a href="javascript:ShowAttendanceBoundary(\'' + school.Id + '\');">Attendance Boundaries</a>'
                    + '<span class="schoolListItemNavSeparator">|</span>';
    }
    sbuffer[sbuffer.length] = '<a href="' + school.PageUrl + '">School Profile</a>'

    sbuffer[sbuffer.length] = '</div></div>';       //end footer and popup

    

    
    return sbuffer.join('');
}

function AddSchoolMarker(schoolItem) {
    var point = new GLatLng(schoolItem.Latitude, schoolItem.Longitude);
    var marker = new GMarker(point, { icon: GetIcon(schoolItem) });

    schoolItem.Point = point;
    schoolItem.Marker = marker;

    GEvent.addListener(marker, "click", function() {
        var infoHtml = GetSchoolPopupHtml(schoolItem.Id);
        schoolMap.openInfoWindowHtml(point, infoHtml);
    });
    GEvent.addListener(marker, 'mouseover', function() {
        markerHover(schoolItem.Id);
    });
    GEvent.addListener(marker, 'mouseout', function() {
        markerHoverEnd(schoolItem.Id);
    });
}


function FilterSchools(schools) {
    for (var i = 0; i < schools.length; i++) {
        var school = schools[i];
        if (MatchesFilters(school))
            school.Visible = true;
        else
            school.Visible = false;
    }
}

function RenderMarkers(schools) {
    $.each(schools, function(index, value) {
        if (value.Visible)
            schoolMap.addOverlay(value.Marker);
    });
}

function SetMapBestFit(schools) {
    // map: an instance of GMap2
    // latlng: an array of instances of GLatLng
    
    schoolMap.closeInfoWindow();
    
    var latlngbounds = new GLatLngBounds();
    if (currentLocation != null)
        latlngbounds.extend(currentLocation.Point);

    var pinsShowing = 0;
    for (var i = 0; i < schools.length; i++) {
        var school = schools[i];
        if (school.Visible) {
            var latLon = new GLatLng(school.Latitude, school.Longitude);
            latlngbounds.extend(latLon);
            pinsShowing++;
        }
    }
    if (pinsShowing > 0) {
        initialZoomLevel = schoolMap.getBoundsZoomLevel(latlngbounds);

        if (pinsShowing < allSchools.length)
            initialZoomLevel = initialZoomLevel - 1;
        
        schoolMap.setZoom(initialZoomLevel);
        
        setTimeout(function() { schoolMap.panTo(latlngbounds.getCenter()); }, 500);
    }
}

function SetMapBestFitRegions(regions) {
    if (regions.length > 0) {
        var bounds = new GLatLngBounds();

        for (var i = 0; i < regions.length; i++) {
            var region = regions[i];
            var regionBounds = region.Overlay.getBounds();
            bounds.extend(regionBounds.getNorthEast());
            bounds.extend(regionBounds.getSouthWest());
        }
        if (bounds != null) {
            var initialZoomLevel = schoolMap.getBoundsZoomLevel(bounds);
            schoolMap.setZoom(initialZoomLevel);
            setTimeout(function() { schoolMap.panTo(bounds.getCenter()); }, 500);
        }        
    }
}

function CenterOnSchool(id, showInfo) {
    schoolMap.setZoom(initialZoomLevel);
    var school = GetSchoolById(id);
    schoolMap.panTo(new GLatLng(school.Latitude, school.Longitude), 13);
    if (showInfo) {
        schoolMap.openInfoWindowHtml(school.Point, GetSchoolPopupHtml(school.Id));
    }
}

function CenterOnSchoolAndZoom(id, showInfo) {
    //schoolMap.setZoom(initialZoomLevel);
    HideAttendanceBoundaries();
    HideBoundaryLegend();
    var school = GetSchoolById(id);
    schoolMap.setCenter(new GLatLng(school.Latitude, school.Longitude), 13);
    if (showInfo) {
        schoolMap.openInfoWindowHtml(school.Point, GetSchoolPopupHtml(school.Id));
    }
}

function ShowBoundaryLegend(school, html) {
    $('#mapLegendTitle').html('Attendance Boundaries for '+school.Name);
    $('#boundaryLegend').html(html);
    $('#mapWrapperFooter').show();
    $.fancybox.resize();
    $('#mapLegendContainer').fadeIn(1500);
    
}
function HideBoundaryLegend() {
    HideAttendanceBoundaries();
    $('#mapLegendContainer').hide();
    $('#mapWrapperFooter').hide();
    $.fancybox.resize();
}

function GetSchoolById(id) {
    return schoolHash[id];
}

function RenderSchoolList(schools) {
    var sbuffer = [];
    $("#schoolList").hide();
    var schoolsRendered = 0;
    for (var i = 0; i < schools.length; i++) {
        var school = schools[i];
        if (school.Visible) {
            schoolsRendered++;

            var displayHideAb = "none";
            if (school.RegionVisible) {
                displayHideAb = "inline";
            }
            sbuffer[sbuffer.length] = '<div id="scList_' + school.Id + '" class="schoolListItem">'
                    + '<img id="scListIcon_' + school.Id + '" class="schoolListIconImage" src="' + school.IconImage + '"/>'
                    + '<div class="schoolListItemName" onclick="CenterOnSchoolAndZoom(\'' + school.Id + '\', true);">' + school.Name + '</div><div class="schoolListItemLinks">';
            if (school.Regions.length > 0) {
                sbuffer[sbuffer.length] = '<a href="javascript:ShowAttendanceBoundary(' + school.Id + ');">Attendance Boundary</a><span class="mapLinkDivider">&nbsp;|&nbsp;</span>'
            }
            sbuffer[sbuffer.length] = '<a href="' + school.PageUrl + '">School Profile</a></div>'                  
                    + '<div style="clear:both;"></div>'
                    + '</div>';
        }
    }

    var html = sbuffer.join('');
    $("#schoolList").html(html);
    $("#schoolList").fadeIn(750);
    if (schoolsRendered > 0) {
        $(".schoolListItem").hover(schoolListItemHover, schoolListItemHoverEnd);
    }
    else {
        html = '<div class="noSchoolsFound">No schools found matching current filters.<div>';
        $("#schoolList").html(html);
    }
}

function ShowBoundaryPopup(id) {
    $('.boundaryLinksPopup').hide();
    $('#blp_' + id).slideDown();
}
function HideBoundaryPopup(id) {
    $('#blp_' + id).slideUp();
}



function schoolListItemHover() {
    //$(this).addClass('schoolListItemHl');
    var id = $(this).attr('id');
    var schoolId = id.replace("scList_", "");
    var school = GetSchoolById(schoolId);
    school.Marker.setImage(school.IconImageHl);
    $("#scListIcon_" + schoolId).attr('src', school.IconImageHl);
}
function schoolListItemHoverEnd() {
    //$(this).removeClass('schoolListItemHl');
    var id = $(this).attr('id');
    var schoolId = id.replace("scList_", "");
    if (currentSchoolId != null && currentSchoolId == schoolId) {
        return;
    }   
    
    var school = GetSchoolById(schoolId);
    school.Marker.setImage(school.IconImage);
    $("#scListIcon_" + schoolId).attr('src', school.IconImage);
}

function markerHover(schoolId) {
    var school = GetSchoolById(schoolId);
    school.Marker.setImage(school.IconImageHl);      
    
    $("#scListIcon_" + schoolId).attr('src', school.IconImageHl);
}
function markerHoverEnd(schoolId) {
    if (currentSchoolId != null && currentSchoolId == schoolId) {
        return;
    }   
    var school = GetSchoolById(schoolId);
    school.Marker.setImage(school.IconImage);
    $("#scListIcon_" + schoolId).attr('src', school.IconImage);
}

