﻿// JScript File
/*** Start: Attach onload/onunload event handlers ***/
if (window.addEventListener) //DOM method for binding an event
{
    window.addEventListener("load", loadMap, false);
    window.addEventListener("unload", unloadMap, false);
}
else if (window.attachEvent) //IE exclusive method for binding an event
{
    window.attachEvent("onload", loadMap);
    window.attachEvent("onunload", unloadMap);
}
else if (document.getElementById) //support older modern browsers
{
    window.onload=loadMap;
    window.onunload=unloadMap;
}
/*** End: Attach onload/onunload event handlers ***/

// Global map variables
var map = null;
var geocoder = null;

// Markermanager
var markergroups = new Array();  //array of markergroup

var bShowAllTags = true;
var bShowGroup = Array(true,true,true,true);
var gSchoolsID = 0;
var gTownsID = 1;
var gUniversitiesID = 2;
var gFaithGroupsID = 3;

// Search
var bSearchResults = false;
var gMapSearchResultsDivID = 'mapSearchResults';
var searchResultAddress = null;
var searchResults = null;

// Initial map settings
var gzoom = widgetZoom || 6;
var gminzoom = 5;
var gmaxzoom = 100;
var gsearchzoom = 9;
var glat = widgetLatitude || 54;
var glon = widgetLongitude || -4;
var gMaxGroupMarker = 25;

// Icon sources
var iconSchoolUrl = "/images/mapping/icons/pins/blue_triangle.png";
var iconSchoolAchievedUrl = "/images/mapping/icons/pins/green_triangle.png";
var iconTownUrl= "/images/mapping/icons/pins/blue_square.png";
var iconTownAchievedUrl= "/images/mapping/icons/pins/green_square.png";
var iconUniversityUrl = "/images/mapping/icons/pins/blue_star.png";
var iconUniversityAchievedUrl = "/images/mapping/icons/pins/green_star.png";
var iconFaithGroupUrl = "/images/mapping/icons/pins/blue_circle.png";
var iconFaithGroupAchievedUrl = "/images/mapping/icons/pins/green_circle.png";
var iconShadow = "/images/mapping/icons/pins/pin_shadow2.png";


/*** start: Define objects ***/
function markergroup(groupname, groupid)
{
    this.groupname = groupname;
    this.groupid = groupid;
    this.markers = new Array();
    
    this.addMarker = function (newmarker)
    {
        this.markers[newmarker.id] = newmarker;
    };

    this.addMarkers = function (newmarkers) 
    {
        for (x in newmarkers)
        {
            this.markers[newmarkers[x].id] = newmarkers[x];
        }
    };

    this.removeMarker = function removeMarker(marker)
    {
        var newmarkers = new Array();
        for (x in this.markers)
        {
            if (marker.id != this.markers[x].id)
            {
                newmarkers[this.markers[x].id] = this.markers[x];
            }
        }
        this.markers = newmarkers;
    };

    this.toString = function()
    { 
        return 'Name=' + this.groupname + ', ID=' + this.groupid + ', markers=' + this.markers.length; 
    };

}

function mapmarker(id, lat,lon,markername, markeraddress, markerinfohtml,isapproved, typeid){
    this.id = id
    this.lat = lat;
    this.lon = lon;
    this.markername = markername;
    this.markerinfohtml = markerinfohtml;
    this.markeraddress = markeraddress;
    this.markerisapproved = isapproved;
    this.markergroupid = typeid;
    this.toString = function () { return 'Name=' + this.markername + ', lat=' + this.lat + ', lon=' + this.lon + ', icon=' + this.icon + ', info=' + this.markerinfohtml; };
    this.GMarker = createMapMarker(this);
}

function SearchResults(divID, searchTerm){
    this.searchTerm = searchTerm;
    this.AddressResults = new Array();
    this.CampaignResults = new Array();

    this.Container = null;
    this.Content = null;
    this.CampaignContent = null;
    this.AddressContent = null;

    this.Initialize = function (divID)
    {
          this.Container = document.getElementById(divID);
          
          this.Container.innerHTML = "";
          this.Container.style.display = "block";
          
          var searchTitle = document.createElement("div");
          searchTitle.className = "mapSearchTitle";
          searchTitle.innerHTML = "<h2>Search Results for '" + escapeHTML(this.searchTerm) + "'</h2>";
          this.Container.appendChild(searchTitle);

          var closeDiv = document.createElement("div");
          closeDiv.className = "mapCloseDiv";
          closeDiv.innerHTML = "<img src='/images/mapping/close.gif' alt='Close'/>";
          closeDiv.onclick = function () { clearSearchResults(); document.getElementById(divID).innerHTML = ""; document.getElementById(divID).style.display = 'none'; refreshMarkers()};
          this.Container.appendChild(closeDiv);
          
          var clearDiv = document.createElement("div");
          clearDiv.className = "body_hr";
          this.Container.appendChild(clearDiv);
          
          var content = document.createElement("div");
          content.id = "mapSearchContent";
          content.className = "mapSearchContent";
          this.Container.appendChild(content);
          this.Content = content;

          var searchContent = document.createElement("div");
          searchContent.className = "mapSearchContent2";
          this.Content.appendChild(searchContent);
          this.CampaignContent = searchContent;
          
          var addressContent = document.createElement("div");
          addressContent.className = "mapSearchContent2";
          this.Content.appendChild(addressContent);
          this.AddressContent = addressContent;
    }
  
    this.Refresh = function ()
    {
        this.ClearResults();
        this.AddSearchResults(this.CampaignResults);
        this.AddAddressResults(this.AddressResults);
    }
    
    this.ClearResults = function ()
    {
        this.CampaignContent.innerHTML = "";
        this.AddressContent.innerHTML = "";
    }
  
    /// Add marker groups
    this.AddSearchResults = function(groups)
    {
        this.CampaignResults = groups;
        for (x in groups)
        {
            if (bShowGroup[x] == true)
            {
                for (y in groups[x].markers)
                {
                     marker = groups[x].markers[y];
                     if (marker != null)
                     {
                        var itemIcon = null;
                        itemIcon = document.createElement("div");
                        itemIcon.className = "mapSearchIcon";
                        itemIcon.innerHTML += "<img onclick='gotoMarker(" + marker.markergroupid + ", " + marker.id + "); return false;' src='" + GetIconURL(marker.markergroupid, marker.markerisapproved) + "'/>";
                        this.CampaignContent.appendChild(itemIcon);

                        var item = null;
                        item = document.createElement("div");
                        item.id = marker.id;
                        item.className = "mapSearchItem";
                        item.innerHTML = "<div><a href='#' onclick='gotoMarker(" + marker.markergroupid + ", " + marker.id + "); return false;'>" + marker.markername + "</a></div>";
                        item.innerHTML += marker.markeraddress;
                        this.CampaignContent.appendChild(item);

                        var itemClear = null;
                        itemClear = document.createElement("div");
                        itemClear.className = "clear_page";
                        itemClear.innerHTML = "<img src='/images/spacer.gif' width='1' height='2' alt='' />";
                        this.CampaignContent.appendChild(itemClear);
                     }
                }            
            }
        }
    }
    
    /// Add address markers
    this.AddAddressResults = function(markers)
    {
        this.AddressResults = markers;
        
        for (x in markers)
        {
            var itemIcon = null;
            itemIcon = document.createElement("div");
            itemIcon.className = "mapSearchIcon";
            itemIcon.innerHTML += "<img onclick='gotoAddressMarker(" + x + "); return false;' src='" + markers[x].getIcon().image + "'/>";
            this.AddressContent.appendChild(itemIcon);

            var item = null;
            item = document.createElement("div");
            item.className = "mapSearchItem";
            item.innerHTML = "<a href='#' onclick='gotoAddressMarker(" + x + "); return false;'>" + markers[x].getTitle() + "</a>";
            this.AddressContent.appendChild(item);

            var itemClear = null;
            itemClear = document.createElement("div");
            itemClear.className = "clear_page";
            itemClear.innerHTML = "<img src='/images/spacer.gif' width='1' height='2' alt='' />";
            this.AddressContent.appendChild(itemClear);
        }

    }
    
    this.DrawResults = function ()
    {
        // Draw campaign markers
        drawGroups(this.CampaignResults);

        // Draw address markers
        for (x in this.AddressResults)
        {
            map.addOverlay(this.AddressResults[x]);
        }        
    }
    
    this.Initialize(divID);
}
/*** end: Define object ***/

/*** start: Icon functions ***/

/// Return icon for campaign marker
function createIcon(groupID, isApproved)
{   
    // Create a base icon for all of our markers that specifies the
    // shadow, icon dimensions, etc.
    var baseIcon = new GIcon();
    baseIcon.image = GetIconURL(groupID, isApproved);
    baseIcon.shadow = iconShadow;
        
    baseIcon.iconSize = new GSize(23, 30);
    baseIcon.shadowSize = new GSize(34, 31);
    baseIcon.iconAnchor = new GPoint(11, 29);
    baseIcon.infoWindowAnchor = new GPoint(12, 2);
    //baseIcon.infoShadowAnchor = new GPoint(32, 29);
    
    return baseIcon;
}

/// Return the source url for campaign icon
function GetIconURL(groupID, isApproved)
{
    returnValue = '';

    if (isApproved)
    {
        if (groupID == gSchoolsID)
            returnValue = iconSchoolAchievedUrl;
        else if (groupID == gTownsID)
            returnValue = iconTownAchievedUrl;
        else if (groupID == gUniversitiesID)
            returnValue = iconUniversityAchievedUrl;
        else if (groupID == gFaithGroupsID)
            returnValue = iconFaithGroupAchievedUrl;
    }
    else
    {
        if (groupID == gSchoolsID)
            returnValue = iconSchoolUrl;
        else if (groupID == gTownsID)
            returnValue = iconTownUrl;
        else if (groupID == gUniversitiesID)
            returnValue = iconUniversityUrl;
        else if (groupID == gFaithGroupsID)
            returnValue = iconFaithGroupUrl;
    }
    return returnValue;
}

/*** end: Icon functions ***/

/*** start: Map graphics functions ***/

function mapDragEnd()
{
    refreshMarkers();
}

function mapZoomStart()
{
    map.clearOverlays();
}

function mapZoomEnd(oldLevel, newLevel) 
{
    if (newLevel < gminzoom)
    {
        zoomIn();
    }
    if (newLevel > gmaxzoom)
    {
        zoomOut();
    }

    refreshMarkers();        
}

function zoomIn()
{
    map.zoomIn();
}

function zoomOut()
{
    map.zoomOut();
}

function zoomToMarkers()
{
    var bounds = new GLatLngBounds();
    var hasResults = false;
    var resultCount = 0;

    if (bSearchResults)
    {
        for (x in searchResults.CampaignResults)
        {
            if (bShowGroup[x] == true)
            {
                for (y in searchResults.CampaignResults[x].markers)
                {
                    resultCount++;
                    hasResults = true;
                
                    bounds.extend(searchResults.CampaignResults[x].markers[y].GMarker.getLatLng());
                }
            }
        }
        for (x in searchResults.AddressResults)
        {
            resultCount++;
            hasResults = true;
            
            bounds.extend(searchResults.AddressResults[x].getLatLng());
        }
        
        if (hasResults && resultCount > 1)
        {
            map.setZoom(map.getBoundsZoomLevel(bounds));
            map.setCenter(bounds.getCenter());
        }
    }
    else
    {
        for (x in markergroups)
        {
            if (bShowGroup[x] == true)
            {
                for (y in markergroups[x].markers)
                {
                    resultCount++;
                    hasResults = true;
                
                    bounds.extend(searchResults.CampaignResults[x].markers[y].GMarker.getLatLng());
                }
            }
        }

        if (hasResults && resultCount > 1)        
        {
            map.setZoom(map.getBoundsZoomLevel(bounds));
            map.setCenter(bounds.getCenter());
        }
    }
}

function toggleGroup(groupID)
{
    if (groupID == gSchoolsID || groupID == gTownsID || groupID == gUniversitiesID || groupID == gFaithGroupsID)
    {
        bShowGroup[groupID] = !bShowGroup[groupID];
        map.clearOverlays();

        if (bSearchResults)
        {
            searchResults.Refresh();
            searchResults.DrawResults();
        }
        else
        {
            drawGroups(markergroups);
        }
    }
    
}

/*** end: Map graphics functions ***/


function refreshMarkers()
{
	//flag "widgetIsHideMarkers" can be set outside the current script
	if (widgetIsHideMarkers)
	{
		map.addOverlay(new GMarker(new GLatLng(glat, glon), {}));
		return;
	}

    if (bSearchResults)
    {
        refreshMarkersCallback();
    }
    else
    {
        sw = map.getBounds().getSouthWest();
        ne = map.getBounds().getNorthEast();
        GoogleMap.GetMarkerGroups(sw.lng(), ne.lng(), sw.lat(), ne.lat(),refreshMarkersCallback);
    }
}

function createMarkerGroups(groups)
{
    newMarkerGroups = new Array();
    for (x in groups)
    {
        group = groups[x];
        if (group != null)
        {
            newMarkerGroups[group.GroupID] = new markergroup(group.GroupName,group.GroupID);
            
            for (y in group.Markers)
            {
                marker = group.Markers[y]
                if (marker != null)
                {
                    newmarker = new mapmarker(marker.ID, marker.Lat, marker.Lon, marker.MarkerName, marker.MarkerAddress, marker.MarkerHtml, marker.Approved, marker.TypeID);
                    newMarkerGroups[group.GroupID].addMarker(newmarker);                    
                }
            }
        }
        
    }
    
    return newMarkerGroups;
}

function refreshMarkersCallback(groups)
{
    newMarkerGroups = createMarkerGroups(groups);
    for (x in newMarkerGroups)
    {
//        if (markergroups[x] == null)
            markergroups[x] = newMarkerGroups[x];
//        else
//            markergroups[x].addMarkers(newMarkerGroups[x].markers);
    }

    map.clearOverlays();
    
    if (bSearchResults)
    {
        searchResults.Refresh();
        searchResults.DrawResults();
    }
    else
        drawGroups(markergroups);
    
        
}

/*** Start: Map load/unload functions ***/
function loadMap() {
    if (GBrowserIsCompatible()) 
    {
        //Initialize map
        map = new GMap2(document.getElementById("map"));
        map.enableDoubleClickZoom();
        map.enableContinuousZoom();        
        map.disableScrollWheelZoom();
        map.setCenter(new GLatLng(glat, glon), gzoom);

        // Initialize geocoder        
        geocoder = new GClientGeocoder();
        
        //Add controls
        //map.addControl(new GLargeMapControl());
        //map.addControl(new GMapTypeControl());
        map.addControl(new GOverviewMapControl());

        // Add map event listeners        
        GEvent.addListener(map, "dragend", mapDragEnd);
        GEvent.addListener(map, "zoomend", mapZoomEnd);
        GEvent.addListener(map, "zoomstart", mapZoomStart);
         
        //Initialize and draw markers
        if (!widgetIsHideMarkers) //flag "widgetIsHideMarkers" can be set outside the current script
		{
			refreshMarkers();
		}
		else
		{
			map.addOverlay(new GMarker(new GLatLng(glat, glon), {title:"Pointer"}));
		}
    }
}

function unloadMap()
{
    try
    {
        GUnload();
    }
    catch(err)
    {
        //Handle errors here
    }    
}

/*** End: Map load/unload functions ***/

function drawGroups(groups)
{
    for (x in groups)
    {
        if (bShowGroup[x] == true)
        {
            drawGroupMarkers(groups[x]);
        }
    }
}

//function applyMapBounds(markers)
//{
//    newMarkers = Array();
//    for (x in markers)
//    {
//        if (map.getBounds().containsLatLng(markers[x].GMarker.getLatLng()))
//            newMarkers[markers[x].id] = markers[x];
//    }
//    return newMarkers;
//}

//function getArrayCount(arr)
//{
//    cnt = 0;
//    for (x in arr)
//    {
//        cnt++;        
//    }
//    
//    return cnt;
//}

//function addMarkersToMap(markers)
//{
//    for (x in markers)
//    {
//        map.addOverlay(markers[x].GMarker);
//    }
//}

function drawGroupMarkers(markergroup)
{
    i = 0;
    for (x in markergroup.markers)
    {
        marker = markergroup.markers[x];
        if (i<gMaxGroupMarker /* && map.getBounds().containsLatLng(marker.GMarker.getLatLng())*/)
        {
            map.addOverlay(marker.GMarker);
            i++;
        }
    }
}


function createMapMarker(marker)
{
    m = null;
    if (marker != null)
    {
        if (marker.lat == 0 && marker.lon == 0)
        {   
        }
        else
        {
            if (m == null)
            {
                //Create marker
                var latlon = null;
                latlon = new GLatLng(marker.lat, marker.lon);        
                m = new GMarker(latlon, {icon:createIcon(marker.markergroupid, marker.markerisapproved), title:marker.markername});
            }
            m.bindInfoWindowHtml(marker.markerinfohtml);
        }
        
    }
    
    return m;
}

function removeMarkerFromMap(marker)
{
    if (marker != null)
    {
        map.removeOverlay(marker.GMarker);
        marker.GMarker = null;
    }
}

/*** start: Map search functionality ***/

/// Go to campaign marker and show info
function gotoMarker(groupid, id)
{
    group = searchResults.CampaignResults[groupid];
    if (group != null)
    {
        marker = group.markers[id];
        if (marker != null)
        {
            GEvent.trigger(marker.GMarker, 'click');
        }
    }
    
}

/// Go to address marker and show info
function gotoAddressMarker(addresMarkerIndex)
{
    marker = searchResultAddress[addresMarkerIndex];
    if (marker != null)
    {
        GEvent.trigger(marker, 'click');
    }
    
}

/// Clear the current search results
function clearSearchResults()
{
    bSearchResults = false; 
    searchResultAddress = null;
    searchResults = null;
}

/// Do google search for string
function mapSearchAddress(string)
{
    geocoder.getLocations(
        string,
        function(results) {
            searchResultAddress = new Array();

            if (results.Status.code == 200)
            {
                for (x in results.Placemark)
                {
                    // Allow only results in UK
                    if (results.Placemark[x].AddressDetails.Country.CountryNameCode == 'GB')
                    {
                        var latlon = new GLatLng(results.Placemark[x].Point.coordinates[1], results.Placemark[x].Point.coordinates[0]);
                        var marker = new GMarker(latlon, { title:results.Placemark[x].address });
                        marker.bindInfoWindowHtml(results.Placemark[x].address);
                        searchResultAddress.push(marker);
                    }
                }
            }
            else
            {
                //Add empty search results
            }

            searchResults.AddAddressResults(searchResultAddress);
            zoomToMarkers();
            refreshMarkers();
            
        }
      );
}

/// Do campaign search and if successfull do google address search
function mapSearch(string) 
{
    bSearchResults = true;        
    searchResults = new SearchResults(gMapSearchResultsDivID, string);

    GoogleMap.SearchEntities(string, 
        function (resultGroups)
        {
            searchResults.AddSearchResults(createMarkerGroups(resultGroups));
            mapSearchAddress(string);
        });
}

/*** End: Map search functionality ***/
