﻿// 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;

// Auto refresh
var timerID = null;
var gTimerInterval = 30000;

// Markermanager
var markergroups = new Array();  //array of markergroup

var bShowRandom = false;
var bShowAllTags = true;
var bShowGroup = Array(true,true);
var bShowInfoWindow = true;
var bShowOverview = true;
var bStaticMap = false;

// Groups
var gSignup = 0;
var gEvent = 1;

// Search
var bSearchResults = false;
var gMapSearchResultsDivID = 'mapSearchResults';
var searchResultAddress = null;
var searchResults = null;

// Initial map settings
var gzoom = 6;
var gminzoom = 5;
var gmaxzoom = 100;
var gsearchzoom = 9;
var glat = 53.5;
var glon = -1.75;
var gMaxGroupMarker = 25;

// Icon sources
var iconEventUrl = "/images/gobananas/page/map/pins/pin_event_green.png";
var iconSignUpUrl = "/images/gobananas/page/map/pins/pin_signup_yellow.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)
        for (var x=0; x<newmarkers.length; x++)
        {
            this.markers[newmarkers[x].id] = newmarkers[x];
        }
    };

    this.removeMarker = function removeMarker(marker)
    {
        var newmarkers = new Array();
        for (var x=0; x<this.markers.length; x++)
        //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,typeid){
    this.id = id
    this.lat = lat;
    this.lon = lon;
    this.markername = markername;
    this.markerinfohtml = markerinfohtml;
    this.markeraddress = markeraddress;
    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 = $.trim(searchTerm);
    this.AddressResults = new Array();
    this.CampaignResults = new Array();

    this.Container = null;
    this.Content = null;
    this.SearchTitleContent = null;
    this.CampaignContent = null;
    this.AddressContent = null;
    
    this.AddressSearchFinished = false;
    this.CampaignSearchFinished = false;
    this.HasResults = false;
    
    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";

          var searchTerm = document.createElement("div");
          searchTerm.innerHTML = "Searching for '" + this.searchTerm + "'";
//          var searchTerm = document.createTextNode("Searching for '" + this.searchTerm + "'");
          this.SearchTitleContent = searchTerm;
          searchTitle.appendChild(searchTerm);

          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";
          searchContent.style["display"] = "none";
          this.Content.appendChild(searchContent);
          this.CampaignContent = searchContent;
          
          var addressContent = document.createElement("div");
          addressContent.className = "mapSearchContent2";
          addressContent.style["display"] = "none";
          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.CampaignSearchFinished = true;
    
        this.CampaignResults = groups;
        for (var x=0; x<groups.length; x++)
        //for (x in groups)
        {
            if (bShowGroup[x] == true)
            {
                for (var y=0; y<groups[x].markers.length; y++)
                //for (y in groups[x].markers)
                {
                     marker = groups[x].markers[y];
                     if (marker != null)
                     {
                        this.CampaignContent.style["display"] = "block";
                     
                        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) + "'/>";
                        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.markeraddress + " - " + marker.markername + "</a></div>";
                        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);
                        
                        this.HasResults = true;
                     }
                }            
            }
        }
        
        this.UpdateTitle();
    }
    
    /// Add address markers
    this.AddAddressResults = function(markers)
    {
        this.AddressSearchFinished = true;
    
        this.AddressResults = markers;
        
        for (var x=0; x<markers.length; x++)
        //for (x in markers)
        {
            this.AddressContent.style["display"] = "block";
        
            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.HasResults = true;
        }
        
        this.UpdateTitle();
    }
    
    this.UpdateTitle = function ()
    {
        if (this.CampaignSearchFinished && this.AddressSearchFinished)
        {
            if (this.HasResults)
                this.SearchTitleContent.innerHTML = "Search results for '" + this.searchTerm + "'";                        
            else
                this.SearchTitleContent.innerHTML = "No search results for '" + this.searchTerm + "'";
        }
    }

    this.DrawResults = function ()
    {
        // Draw campaign markers
        drawGroups(this.CampaignResults);

        // Draw address markers
        for (var x=0; x < this.AddressResults.length; x++)
        //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)
{   
    // Create a base icon for all of our markers that specifies the
    // shadow, icon dimensions, etc.
    var baseIcon = new GIcon();
    baseIcon.image = GetIconURL(groupID);
    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)
{
    returnValue = '';

    if (groupID == gEvent)
        returnValue = iconEventUrl;
    else if (groupID == gSignup)
        returnValue = iconSignUpUrl;

    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 (var x=0; x<searchResults.CampaignResults.length; x++)
        //for (x in searchResults.CampaignResults)
        {
            if (bShowGroup[x] == true)
            {
                for (var y=0; y<searchResults.CampaignResults[x].markers.length; y++)
                //for (y in searchResults.CampaignResults[x].markers)
                {
                    if (searchResults.CampaignResults[x].markers[y] != undefined)
                    {
                        resultCount++;
                        hasResults = true;
                
                        bounds.extend(searchResults.CampaignResults[x].markers[y].GMarker.getLatLng());
                    }
                }
            }
        }
        for (var x=0; x < searchResults.AddressResults.length; x++)
        //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 (var x=0; x < markergroups.length; x++)
        {
            if (bShowGroup[x] == true)
            {
                for (var y=0; y < markergroups[x].markers.length; y++)
                {
                    if (markergroups[x].markers[y] != undefined)
                    {
                        resultCount++;
                        hasResults = true;
                    
                        bounds.extend(markergroups[x].markers[y].GMarker.getLatLng());
                    }
                }
            }
        }

        if (hasResults && resultCount > 1)        
        {
            map.setZoom(map.getBoundsZoomLevel(bounds));
            map.setCenter(bounds.getCenter());
        }
        else if (hasResults && resultCount == 1)        
        {
            map.setZoom(9);
            map.setCenter(bounds.getCenter());
        }        
    }
}

function toggleGroup(groupID)
{
    if (groupID == gEvent || groupID == gSignup)
    {
        bShowGroup[groupID] = !bShowGroup[groupID];
        map.clearOverlays();

        if (bSearchResults)
        {
            searchResults.Refresh();
            searchResults.DrawResults();
        }
        drawGroups(markergroups);
    }
    
}

function showGroup(groupID, bShow)
{
    if (groupID == gEvent || groupID == gSignup)
    {
        bShowGroup[groupID] = bShow;
        map.clearOverlays();        
        
        if (bSearchResults)
        {
            searchResults.Refresh();
            searchResults.DrawResults();
        }
        drawGroups(markergroups);
    }
}

/*** end: Map graphics functions ***/

function refreshRandomMarker()
{
    if (timerID != null)
        clearInterval(timerID);
    GoogleMap.GetGoBananasRandomMarker(refreshRandomMarkerCallback, refreshMarkerFailedCallback, timeoutCallback);
}


function refreshRandomMarkerCallback(marker)
{
    if (marker != null)
    {
        map.clearOverlays();
    
        newmarker = new mapmarker(marker.ID, marker.Lat, marker.Lon, marker.MarkerName, marker.MarkerAddress, marker.MarkerHtml, marker.TypeID);
        map.addOverlay(newmarker.GMarker);
        map.panTo(newmarker.GMarker.getLatLng())
    }
        
    timerID = setInterval(refreshRandomMarker,gTimerInterval);
}

function timeoutCallback(args)
{
}

function refreshMarkerFailedCallback(args)
{
}

function refreshMarkers()
{
    if (bSearchResults)
    {
        refreshMarkersCallback();
    }
    
    sw = map.getBounds().getSouthWest();
    ne = map.getBounds().getNorthEast();
    
    if (bShowRandom)
    {
        GoogleMap.GetGoBananasRandomMarker(refreshRandomMarkerCallback, refreshMarkerFailedCallback, timeoutCallback);
    }
    else        
        GoogleMap.GetGoBananasMarkerGroups(sw.lng(), ne.lng(), sw.lat(), ne.lat(), refreshMarkersCallback, refreshMarkerFailedCallback, timeoutCallback);
}

function createMarkerGroups(groups)
{
    var newMarkerGroups = new Array();
    if (groups == undefined || groups == "undefined") return newMarkerGroups;
    for (var x=0; x<groups.length; x++)
    {
        group = groups[x];
        if (group != null)
        {
            newMarkerGroups[group.GroupID] = new markergroup(group.GroupName,group.GroupID);
            
            for (var y=0; y<group.Markers.length; y++)
            {
                marker = group.Markers[y]
                if (marker != null)
                {
                    newmarker = new mapmarker(marker.ID, marker.Lat, marker.Lon, marker.MarkerName, marker.MarkerAddress, marker.MarkerHtml, marker.TypeID);
                    newMarkerGroups[group.GroupID].addMarker(newmarker);                    
                }
            }
        }
        
    }
    
    return newMarkerGroups;
}

function refreshMarkersCallback(groups)
{
    newMarkerGroups = createMarkerGroups(groups);
    for (var x=0; x < newMarkerGroups.length; x++)
    {
//        if (markergroups[x] == null)
            markergroups[x] = newMarkerGroups[x];
//        else
//            markergroups[x].addMarkers(newMarkerGroups[x].markers);
    }

    map.clearOverlays();
    
    if (bSearchResults)
    {
        searchResults.Refresh();
        searchResults.DrawResults();
    }
    drawGroups(markergroups);
}


/*** Start: Map load/unload functions ***/
function loadMap() {
    if (GBrowserIsCompatible()) 
    {
        //Initialize map
        map = new GMap2(document.getElementById("mapGoBananas"));
        
        if (bStaticMap)
        {
            map.disableDoubleClickZoom();
            map.disableContinuousZoom();
            map.disableDragging();
        }
        else
        {
            map.enableDoubleClickZoom();
            map.enableContinuousZoom();
            map.enableDragging();
        }
        
        if (bShowInfoWindow)
            map.enableInfoWindow(); 
        else
            map.disableInfoWindow();
        
        map.disableScrollWheelZoom();
        map.setCenter(new GLatLng(glat, glon), gzoom);

        // Initialize geocoder        
        geocoder = new GClientGeocoder();
        
        //Add controls
        //map.addControl(new GLargeMapControl());
        //map.addControl(new GMapTypeControl());
        
        if (bShowOverview)
            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 (bShowRandom)
            refreshRandomMarker();
        else 
            refreshMarkers();
    }
}

function unloadMap()
{
    try
    {
        GUnload();
    }
    catch(err)
    {
        //Handle errors here
    }    
}

/*** End: Map load/unload functions ***/

function drawGroups(groups)
{
    for (var x=0; x < groups.length; x++)
    //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 (var x=0; x < markergroup.markers.length; x++)
    //for (x in markergroup.markers)
    {
		if (x == undefined || x == "undefined") continue;
        marker = markergroup.markers[x];
        if (marker == undefined || marker == "undefined") continue;
        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), 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 (var x=0; x<results.Placemark.length; x++)
                //for (x in results.Placemark)
                {
                    if (results.Placemark[x] == undefined || results.Placemark[x] == "undefined") continue;
                    // Allow only results in UK
                    if (results.Placemark[x].AddressDetails == undefined) continue;
                    if (results.Placemark[x].AddressDetails.Country == undefined) continue;
                    
                    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) 
{
    string = $.trim(string);
    bSearchResults = true;        
    searchResults = new SearchResults(gMapSearchResultsDivID, string);

    sw = map.getBounds().getSouthWest();
    ne = map.getBounds().getNorthEast();
    GoogleMap.SearchGoBananas(string, sw.lng(), ne.lng(), sw.lat(), ne.lat(),
        function (resultGroups)
        {
            searchResults.AddSearchResults(createMarkerGroups(resultGroups));
            mapSearchAddress(string);
        }, refreshMarkerFailedCallback, timeoutCallback);
}

/*** End: Map search functionality ***/