﻿// We define the available location types
function LocationType() { }
var ShowPOIs;
var ListOfPOIs = null;
var AirportMap = false;

/// We define here the ZooverGoogleLocation object 
/// Constructor and getter and setter methods
function ZooverGoogleLocation (index, entityId, googlePoint, iconUrl, shadowUrl, isPOI, isAirport)
{
	var _Index = index;
	var _EntityId = entityId;
	var _GooglePoint = googlePoint;
	var _GoogleMarker = null;
	var _HighlightMarker = null;
	var _IconUrl = iconUrl;
	var _ShadowUrl = shadowUrl;
	var _IsPOI = isPOI;
	var _IsAirport = isAirport;
	this.getIndex = function () {return _Index;}
	this.getEntityId = function () {return _EntityId;}
	this.getGooglePoint = function () {return _GooglePoint;}
	this.getIconUrl = function () {return _IconUrl; }
	this.getShadowUrl = function () {return _ShadowUrl; }
	
	/// Getter function for property "GoogleMarker"
	this.getGoogleMarker = function () {return _GoogleMarker;}
	/// Setter function for property "GoogleMarker"
	this.setGoogleMarker = function (googleMarker) { _GoogleMarker = googleMarker; }
	
	/// Getter function for property "HighlightMarker"
	this.getHighlightMarker = function () {return _HighlightMarker;}
	/// Setter function for property "HighlightMarker"
	this.setHighlightMarker = function(value) { _HighlightMarker = value; }

	this.IsPOI = function() { return _IsPOI; }

	this.IsAirport = function() { return _IsAirport; }

	this.getTooltipHtml = function(entityTooltipUrl, tooltipPOI) {
		var lTooltipUrl = entityTooltipUrl;
		if (this.IsPOI() == "True" || this.IsPOI() == true) {
			lTooltipUrl = tooltipPOI;
		}

		if (this.IsAirport() == "True" || this.IsAirport() == true) {
			var lToolTipInfo = FindAirport(this.getEntityId());
			
			if (lToolTipInfo != null) {
				var lToolTipValue = lToolTipInfo.GetToolTipHtml();
				return lToolTipValue;
			}
		}
		if (lTooltipUrl != '') {
			lTooltipUrl = lTooltipUrl + '?entid=' + this.getEntityId();
			// position id is used to determine which location was highlighted
			lTooltipUrl = lTooltipUrl + '&position=' + this.getIndex();

			return "<iframe class='googleInfoWindow2' frameborder='0' scrolling='no' src='"
				+ lTooltipUrl + "'></iframe>";
		}
		return '';
	}
}

/// We define here the ZooverGoogleMap object 
/// Constructor and getter and setter methods
function ZooverGoogleMap (htmlContainerName, mapCenterLatitude, mapCenterLongitude,
	mapZoom, entityTooltipUrl, highlightCenter, tooltipPOI)
{
	var _HtmlContainerName = htmlContainerName;
	var _MapCenterLatitude = parseFloat(mapCenterLatitude);
	var _MapCenterLongitude = parseFloat(mapCenterLongitude);
	var _MapZoom = mapZoom;
	var _Map;
	var _ShowAllMarkers = true;
	var _NumberOfMarkersShown = 10;
	var _LocationsArray = new Array();
	var _EntityTooltipUrl = entityTooltipUrl;
	var _ZooverInfoWindow;
	var _OverviewMapControl;
	var _HighlightCenter = highlightCenter;
	var _TooltipPOI = tooltipPOI;

	/// Getter member for 'Map' property 
	this.getMap = function () { return _Map; }
	
	/// Setter member for 'Map' property 
	this.setMap = function (map) 
	{ 
		_Map = map;
// THE NEW INFO WINDOW MIGHT BE USED AT A LATER TIME
//		// when the markers are cleared, we make sure the info window overlay will still be there
//		GEvent.addListener(map, "clearoverlays", function() {
//			// add the zoover info window control
//			lZooverInfoWindow = new ZooverInfoWindow(_Map);
//			_ZooverInfoWindow = lZooverInfoWindow;
//			_Map.addOverlay(lZooverInfoWindow);
//		});
//		// hide the info window when the map is clicked on
//		GEvent.addListener(map, "click", function(overlay, point) {
//			if (!overlay)
//			{
//				_ZooverInfoWindow.Hide();
//				_OverviewMapControl.show();
//			}
//				
//		});
	}

	/// Getter member for 'OverviewMapControl' property
	this.getOverviewMapControl = function () { return _OverviewMapControl; }

	/// Setter member for 'OverviewMapControl' property
	this.setOverviewMapControl = function (control) { _OverviewMapControl = control; }

	/// Getter member for 'ZooverInfoWindow' property
	this.getZooverInfoWindow = function () { return _ZooverInfoWindow; }

	/// Getter member for 'HtmlContainerName' property 
	this.getHtmlContainerName = function () { return _HtmlContainerName; }
	
	/// Getter member for 'MapCenterLatitude' property 
	this.getMapCenterLatitude = function () { return _MapCenterLatitude; }
	
	/// Setter member for 'MapCenterLatitude' property 
	this.setMapCenterLatitude = function (mapCenterLatitude) { _MapCenterLatitude = mapCenterLatitude; }

	/// Getter member for 'MapCenterLongitude' property 
	this.getMapCenterLongitude = function () { return _MapCenterLongitude; }

	/// Setter member for 'MapCenterLongitude' property 
	this.setMapCenterLongitude = function (mapCenterLongitude) { _MapCenterLongitude = mapCenterLongitude;	}

	/// Getter member for 'MapZoom' property 
	this.getMapZoom = function () {return _MapZoom; }

	/// Setter member for 'MapZoom' property 
	this.setMapZoom = function (mapZoom) { _MapZoom = mapZoom; }
	
	/// Getter member for 'ShowAllMarkers' property 
	this.getShowAllMarkers = function () {return _ShowAllMarkers; }

	/// Setter member for 'ShowAllMarkers' property 
	this.setShowAllMarkers = function (showAllMarkers) { _ShowAllMarkers = showAllMarkers; }

	/// Getter member for 'NumberOfMarkersShown' property 
	this.getNumberOfMarkersShown = function () {return _NumberOfMarkersShown; }

	/// Setter member for 'NumberOfMarkersShown' property 
	this.setNumberOfMarkersShown = function (numberOfMarkersShown) { _NumberOfMarkersShown = numberOfMarkersShown; }

	/// Getter member for 'LocationsArray' property 
	this.getLocationsArray = function () {return _LocationsArray; }

	/// Setter member for 'LocationsArray' property 
	this.setLocationsArray = function (locationsArray) { _LocationsArray = locationsArray; }
	
	/// Getter member for 'EntityTooltipUrl' property
	this.getEntityTooltipUrl = function() { return _EntityTooltipUrl; }

    //The tooltip for POI
	this.getTooltipPOIUrl = function() { return _TooltipPOI; }

	this.getHighlightCenter = function() { return _HighlightCenter; }
}

/// Define the GetHighlightedIconUrl member
ZooverGoogleMap.prototype.GetHighlightedIconUrl = function (url)
{
	return url;//.replace('.png', '_highlighted.png')
}

/// Define the ReCenter member 
ZooverGoogleMap.prototype.ReCenter = function()
{
	if (GBrowserIsCompatible()) 
	{
		// set start position
		this.getMap().setCenter(new GLatLng(this.getMapCenterLatitude(), this.getMapCenterLongitude()), 
			true);
		this.getMap().setZoom(this.getMapZoom());
	}
}

/// Defines the EnsureGoogleMap member
ZooverGoogleMap.prototype.EnsureGoogleMap = function()
{
	if (this.getMap() == null)
	{
		this.MakeNewMap();
	}
}
/// Defines the MakeNewMap member
ZooverGoogleMap.prototype.MakeNewMap = function() {
	var lHtmlContainer;
	var lOverviewMapControl;
	if (GBrowserIsCompatible()) {
		lHtmlContainer = document.getElementById(this.getHtmlContainerName());
		if (lHtmlContainer != null) {
			// map object
			this.setMap(new GMap2(lHtmlContainer));

			// set start position		
			this.ReCenter();

			// add the map type control
			this.getMap().addControl(new GMapTypeControl());
			// add the zoom control
			this.getMap().addControl(new GLargeMapControl3D());
			// add a overview map control
			lOverviewMapControl = new GOverviewMapControl();
			this.getMap().addControl(lOverviewMapControl);
			// keep a reference of the overview map control as it has to be hidden when it overlaps with the info window
			this.setOverviewMapControl(lOverviewMapControl);

			if (this.getLocationsArray().length > 0) {
				this.DisplayMarkers();
			}
		}
	}
}

/// Define the AddMarkersFromXml member
ZooverGoogleMap.prototype.AddMarkersFromXml = function (locationsDataXml)
{
	this.AddLocationsFromXml (locationsDataXml);
	
	this.DisplayMarkers ();
}

/// Define the AddLocation member
ZooverGoogleMap.prototype.AddLocation = function(latitude, longitude, entityId, iconUrl, shadowUrl, isPOI, isAirport) {
	var lGooglePoint = this.CreateGooglePoint1(latitude, longitude);
	if (lGooglePoint != null) {
		this.getLocationsArray()[this.getLocationsArray().length] = new ZooverGoogleLocation(
			this.getLocationsArray().length + 1, entityId, lGooglePoint, iconUrl, shadowUrl, isPOI, isAirport);
	}
	else {
		this.getLocationsArray()[this.getLocationsArray().length] = null;
	}
}

/// Define the AddMarkersFromXml member
ZooverGoogleMap.prototype.AddLocationsFromXml = function(locationsDataXml) {
    var lGooglePoint;
    var lXmlData = GXml.parse(locationsDataXml);

    var lLocations = lXmlData.documentElement.getElementsByTagName("location");
    var lMaxMarkersShown = lXmlData.documentElement.getElementsByTagName("max-markers");
    var lCorectPointers = 0;

    if (lLocations != null) {
        var lNumberOfPOIs = GetNumberOfPOIs(this.getLocationsArray());
        this.setLocationsArray(GetArrayOnlyWithPOIs(lLocations.length, this.getLocationsArray(), lNumberOfPOIs));
        for (var i = 0; i < lLocations.length; i++) {
            lGooglePoint = this.CreateGooglePoint(lLocations[i]);
            this.getLocationsArray()[i + lNumberOfPOIs] = new ZooverGoogleLocation(lLocations[i].getAttribute("idx"),
				lLocations[i].getAttribute("ent-id"), lGooglePoint, lLocations[i].getAttribute("location-icon-url"),
				lLocations[i].getAttribute("location-shadow-url"), false);
        }
        
        // if we have the max-markers node and there is value inside
        if (lMaxMarkersShown != null && GXml.value(lMaxMarkersShown[0]).length > 0) {
            try {
                this.setNumberOfMarkersShown(parseInt(GXml.value(lMaxMarkersShown[0])));
            }
            catch (e) { }
        }
    }
    else {
        this.setLocationsArray(new Array(0));
    }
}

function GetNumberOfPOIs(currentArray){
    var lNumberOfPOIs = 0;
    for (var i=0; i < currentArray.length; i++)
    {
        if (currentArray[i].IsPOI() == "True"){
            lNumberOfPOIs++;
            currentArray[i].setGoogleMarker(null);
        }
    }
    return lNumberOfPOIs;
}

function GetArrayOnlyWithPOIs(length, currentArray, numberOfPOIs){
    var lResult = new Array(length + numberOfPOIs);
    var lCount = 0;
    for (var i=0; i < currentArray.length; i++)
    {
        if (currentArray[i].IsPOI() == "True"){
            lResult[lCount] = currentArray[i];
            lCount++;
        }
    }
    return lResult;
}

ZooverGoogleMap.prototype.ClearMarkers = function() {
    if (ListOfPOIs != null) {
        for (var i = 0; i < ListOfPOIs.length; i++) {
            this.AddLocation(ListOfPOIs[i].Latitude + '', ListOfPOIs[i].Longitude + '', ListOfPOIs[i].EntityId, ListOfPOIs[i].IconUrl,
                ListOfPOIs[i].ShadowUrl, "True");
        }
        ListOfPOIs = new Array();
    }

    for (var i = 0; i < this.getLocationsArray().length; i++) {
        this.getLocationsArray()[i].setGoogleMarker(null);
    }
}

ZooverGoogleMap.prototype.CreateGooglePoint = function (locationNode)
{
	var lLatitude = locationNode.getAttribute("lat");
	var lLongitude = locationNode.getAttribute("long");
	if (lLatitude != null  && lLatitude.length > 0 && 
		lLongitude != null && lLongitude.length > 0)
	{
        return new GLatLng(parseFloat(lLatitude), parseFloat(lLongitude));
	}
	
    return null;
}

ZooverGoogleMap.prototype.CreateGooglePoint1 = function (latitude, longitude)
{
	if (latitude.length > 0 && longitude.length > 0)
	{
        return new GLatLng(parseFloat(latitude), parseFloat(longitude));
	}
    return null;
}

ZooverGoogleMap.prototype.DisplayMarkers = function() {
	///We remove all the markers we had before 
	this.getMap().clearOverlays();
	if (this.getShowAllMarkers()) {
		for (var i = 0; i < this.getLocationsArray().length; i++) {
			this.DisplayOneMarker(this.getLocationsArray()[i]);
		}
	}
	else {
		for (var i = 0; i < this.getLocationsArray().length && i < this.getNumberOfMarkersShown(); i++) {
			this.DisplayOneMarker(this.getLocationsArray()[i]);
		}
	}
	if (this.getHighlightCenter() == 'true') {
		this.HighlightLocation(this.getLocationsArray()[0].getEntityId());
		scrollToTabs('scr');
	}
}

ZooverGoogleMap.prototype.DisplayOneMarker = function (zooverGoogleLocation)
{
	var lMarker, lHighlightMarker;
	
	try
	{
		if (zooverGoogleLocation != null) {
		    if ((zooverGoogleLocation.IsPOI() == "True" && ShowPOIs) || (zooverGoogleLocation.IsPOI()!="True"))
		    {
			lMarker = zooverGoogleLocation.getGoogleMarker();
			if (lMarker == null) 
			{
				lMarker = this.CreateMarker (zooverGoogleLocation);				
				lHighlightMarker = this.CreateHighlightMarker(zooverGoogleLocation);
				
				this.getMap().addOverlay(lMarker);
			}
			}
		}
	}
	catch (e)
	{
		// We do nothing, but we want the other markers to be shown so we don't throw the exception further
	}
	return lMarker;
}

ZooverGoogleMap.prototype.CreateMarker = function(zooverGoogleLocation) {
	var lMarker;
	var lIcon = this.CreateIcon(zooverGoogleLocation);
	var lTooltipUrl = this.getEntityTooltipUrl();
	// (NEW INFO WINDOW CODE) var lWindow = this.getZooverInfoWindow();
	var lOverviewMapControl = this.getOverviewMapControl();

	if (lIcon == null)
		lMarker = new GMarker(zooverGoogleLocation.getGooglePoint());
	else
		lMarker = new GMarker(zooverGoogleLocation.getGooglePoint(), lIcon);

	zooverGoogleLocation.setGoogleMarker(lMarker);

	lTooltipUrl = zooverGoogleLocation.getTooltipHtml(this.getEntityTooltipUrl(), this.getTooltipPOIUrl());

	if (lTooltipUrl != '') {
		GEvent.addListener(lMarker, "click", function() {
			// (NEW INFO WINDOW CODE) lWindow.OpenOnMarker(lMarker, lTooltipUrl, lOverviewMapControl);
			lMarker.openInfoWindowHtml(lTooltipUrl)
		});

		if (AirportMap == true) {
			GEvent.addListener(lMarker, "mouseover", function() {
				lMarker.openInfoWindowHtml(lTooltipUrl)
			});
		}
	}
	return lMarker;
}

ZooverGoogleMap.prototype.CreateHighlightMarker = function (zooverGoogleLocation)
{    
	var lMarker;
    var lIcon = this.CreateHighlightIcon (zooverGoogleLocation);

    if(lIcon == null)
        lMarker = new GMarker (zooverGoogleLocation.getGooglePoint());
    else
        lMarker = new GMarker (zooverGoogleLocation.getGooglePoint(), lIcon);
    
    zooverGoogleLocation.setHighlightMarker (lMarker);
    
    return lMarker;
}

ZooverGoogleMap.prototype.CreateIcon = function (zooverGoogleLocation)
{
	var lIconUrl = zooverGoogleLocation.getIconUrl();
	if (lIconUrl != '')
	{					
		// Create our "tiny" marker icon
		var lIcon = new GIcon();
		lIcon.image = lIconUrl;
		lIcon.shadow = zooverGoogleLocation.getShadowUrl();
		lIcon.iconSize = new GSize(25, 25);
		lIcon.shadowSize = new GSize(25, 25);
		lIcon.iconAnchor = new GPoint(10, 0);
		lIcon.infoWindowAnchor = new GPoint(12, 12);
        
		return lIcon;
	}
	else
	{
		return null;
	}
}

ZooverGoogleMap.prototype.CreateHighlightIcon = function (zooverGoogleLocation)
{
	var lHighlightIconUrl = zooverGoogleLocation.getIconUrl();
	if (lHighlightIconUrl != '')
	{					
		var lIcon = new GIcon();
		lIcon.image = lHighlightIconUrl;
		lIcon.shadow = zooverGoogleLocation.getShadowUrl();
		lIcon.iconSize = new GSize(28, 28);
		lIcon.shadowSize = new GSize(39, 34);
		lIcon.iconAnchor = new GPoint(0, 28);
		lIcon.infoWindowAnchor = new GPoint(-22, 130);
        
		return lIcon;
	}
	else
	{
		return null;
	}
}


ZooverGoogleMap.prototype.HighlightMarker = function (index, highlight)
{
	var lZooverGoogleLocation;
	var lGoogleMarker, lHighlightMarker;
	
	if (this.getMap() != null && index < this.getLocationsArray().length)
	{
		lZooverGoogleLocation = this.getLocationsArray()[index];
		if (lZooverGoogleLocation != null)
		{
			lGoogleMarker = lZooverGoogleLocation.getGoogleMarker();
			lHighlightMarker = lZooverGoogleLocation.getHighlightMarker();
			if (lGoogleMarker != null && lHighlightMarker != null)
			{
				if (highlight)
				{					
					this.getMap().addOverlay (lHighlightMarker);
				}
				else
				{					
					this.getMap().removeOverlay (lHighlightMarker);
				}
			}
		}
	}	
}

ZooverGoogleMap.prototype.HighlightLocation = function (entityId)
{
	var lZooverGoogleLocation;
	var lTooltipUrl;
	var lGoogleMarker;
	var lMapAnchorPosition;
	var lGoogleMapAnchorElement;
	var lScrollY;
	if (this.getMap() !=null)
	{
		for (var i=0; i < this.getLocationsArray().length; i++)
		{
			if (this.getLocationsArray()[i].getEntityId() == entityId)
			{
				lZooverGoogleLocation = this.getLocationsArray()[i];
				if (lZooverGoogleLocation != null)
				{
					lGoogleMarker = this.DisplayOneMarker(lZooverGoogleLocation);
					if (lGoogleMarker != null)
					{
						lTooltipUrl = lZooverGoogleLocation.getTooltipHtml(this.getEntityTooltipUrl(), this.getTooltipPOIUrl());
						if (lTooltipUrl != null)
						{
							lGoogleMarker.openInfoWindowHtml (lTooltipUrl);
							// (NEW INFO WINDOW CODE) this.getZooverInfoWindow().OpenOnMarker(lGoogleMarker, lTooltipUrl, this.getOverviewMapControl());
						}
					}
				}
				
				// Scroll to the map anchor.
				if(document.getElementById) 
				{
					lGoogleMapAnchorElement = document.getElementById ('GoogleMapAnchor');
					
					// Check if the anchor element is found.
					if (lGoogleMapAnchorElement != null) 
					{
						lMapAnchorPosition = getElementYPosition (lGoogleMapAnchorElement);
						
						if (window.scrollY)
							lScrollY = window.scrollY;
						else if (document.documentElement.scrollTop)
							lScrollY = document.documentElement.scrollTop;
						else
							lScrollY = document.body.scrollTop;

						SlowScroll (lScrollY, lMapAnchorPosition);
					}
				}
			}
		}
	}
}

function SlowScroll (currentY, finalOrizontalPosition)
{
	var lStep = 20;
	var lNextIterationTime = 5;
	var lNewY;

	if ((currentY - finalOrizontalPosition) < lStep)
	{
		window.scrollTo(0, finalOrizontalPosition);
	}
	else
	{
		lNewY = currentY - lStep;
		window.scrollTo(0, lNewY);
		window.setTimeout(function () {SlowScroll (lNewY, finalOrizontalPosition);}, lNextIterationTime);
	}	
}

var googleMapsArray = new Array();

function GoogleMapEndecaServiceComplete(sender, result)
{
	var lCurrentPlaceHolder;
	var lCurrentItem;
	var lCurrentGoogleMap;
	
	// Iterate over the result items and run the 'AddMarkersFromXml' method of the right google map
	for (i=0; i < result.Items.length; i++)
	{
		// Each item contains an EndecaQueryServiceResponseItem object
		lCurrentItem = result.Items[i];
		
		if (lCurrentItem.ResponseType == ReponseType.GOOGLE_MAP)
		{
			try
			{
				lCurrentGoogleMap = googleMapsArray[lCurrentItem.PlaceHolderId];
				if (lCurrentGoogleMap != null)
				{
					lCurrentGoogleMap.AddMarkersFromXml (lCurrentItem.InnerHtml);
				}
			}
			catch (e) {}			
		}
	}	
}

/* Get the y position for an element */
function getElementYPosition(el)
{
	var yPos = 0;
	
	if (el.offsetParent)
	{
		while (el.offsetParent)
		{
			yPos += el.offsetTop
			el = el.offsetParent;
		}
	}
	else if (el.y)
		yPos += el.y;

	return yPos;
}

/* EWindow code */
function ZooverInfoWindow(zooverGoogleMap)
{
	// fields
	var _Map = zooverGoogleMap;
	var _ContainerDiv;
	var _Point;
	var _OffsetPoint;
	
	// properties
	this.getMap = function () { return _Map; }
	
	this.getContainerDiv = function() { return _ContainerDiv; }
	this.setContainerDiv = function(containerDiv) { _ContainerDiv = containerDiv; }
	
	this.getPoint = function () { return _Point; }
	this.setPoint = function (point) { _Point = point; }
	
	this.getOffsetPoint = function () { return _OffsetPoint; }
	this.setOffsetPoint = function (point) { _OffsetPoint = point; }
	
	this.visible = false;
}

// Declare our ZooverInfoWindow as a GOverlay control
ZooverInfoWindow.prototype = new GOverlay();

// GOverlay interface members //
// ZooverInfoWindow initialization
ZooverInfoWindow.prototype.initialize = function(map)
{
	var containerDiv = document.createElement('div');
	
	containerDiv.style.position = 'absolute';
	containerDiv.className = 'panel infowindow';
	
	// attaching zoover window to the map
	map.getPane(G_MAP_FLOAT_PANE).appendChild(containerDiv);
	this.setContainerDiv(containerDiv);
	this.Hide();
}

// ZooverInfoWindow redraw
ZooverInfoWindow.prototype.redraw = function(force)
{
	if (!this.visible) { return; }
	var lMarkerPoint = this.getMap().fromLatLngToDivPixel(this.getPoint());
	
	var lPx = lMarkerPoint.x + this.getOffsetPoint().x;
	var lPy = lMarkerPoint.y + this.getOffsetPoint().y;
	
	this.getContainerDiv().style.left = lPx + "px";
	this.getContainerDiv().style.top = lPy + "px";
}

// ZooverInfoWindow remove
ZooverInfoWindow.prototype.remove = function()
{
	this.getContainerDiv().parentNode.removeChild(this.getContainerDiv());
	this.visible = false;
}
// //--End GOverlay interface members //

ZooverInfoWindow.prototype.Show = function()
{
	this.visible = true;
	this.getContainerDiv().style.display = '';
}

ZooverInfoWindow.prototype.Hide = function()
{
	this.visible = false;
	this.getContainerDiv().style.display = 'none';
}

ZooverInfoWindow.prototype.OpenOnMarker = function(marker, html, overviewMapControl)
{
	// varables
	var lMarkerPoint;
	var lPanByX = 0;
	var lPanByY = 0;
	var lx = marker.getIcon().iconAnchor.x - marker.getIcon().infoWindowAnchor.x;
	var ly = marker.getIcon().iconAnchor.y - marker.getIcon().infoWindowAnchor.y;
	var lOffsetPoint = new GPoint(lx, ly);
	
	this.setOffsetPoint(lOffsetPoint);
	this.setPoint(marker.getPoint());
	
	this.getContainerDiv().innerHTML = html;
	this.getContainerDiv().style.zIndex = GOverlay.getZIndex(marker.getPoint().lat()) + 1;
	
	// obtain marker coordinates in current container (in pixels)
	lMarkerPoint = this.getMap().fromLatLngToContainerPixel(marker.getPoint());
	
	// obtain info window coordinates in current container (top-left corner of the map as reference)
	var lPx = lMarkerPoint.x + lx;
	var lPy = lMarkerPoint.y + ly;
				
	this.Show();		
	
	// check if the info windows gets outside the map container	
	// NOTE: this.getContainerDiv() has clientWidth or clientHeight only if it is visible
	if (this.getMap().getSize().width - lPx < this.getContainerDiv().clientWidth)
		lPanByX = (this.getMap().getSize().width - lPx) - this.getContainerDiv().clientWidth - 10;

	if (lPy < 25) // 25 = top distance between info window and top of the map + GMapType control height
		lPanByY = -lPy + 25;
	
	if ((lPanByX != 0) || (lPanByY != 0))
		this.getMap().panBy(new GSize(lPanByX, lPanByY));
	
	// if the info window overlaps with the GOverviewMapControl control (150 = GOverviewMapControl height & width)
	if ((this.getMap().getSize().height - lPy - this.getContainerDiv().clientHeight < 150) && (this.getMap().getSize().width - lPx - this.getContainerDiv().clientWidth < 150))
		overviewMapControl.hide();	
	
	this.redraw(true);
}
