//<![CDATA[

// Object literal with data and functions for displaying Google Maps
var EPiServerGoogleMaps =
{
    canvas: {},
    map: {},
    config: {},
    data: {},
    initScript: false,
    initFunctionsCalled: false,
    pointsData: {},
    openOverlays: {},
    
    load: function()
    {
        if (GBrowserIsCompatible()) 
        {    
            EPiServerGoogleMaps.canvas = document.getElementById("googleMap");
            EPiServerGoogleMaps.map = new GMap2(EPiServerGoogleMaps.canvas);
            EPiServerGoogleMaps.map.disableDoubleClickZoom();
            
            EPiServerGoogleMaps.pointsData = Array();
            EPiServerGoogleMaps.openOverlays = Array();
                      
            GDownloadUrl(EPiServerGoogleMaps.config, function(vdata, responseCode)
            {
                var errorMessage = '';
                if (responseCode == 200)
                {
                    var xml = GXml.parse(vdata);
                    if (xml)
                    {                                        
                        EPiServerGoogleMaps.config = DOMUtils.getFirstChildNodeByName(xml, 'config'); 
                        EPiServerGoogleMaps.data = DOMUtils.getFirstChildNodeByName(xml, 'data');
                        EPiServerGoogleMaps.initScript = DOMUtils.getFirstChildNodeByName(xml, 'initscript');
                        
                        errorMessage = EPiServerGoogleMaps.mapInit(); 
                    } 
                    else 
                    {
                        errorMessage = 'Error when parsing the map configuration xml.';
                    }
                } 
                else 
                { 
                    errorMessage = 'Error when getting the map configuration.';
                }
                if  ((errorMessage) && (errorMessage != ''))
                    alert(errorMessage);
            });                    
        }
    },
    
    mapInit: function()
    {
        // Set map size
        var size = DOMUtils.getFirstChildNodeByName(EPiServerGoogleMaps.config, 'size');
        
        var width = DOMUtils.getFirstChildNodeValueByName(size, 'width');
        var height = DOMUtils.getFirstChildNodeValueByName(size, 'height');
        
        EPiServerGoogleMaps.setMapSize(width, height);
        
        // Center map and set zoom
        var centerPoint = EPiServerGoogleMaps.findCenter();
        
        // Set zoom
        var zoom = DOMUtils.getFirstChildNodeValueByName(EPiServerGoogleMaps.config, 'zoom');
        centerPoint.zoom = parseInt(zoom);
        
        EPiServerGoogleMaps.setCenterAndZoom(centerPoint);

        if(centerPoint.zoom == 1)
        {
            EPiServerGoogleMaps.map.disableDragging();
        }
        else
        {
            EPiServerGoogleMaps.map.enableDragging();
        }
    
        if(centerPoint.zoom > 5)
        {
            EPiServerGoogleMaps.map.setMapType(G_NORMAL_MAP);
            EPiServerGoogleMaps.map.addControl(new GMapTypeControl());
        }
        else
        {
            EPiServerGoogleMaps.map.removeControl(new GMapTypeControl());
        }
    
        var mapType = null;
    
        try 
        {
            mapType = DOMUtils.getFirstChildNodeValueByName(EPiServerGoogleMaps.config, 'mapType');
        }
        catch (ex)
        {
            
        } 
    
        if(mapType != null)
        {
            
            switch(mapType)
            {
                case 'normal':
                    EPiServerGoogleMaps.map.setMapType(G_NORMAL_MAP);
                    break;
                case 'satellite':
                    EPiServerGoogleMaps.map.setMapType(G_SATELLITE_MAP);
                    break;
                case 'hybrid':
                    EPiServerGoogleMaps.map.setMapType(G_HYBRID_MAP);
                    break;
                case 'physical':
                    EPiServerGoogleMaps.map.setMapType(G_PHYSICAL_MAP);
                    break;
            }
        }
        else
        {
            EPiServerGoogleMaps.map.setMapType(G_PHYSICAL_MAP);
        }
             
        GEvent.addListener(EPiServerGoogleMaps.map, 'click', 
                    function(overlay, latlng, overlaylatlng) 
                    {
                        if(overlay != null)
                        {
                            var pointData = EPiServerGoogleMaps.pointsData[overlaylatlng];
                            if(pointData != undefined && pointData.pageUrl != '')
                                document.location.href = pointData.pageUrl;
                        }
                    });
        
        if(!EPiServerGoogleMaps.initFunctionsCalled)
        {
            setTimeout(EPiServerGoogleMaps.mapPointsInit, 500);
            if (EPiServerGoogleMaps.initScript)
                setTimeout(EPiServerGoogleMaps.runInitScript, 500);
        
            EPiServerGoogleMaps.initFunctionsCalled = true;
        }    
    },
    
    mapPointsInit: function()
    {
        var pois = EPiServerGoogleMaps.data.getElementsByTagName('poi');

        for (var i = 0; i < pois.length; i++)
        {   
            var point = pois[i];
            
            var pageUrl = DOMUtils.getFirstChildNodeValueByName(point, 'pageUrl');      
            
            var infoWindowContent = '';
            
            var infoWindowText = DOMUtils.getFirstChildNodeValueByName(point, 'infoWindowText');
            if(infoWindowText != '') // TODO: CHeck if empty here
            {
                infoWindowContent = DOMUtils.getFirstChildNodeValueByName(point, 'infoWindowText');
            }
            
            var infoWindowOptionsData = DOMUtils.getFirstChildNodeValueByName(point, 'infoWindowOptions');
            
            var gPointNode = DOMUtils.getFirstChildNodeByName(point, 'gpoint');
            var lat = DOMUtils.getFirstChildNodeValueByName(gPointNode, 'lat');
            var lng = DOMUtils.getFirstChildNodeValueByName(gPointNode, 'lng');
           
            var pointKey = '(' + lat + ', ' + lng + ')';
                        
            var mapPoint = new MapPoint(lat, lng);
            
            mapPoint.pageUrl = pageUrl;
            mapPoint.infoWindowContent = infoWindowContent;
            mapPoint.infoWindowOptions = EPiServerGoogleMaps.parseInfoWindowOptions(infoWindowOptionsData);
            
            EPiServerGoogleMaps.pointsData[pointKey] = mapPoint;
           
            EPiServerGoogleMaps.updateMarker(i, mapPoint);
        }
    },
    
    setMapSize: function(width, height)
    {
        EPiServerGoogleMaps.canvas.style.width = width + 'px';
        EPiServerGoogleMaps.canvas.style.height = height + 'px';
        EPiServerGoogleMaps.map.checkResize();
    },
    
    findCenter: function()
    {
        var centerNode = DOMUtils.getFirstChildNodeByName(EPiServerGoogleMaps.config, 'center');
      
        var poiNode = DOMUtils.getFirstChildNodeByName(centerNode, 'poi');
                
        var lat = DOMUtils.getFirstChildNodeValueByName(poiNode, 'lat');
        var lng = DOMUtils.getFirstChildNodeValueByName(poiNode, 'lng');
                
        var centerPoint = new MapPoint(lat, lng);
       
        return centerPoint;
    },
    
    setCenterAndZoom: function(point)
    {        
        EPiServerGoogleMaps.map.setCenter(point.location, point.zoom); 
    },
    
    parseInfoWindowOptions: function(infoWindowOptionsData)
    {
        // Create options object literal
        var infoWindowOptions = {};
        
        // Set default values for options
        infoWindowOptions.enableCloseButton = false;
       
        // Set options based on input string
        if(infoWindowOptionsData != null)
        {
            var options = infoWindowOptionsData.split('|');
            for(var i = 0; i < options.length; i++)
            {
                var option = options[i];
                
                var keyValue = option.split(';');
                var key = keyValue[0];
                var value = keyValue[1];
                
                if(key == 'backgroundColor')
                    infoWindowOptions.backgroundColor = value;
                    
                if(key == 'enableCloseButton')
                {
                    infoWindowOptions.enableCloseButton = true;
                }
            }
            
        }
     
        return infoWindowOptions;
    },
    
    updateMarker: function(markerId, point)
    {  
        var marker = EPiServerGoogleMaps.createMarker(markerId, point);
       
        // Add marker to map     
        marker.setPoint(point.location);
        EPiServerGoogleMaps.map.addOverlay(marker);
        
    },
    
    createMarker: function(markerId, point) 
    {        
        var marker = new GMarker(point);
        
        if(point.infoWindowContent != null)
        {        
        
            var infoWindowContent = ''; 
            infoWindowContent += point.infoWindowContent;
            if(point.infoWindowOptions.enableCloseButton)
            {
                infoWindowContent += '<a href="#" class="closeMe" onclick="EPiServerGoogleMaps.closeInfoWindow(this);"><img src="/ClientUI/Images/maps/button.close.png" alt="close"></a>';
            }

            marker.overlay = new SidaInfoWindow(markerId, marker, 200, -1, 'googleMapPopup', point.infoWindowOptions.backgroundColor, infoWindowContent, -20, 40);
            
            GEvent.addListener(marker, "mouseover", 
                function() 
                {
                    if(!EPiServerGoogleMaps.openOverlays.contains(marker.overlay.markerId))
                    {
                        EPiServerGoogleMaps.map.addOverlay(marker.overlay);
                        EPiServerGoogleMaps.openOverlays.add(marker.overlay.markerId);
                    }
                });
            
                
            if(!point.infoWindowOptions.enableCloseButton)
            {
                GEvent.addListener(marker, "mouseout",
                    function() 
                    {
                        EPiServerGoogleMaps.map.removeOverlay(marker.overlay);
                        EPiServerGoogleMaps.openOverlays.remove(marker.overlay.markerId);
                    });
            }
        }
            
        GEvent.addListener(EPiServerGoogleMaps.map.getInfoWindow(), 'closeclick',
            function() 
            {
                 // Center map and set zoom
                var centerPoint = EPiServerGoogleMaps.findCenter();
        
                // Set zoom
                var zoom = DOMUtils.getFirstChildNodeValueByName(EPiServerGoogleMaps.config, 'zoom');
                centerPoint.zoom = parseInt(zoom);
                
                EPiServerGoogleMaps.setCenterAndZoom(centerPoint); // TODO: How to remove without object?
            });
            
        return marker;        
    },
  
    closeInfoWindow: function(link)
    {
        // HACK! Probably leaks memory like a sieve
        var infoWindow = link.parentNode;                
        infoWindow.parentNode.removeChild(infoWindow);
      
        var htmlId =  infoWindow.id;
        var idx = htmlId.indexOf('_');
        var overlayId = htmlId.substring(idx + 1, htmlId.length);   
        
        EPiServerGoogleMaps.openOverlays.remove(overlayId);
    },
    
    runInitScript: function()
    {        
        if (EPiServerGoogleMaps.initScript.firstChild)
        {
            if (EPiServerGoogleMaps.initScript.firstChild.data)
            {
                eval(EPiServerGoogleMaps.initScript.firstChild.data);
            }
        }
    }
};

// Methods Making the Array into a list

Array.prototype.contains = function (o) 
{
    for (var i = 0; i < this.length; i++) {
        if (this[i] == o) {
            return true;
        }
    }
    return false;
};

Array.prototype.add = function(o)
{
    this[this.length] = o;
};


Array.prototype.remove = function (o) 
{
	var result = false;
	var array = [];
	for (var i = 0; i < this.length; i++) 
	{
		if (this[i] == o) 
		{
			result = true;
		} 
		else 
		{
			array.push(this[i]);
		}
	}
	this.clear();
	for (var i = 0; i < array.length; i++) 
	{
		this.push(array[i]);
	}
	array = null;
	return result;
};

Array.prototype.clear = function () 
{
    this.length = 0;
};

/*
Array.prototype.push = function (o) 
{
    this[this.length] = o;
    return this.length;
};
*/

var DOMUtils =
{
    getFirstChildNodeValueByName: function(containerNode, nodeName)
    {
        if(!containerNode) return null;
        if(!nodeName) return null;
    
        var foundElements = containerNode.getElementsByTagName(nodeName);
        
        if(foundElements.length > 0)
        {
            var firstFoundElement = foundElements[0];
            if(firstFoundElement != undefined)
            {
                var firstChild = firstFoundElement.firstChild;
                if(firstChild != undefined)
                {
                    return firstChild.data;
                }
            }
        }
        return null;
    },
    
    getFirstChildNodeByName: function(containerNode, nodeName)
    {
        if(!containerNode) return null;
        if(!nodeName) return null;
         
        var foundElements = containerNode.getElementsByTagName(nodeName);
               
        if(foundElements.length > 0)
        {
            var firstFoundElement = foundElements[0];
            if(firstFoundElement != undefined)
            {
                return firstFoundElement;
            }
        }
        return null;
    }
};

// MapPoint object constructor
function MapPoint(lat, lng)
{
    this.city = '';
    this.country = '';  
    this.location = new GLatLng(lat, lng);
    this.zoom = 1;
    this.pageUrl = '';
    this.infoWindowContent = '';
    this.infoWindowOptions = '';     
}

// Custom info window
function SidaInfoWindow(markerId, marker, divWidth, divHeight, divClassName, divBackgroundColor, template, anchorOffsetX, anchorOffsetY) 
{
    this.markerId = markerId;
	this.marker = marker;
	this.template = template;
	this.divHeight = divHeight;
	this.divWidth = divWidth;
	this.divClassName = divClassName;
	this.divBackgroundColor = divBackgroundColor;
	
	this.anchorOffsetX = anchorOffsetX;
	
	if (null == this.anchorOffsetX)
	{
		this.anchorOffsetX = 0;
	}
	
	this.anchorOffsetY = anchorOffsetY;
	
	if (null == this.anchorOffsetY)
	{
		this.anchorOffsetY = 0;
	}
}

SidaInfoWindow.prototype = new GOverlay();

SidaInfoWindow.prototype.initialize = function(map) 
{

  div = document.createElement("div");
  divUpLeft = document.createElement("div");
  divDownRight = document.createElement("div");
  divUpRight = document.createElement("div");
  divDownLeft = document.createElement("div");
  
  
  
  
  
	div.id = 'infoWindow_' + this.markerId;
	divUpLeft.style.position = "absolute";
	if(this.divHeight != -1)
		div.style.height = this.divHeight + 'px';
	if(this.divHeight != -1)
		div.style.width = this.divWidth + 'px';
	div.innerHTML = this.template;
	var theLeft = map.fromLatLngToDivPixel(this.marker.getPoint()).x
	var theTop = map.fromLatLngToDivPixel(this.marker.getPoint()).y
//  alert(this.anchorOffsetX)
  
	divUpLeft.style.top 	= (theTop - this.divHeight - this.anchorOffsetY) + 'px';
//   	 divUpLeft.style.left 	= (theLeft - this.anchorOffsetX)+ 'px';
  
  //div.addClass(this.divBackgroundColor);
	map.getPane(G_MAP_FLOAT_PANE).appendChild(divUpLeft);
	divUpLeft.appendChild(divDownRight);
	divDownRight.appendChild(divUpRight);
	divUpRight.appendChild(divDownLeft);
	divDownLeft.appendChild(div);

	if(theLeft > (parseInt(EPiServerGoogleMaps.canvas.style.width) / 2)){
		divUpLeft.style.left 	= (theLeft - div.offsetWidth + (this.anchorOffsetX * 2))+ 'px';
		div.className = this.divClassName + ' ' + this.divBackgroundColor + "Left";
		divUpLeft.className = "upLeft " + this.divBackgroundColor + "Left";
		divDownRight.className = "downRight " + this.divBackgroundColor + "Left";
		divUpRight.className = "upRight " + this.divBackgroundColor + "Left";
		divDownLeft.className = "downLeft " + this.divBackgroundColor + "Left";
	} else {
		divUpLeft.style.left 	= (theLeft - this.anchorOffsetX)+ 'px';
		div.className = this.divClassName + ' ' + this.divBackgroundColor;
		divUpLeft.className = "upLeft " + this.divBackgroundColor;
		divDownRight.className = "downRight " + this.divBackgroundColor;
		divUpRight.className = "upRight " + this.divBackgroundColor;
		divDownLeft.className = "downLeft " + this.divBackgroundColor	;
	}
	this.map_ = map;
	this.div_ = divUpLeft;  
}

SidaInfoWindow.prototype.remove = function() 
{
  this.div_.parentNode.removeChild(this.div_);
}

SidaInfoWindow.prototype.redraw = function(force) 
{
 var theLeft = this.map_.fromLatLngToDivPixel(this.marker.getPoint()).x; 
  if(theLeft > (parseInt(EPiServerGoogleMaps.canvas.style.width) / 2)){
 	 divUpLeft.style.left 	= (theLeft - div.offsetWidth + (this.anchorOffsetX*2))+ 'px';
	 div.className = this.divClassName + ' ' + this.divBackgroundColor + "Left";
  } else {
 	 divUpLeft.style.left 	= (theLeft - this.anchorOffsetX)+ 'px';
	 div.className = this.divClassName + ' ' + this.divBackgroundColor;
  }
//  this.div_.style.left 	= (this.map_.fromLatLngToDivPixel(this.marker.getPoint()).x - this.anchorOffsetX)+ 'px';
  this.div_.style.top = (this.map_.fromLatLngToDivPixel(this.marker.getPoint()).y - this.divHeight - this.anchorOffsetY) + 'px';
}
