﻿
var map; 
var currentMarker;
var currentMarkerInfo;

var bounds;
var countryCode;

// an array holding all the listeners added on the map and the attached overlays
var listeners = [];

// keep only one instance of type ELable to serve all the popup overlays.
var baloon;

// 0 => locked state
// 1 => unlocked state
// used to block the onclick event on markers if a marker is loading in the background
var markerInfoLock = function() {
	this.value = 0;
	return {
		lock: function() {
			value = 0;
		},
		unlock: function() {
			value = 1;
		},
		isLocked: function() {
			return (value == 0);
		}
	}
} ();


function InitializeMap() {	
  if (GBrowserIsCompatible()) {
  
    var settings = ReadSettings();
    countryCode = settings["country-code"];

    if (settings != null) {
    		baloon = new ELabel();
				   
        map = new GMap2(document.getElementById("map"));
        
        bounds = new GLatLngBounds();
         
        map.addMapType(G_PHYSICAL_MAP);
        map.setMapType(G_PHYSICAL_MAP);
        
        var topRight = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10));
        var bottomRight = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,10));
        
        map.addControl(new GSmallMapControl());
         
        var mapTypeControl = new GHierarchicalMapTypeControl();
        mapTypeControl.clearRelationships();
        mapTypeControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels weergeven", false);

        map.addControl(mapTypeControl, topRight);

        var handler = GEvent.addListener(map, "dblclick", function() {
        	map.removeControl(mapTypeControl);
        	map.addControl(new GHierarchicalMapTypeControl(), bottomRight);
        });

        listeners.push(handler);

        InsertMarkers(map, settings["areas"]);
        
        GetCountryInfo();

        BestFit(map, bounds);

        // enable info baloons for markers
        markerInfoLock.unlock();
    }
  }
}

function BestFit(map, bounds) 
{
    // maximum zoom level accepted
    var maxZoomLevel = 8;

    // get calculated zoom.
    var zoom = map.getBoundsZoomLevel(bounds);
    
    // if calculated zoom is greater than maximum zoom level accepted reset the zoom to the maximum accepted level
    zoom = zoom > maxZoomLevel ? maxZoomLevel : zoom;
    
    map.setCenter(bounds.getCenter(), zoom);
 }

 function GetCountryInfo() {
 		if ((countryCode != undefined) && (countryCode != '') && (countryCode.length == 2))
    {
        request = 'http://ws.geonames.org/countryInfoJSON?formatted=true&lang=nl&country=' + countryCode + '&style=full&callback=AddCountryMarginToBounds';

        // Create a new script object
        aObj = new JSONscriptRequest(request);
        
        // Build the script tag
        aObj.buildScriptTag();
        
        // Execute (add) the script tag
        aObj.addScriptTag();
    }

}

function AddCountryMarginToBounds(jsonData)
{
  if (jsonData == null) 
  {
    // There was a problem parsing search results
    return;
  }
  
  var countryInfo = jsonData.geonames[0];
  
  if (countryInfo)
  {
      var westLong = countryInfo.bBoxWest;
      var eastLong = countryInfo.bBoxEast;
      var northLat = countryInfo.bBoxNorth;
      var southLat = countryInfo.bBoxSouth;
      
      var northWest = new GLatLng(northLat, westLong);
      var southEast = new GLatLng(southLat, eastLong);
      
      bounds.extend(northWest);
      bounds.extend(southEast);
      
      BestFit(map, bounds);
  }
}

function RemoveCurrentMarker(map)
{
	if (currentMarker && currentMarkerInfo) {
		
		 currentMarker.setImage(currentMarker.getIcon().image.replace('act.png', '.png'));
     map.removeOverlay(currentMarkerInfo);

     delete currentMarkerInfo.html;
  }
}

function ReadSettings()
{
  var mapDiv = document.getElementById("gsmMapMainDiv");
  
  if (mapDiv !== undefined)
  {
     //for IE
     var settings = mapDiv.childNodes[0].value;
     if (settings == undefined)
     {
        // for non-IE
        settings = mapDiv.childNodes[1].value;
     }
     
     var geoSettings = settings.split(';');
     
     var i = 0;
     
     var arraySettings = new Array(geoSettings.length);
     
     for (i = 0; i < geoSettings.length; i++)
     {
       var geoSet = geoSettings[i].split('=');
       var key = geoSet[0];

       geoSet.slice(0, 1);
       
       var value = geoSet.join('');

       if (key == "areas")
       {
         value = ReadAreaSettings(value);  
       }
       
       arraySettings[key] = value;
     }
     
     return arraySettings;
  }
  
  return null;
}

function ReadAreaSettings(settings)
{
   var areas = settings.split('}');
   var arrayAreaSettings = new Array(areas.length - 1);
      
   for (i = 0; i < areas.length - 1; i++)
   {
      var areaSettings = areas[i].split('^');
      var areaSetting = new Array(areaSettings.length);
      
      var id = 'area' + areaSettings[0].substring(1);
      
      areaSetting["latitude"] = parseFloat(areaSettings[1].replace(',', '.'), 10);
      areaSetting["longitude"] = parseFloat(areaSettings[2].replace(',', '.'), 10);
      areaSetting["name"] = areaSettings[3];
      areaSetting["count"] = areaSettings[4];
      areaSetting["id"] = id;
      areaSetting["roundtrips"] = ReadRoundtripSettings(areaSettings[5]);
      areaSetting["href"] = areaSettings[6];
      areaSetting["flagSrc"] = (areaSettings[7]);
      
      arrayAreaSettings[id] = areaSetting;
   }
   
   return arrayAreaSettings;
   
}

function ReadRoundtripSettings(roundtripSettings)
{
   if (roundtripSettings != '')
   {
       var roundtrips = roundtripSettings.split(']');
       var i = 0;
       var arrayRoundtripSettings = new Array(roundtrips.length - 1);
        
       for (i = 0; i < roundtrips.length - 1; i++)
       {
          var rtrSettings = roundtrips[i].split('|');
          var rtrSetting = new Array(rtrSettings.length);
          
          var id = 'rtr' + rtrSettings[0].substring(1);
          
          rtrSetting["id"] = id;
          rtrSetting["latitude"] = parseFloat(rtrSettings[1].replace(',', '.'), 10);
          rtrSetting["longitude"] = parseFloat(rtrSettings[2].replace(',', '.'), 10);
          rtrSetting["icon"] = rtrSettings[3];
          rtrSetting["title"] = rtrSettings[4];
          rtrSetting["countryid"] = rtrSettings[5];
           
          arrayRoundtripSettings[id] = rtrSetting;
       }
       
       return arrayRoundtripSettings;
   }
   
   return null;
}

function InsertMarkers(map, areaSettings) {
	for (var area in areaSettings) {
		
    if (areaSettings.length > 1)
    {
       InsertAreaMarker(map, areaSettings[area]);
    }
    else
    {
      if (areaSettings[area]["name"] != "dummyArea")
      {
        countryCode = '';
      }  
      InsertRoundtripMarkers(map, areaSettings[area]);
    }
  }
}

function InsertAreaMarker(map, areaSetting) {
	var opts = { c: areaSetting.count, i: areaSetting.id, n: areaSetting.name, h: areaSetting.href, f:areaSetting.flagSrc };
	var marker = new OverlayArea(new GLatLng(areaSetting.latitude, areaSetting.longitude), opts);
	map.addOverlay(marker);

	bounds.extend(marker.getPoint());
}

function InsertRoundtripMarkers(map, areaSetting)
{ 
    var roundtripMarkers = areaSetting["roundtrips"];
    
    if (roundtripMarkers != null)
    {
        InsertRoundtripMarkerIcons(map, roundtripMarkers);
    }
}

function InsertRoundtripMarkerIcons(map, roundtripMarkers)
{
   for (var rtr in roundtripMarkers)
   {
     var rtrMarker = GetRoundtripMarker(roundtripMarkers[rtr]);
      
     map.addOverlay(rtrMarker);
     SetRoundtripMarkerEventListeners(map, rtrMarker, roundtripMarkers[rtr]);
     
     bounds.extend(rtrMarker.getPoint());
   }
}

function SetRoundtripMarkerEventListeners(map, marker, roundtripSettings)
{
	var handler = GEvent.addListener(marker, "click", function() {
		// check to see if any info baloon is opening

		if (!markerInfoLock.isLocked()) {

			// disable marker info baloons
			markerInfoLock.lock();

			GetRtrInfo(map, marker, roundtripSettings);
		}
	});
	
	listeners.push(handler);	
}

// if the marker baloon is opened and the baloon does not fit the map container, recenter the map
function PanMap(map, marker) {	
	// this 2 widths should match $get('map').style.width !!!
	var containerWidth = 578;

	
	// the pixel coordinates of the marker
	var markerPixelCoord = map.fromLatLngToContainerPixel(marker.getPoint());
	
	// the minimum top/left number of pixels as padding
	var topBorder = 90;
	var widthBorder = 80;
	
	// the minimum number of pixel space needed on the left
	var overlayWidth = 340;
	overlayWidth = (overlayWidth / 2) + widthBorder;
	
	// the minimum number of pixel space needed on top
	var overlayHeight = 150;
		overlayHeight = overlayHeight + topBorder;

	// the offset the map will be panned by
	var offSetX = 0, offSetY = 0;
	
	// left margin check	
	// if the baloon extends to the left, out of the map container, pan the map to the right with 
	// the amount of overflowed pixels
	if (markerPixelCoord.x < overlayWidth) {
		offSetX += overlayWidth - markerPixelCoord.x;
	}

	// right margin check
	// if the baloon extends to the right, out of the map container, pan the map to the left with
	// the amount of overflowed pixels
	if (containerWidth - markerPixelCoord.x < overlayWidth) {
		offSetX -= (overlayWidth - (containerWidth - markerPixelCoord.x));
	}

	// top margin check
	// if the baloon extends to the top, out of the map container, pan the map to the right with 
	// the amount of overflowed pixels
	if (markerPixelCoord.y < overlayHeight) {
		offSetY += overlayHeight - markerPixelCoord.y;
	}

	if (offSetX !== 0 || offSetY !== 0) {
		map.panBy(new GSize(offSetX, offSetY));
	}
}

function GetRoundtripMarker(roundtripSetting)
{
    var markerIcon = GetRtrIcon(roundtripSetting["icon"]);
    return new GMarker(new GLatLng(roundtripSetting["latitude"], roundtripSetting["longitude"]), {icon: markerIcon, title: roundtripSetting["title"]});
}

function GetRtrIcon(iconHref) 
{
    var icon = new GIcon();
    icon.image = iconHref;
    icon.iconAnchor = new GPoint(16, 16);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(35, 35);
     
    return icon;
}
      
function GetRtrInfo(map, marker, roundtripSettings)
{
  try {
  	SNP.GoogleMaps.GMSInfoProvider.GetRoundtripInfo(parseInt(roundtripSettings["id"].replace('rtr', ''), 10),
                        parseInt(roundtripSettings["countryid"], 10),
                        function(result) {
  												
                        	// remove current overlay
                        	RemoveCurrentMarker(map);

                        	// if there already exists a marker that we've previously selected, display it
                        	if (window.snpLastMarker) {
                        		window.snpLastMarker.show();
                        	}

                        	window.snpLastMarker = marker;

                        	var iconSrc = roundtripSettings["icon"].replace(".png", "act.png");

                        	snpLastMarker.hide();

                        	var lastMarkerPoint = snpLastMarker.getLatLng();

                        	var resultInfos = result.split('@');

                        	var infoMarker = baloon.setValues(lastMarkerPoint, resultInfos[0], 0, parseInt(resultInfos[1], 10), iconSrc);

                        	currentMarker = snpLastMarker;
                        	currentMarkerInfo = infoMarker;

                        	map.addOverlay(infoMarker);

                        	// pan map
                        	PanMap(map, marker);

                        	// logic specific to IE6
                        	// it applies the AlphaLoader filter to the PNGs inside the GoogleMapsOverlay.ascx			
                        	if (navigator.appVersion.indexOf('MSIE 6.0') > -1) {
                        		var markerImg = document.getElementById('markerId');
                        		if (markerImg) {
                        			document.getElementById('markerContainer').innerHTML = applyTransparencyFilter(markerImg, 'position:absolute;left:160px;', 'image');
                        		}

                        		var closingImg = document.getElementById('closer');
                        		if (closingImg) {
                        			document.getElementById('closerContainer').innerHTML = applyTransparencyFilter(closingImg, '', 'image');
                        		}
                        	}
                        	
                        	// enable marker info baloons
                        	markerInfoLock.unlock();
                        },
      FailedCallback);
    }
  catch (e) {
  	FailedCallback(e);
  }
}

function FailedCallback(e){ }

function clearMarkers() {
	var i = 0;
	// remove listeners
	for (i; i < listeners.length; i++) {
		GEvent.removeListener(listeners.pop());
	}
	
	// clear markers
	if (map) {
		map.clearOverlays();
	}

	// remove the listener array
	delete listeners;
}

function cleaner() {
	// remove all handlers from all the DOM elements
	purgeHandlers(document);
	
	clearMarkers();

	GEvent.clearListeners(map, 'dblclick');

	GUnload();
}

Sys.Application.add_load(function() {
			InitializeMap();
});

Sys.Application.add_unload(function() {
		cleaner();
});
