/*
 * 
 * requires :
 * showCBD (boolean)
 * siteBaseURI
 * city
 * dsdRef
 * F
 * site
 * restoreView (boolean)
 * locationGeocoding_defaultCBD
 * locationGeocoding_cbdZoom
 * wfeDataSource
 * ratingPopUpUrl
 * FFPopUpUrl
 * FFDisclaimerPopUpUrl
 */

function cursor_wait()
{
	/* console.log("cursor_wait::"); */
	document.getElementById("body").style.cursor = "wait";
}

function cursor_clear()
{
	/* console.log("cursor_clear::"); */
	document.getElementById("body").style.cursor = "auto";
}

/* cause brain-dead IE can't do array.indexOf */
function findInArray(a, obj)
{
	for(var i=0; i<a.length; i++)
	{
		if(a[i]==obj)
		{
			return i;
		}
	}
	return -1;
}

var hotelList = new Array();
var userSortedHotelList = new Array();
var lMarkerList = new Array();
var ew;

function hotel(hotelIndex, hotelID, hotelName, latitude, longitude, queryIndex, imageName, imageAlt, selectRoomURL, locality, stars, isSelfRated, hotelInfo, hasRestaurants, hasChildCare, hasParking, hasPool, hasWifi, isFF, ffOffering, hasAvailable)
{
	this.index = hotelIndex;
	this.hotelID = hotelID;
	this.hotelName = hotelName;
	this.latitude = latitude;
	this.longitude = longitude;
	this.iconX = 0;
	this.iconY = 0;
	this.queryIndex = queryIndex;
	this.imageName = imageName;
	this.imageAlt = imageAlt;
	this.selectRoomURL = selectRoomURL;
	this.locality = locality;
	this.stars = String(stars);
	this.isSelfRated = isSelfRated;
	this.hotelInfo = hotelInfo;
	this.hasRestaurants = hasRestaurants;
	this.hasWifi = hasWifi;
	this.hasChildCare = hasChildCare;
	this.hasParking = hasParking;
	this.hasPool = hasPool;
	this.isFF = isFF;
	this.ffOffering = ffOffering;
	this.hasAvailable = hasAvailable;
	this.lMarkerIndex='';
	/* console.log("hotel::created a hotel " + this.hotelName + " with query index " + this.queryIndex + ", longitude:" + longitude); */
}

function sortHotelByQueryIndex(a, b) {
    var x = parseInt(a.queryIndex);
    var y = parseInt(b.queryIndex);
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

function LMarker(iconIdx, title, latitude, longitude)
{
	var iconNum = parseInt(iconIdx) + 1;
	/* mainIcon is the variable used normally to create the icons.  Various functions will set mainIcon to 'standard', 'cluster' etc */
	this.mainIcon= siteBaseURI + "/images/googleMaps/standard.png";
	this.mainPrintIcon= siteBaseURI + "/images/googleMaps/standard.gif";
	this.mainFFPrintIcon= siteBaseURI + "/images/googleMaps/standardFF.gif";
	
	this.standardIcon= siteBaseURI + "/images/googleMaps/standard.png";
	this.standardPrintIcon= siteBaseURI + "/images/googleMaps/standard.gif";
	this.standardFFPrintIcon= siteBaseURI + "/images/googleMaps/standardFF.gif";

	this.hoverIcon= siteBaseURI + "/images/googleMaps/selected.png";

	this.shortlistIcon= siteBaseURI + "/images/googleMaps/shortlist.png";
	this.shortlistPrintIcon= siteBaseURI + "/images/googleMaps/shortlist.gif";
	this.shortlistFFPrintIcon= siteBaseURI + "/images/googleMaps/shortlistFF.gif";

	this.clusterIcon= siteBaseURI + "/images/googleMaps/cluster.png";
	this.clusterHoverIcon= siteBaseURI + "/images/googleMaps/clusterSelected.png";
	this.clusterPrintIcon= siteBaseURI + "/images/googleMaps/cluster.gif";
	this.clusterFFPrintIcon= siteBaseURI + "/images/googleMaps/clusterFF.gif";

	this.infoWindowOpen=false;
	this.marker="";
	this.isCluster=false;
	this.title = title.replace(/&amp;/,'&');
	this.latitude = latitude;
	this.longitude = longitude;
	this.iconNum = iconNum;
}

function addHotelMarkers()
{
	/* console.log("addHotelMarkers::"); */
	cursor_wait();
	/* console.time("addHotelMarkers"); */ 
	removeAllHotelMarkers();
	/*
		OK, so here's the stategy.
		If there's only one hotel, just plot it and get out. Otherwise...
		The 'hotelList' is sorted by longitude.  We need to find the pixel position of each icon.
		But we only need to Google convert two icons ... from there we can work out the rest ourselves, as we can assume that at the 
		zooms we're using the distance between latitudes (and longitudes) remains constant. 
		Now the icons are 20x x 34y.  So 		 
	*/
	if ( hotelList.length < 2)
	{
		for (i in hotelList)
		{
			/* console.log("addHotelMarkers::less than 2 hotels, insert marker and exit"); */
			var lMarker = new LMarker(hotelList[i].queryIndex, hotelList[i].hotelName, hotelList[i].latitude, hotelList[i].longitude);
			lMarkerList[i] = lMarker;
			hotelList[i].lMarkerIndex = i;
			makeMarker(lMarker, lMarker.mainIcon, lMarker.mainPrintIcon, lMarker.mainFFPrintIcon); 
		}
		GEvent.addListener(map,"click", clickMarker);
		GEvent.addListener(map,"infowindowclose", closeMarker);
		cursor_clear();	
		return;
	}
	/* Let Google convert a few icons.  We want the best resolution, so find the markers that are furthest apart in each direction.  X is easy ... its already sorted: */
	var hotel = hotelList[0];
	var gPoint = map.fromLatLngToContainerPixel(new GLatLng(hotel.latitude, hotel.longitude));
	hotel.iconX = gPoint.x;
	hotel.iconY = gPoint.y;
	/* console.log("addHotelMarkers::hotel0 long, lat = " + hotel.longitude + "," + hotel.latitude + "; x=" + hotel.iconX); */ 
	hotel = hotelList[hotelList.length - 1];
	gPoint = map.fromLatLngToContainerPixel(new GLatLng(hotel.latitude, hotel.longitude));
	hotel.iconX = gPoint.x;
	hotel.iconY = gPoint.y;
	/* console.log("addHotelMarkers::hotelLast long, lat = " + hotel.longitude + "," + hotel.latitude + "; x=" + hotel.iconX); */
	var longsPerPixel = (hotel.longitude - hotelList[0].longitude) / (hotel.iconX - hotelList[0].iconX);
	if ( hotel.iconX == hotelList[0].iconX )
	{
		longsPerPixel = 1;
	}
	/* For Y, we must find min and max latitude */
	var minLatitude = 180;
	var maxLatitude = -180;
	for (i in hotelList)
	{
		if ( hotelList[i].latitude < minLatitude ) {
			minLatitude = hotelList[i].latitude;
		}
		if ( hotelList[i].latitude > maxLatitude ) {
			maxLatitude = hotelList[i].latitude;
		}
	}
	var gPointMin = map.fromLatLngToContainerPixel(new GLatLng(minLatitude, hotel.longitude));
	var gPointMax = map.fromLatLngToContainerPixel(new GLatLng(maxLatitude, hotel.longitude));
	/* console.log("addHotelMarkers::debug pointMin=" + gPointMin.toString() + ", pointMax=" + gPointMax.toString()); */
	/* console.log("addHotelMarkers::max, min latitudes = " + maxLatitude + "," + minLatitude + " max,min Y = " + gPointMax.y + "," + gPointMin.y); */
	var latsPerPixel = (maxLatitude - minLatitude) / (gPointMax.y - gPointMin.y);
	if ( gPointMax.y == gPointMin.y )
	{
		latsPerPixel = 1;
	}
	/* manually do the rest */
	/* console.log("addHotelMarkers::latsPerPixel = " + latsPerPixel); */ 
	/* console.log("addHotelMarkers::longsPerPixel = " + longsPerPixel); */ 
	var hotel0 = hotelList[0];
	for (i = 1; i < hotelList.length - 1; i++)
	{
		hotel = hotelList[i];
		hotel.iconY = (hotel.latitude - hotel0.latitude) / latsPerPixel + hotel0.iconY;
		hotel.iconX = (hotel.longitude - hotel0.longitude) / longsPerPixel + hotel0.iconX;
		/* console.log("addHotelMarkers::hotel[" + i + "] long, lat = " + hotel.longitude + "," + hotel.latitude + "; x,y=" + hotel.iconX + "," + hotel.iconY); */ 
	}
	/*  scan through each hotel and if there's any other hotel within icon width & height*/
	/* console.time("addHotelMarkers::scan"); */ 
	for (i in hotelList)
	{
		hotel = hotelList[i];
		/* some hotels have already been assigned to earlier clusters, bypass them */
		if ( hotel.lMarkerIndex === '' )
		{
			var lMarker = new LMarker(hotel.queryIndex, hotel.hotelName, hotel.latitude, hotel.longitude);
			if ( findInArray(getShortList(), hotel.hotelID) > -1 )
			{
				lMarker.mainIcon = lMarker.shortlistIcon;
				lMarker.mainPrintIcon = lMarker.shortlistPrintIcon;
				lMarker.mainFFPrintIcon = lMarker.shortlistFFPrintIcon;
			}
			var mIndex = lMarkerList.length;
			/* console.log("addHotelMarkers::creating marker " + mIndex + " for hotel[" + i + "] " + hotel.hotelName); */
			lMarkerList[mIndex] = lMarker;
			hotel.lMarkerIndex = mIndex;
			/* go see if this hotel has anything touching it to the right - 20 pixels (icon width) or top/bottom 34 pixels*/
			var testX = hotel.iconX + 20;
			var testY1 = hotel.iconY - 34;
			var testY2 = hotel.iconY + 34;
			/* console.log("addHotelMarkers::hotel is at " + hotel.iconX + "," + hotel.iconY); */
			/* console.log("addHotelMarkers::test co-ords:x=" + testX + ", y=" + testY1 + " to " + testY2); */
			var numberOfHotelsInMarker = 1;
			for (scanAhead = parseInt(i) + 1; scanAhead < hotelList.length; scanAhead++)
			{
				var hotelTest = hotelList[scanAhead];
				/* console.log("addHotelMarkers::now testing against hotel[" + scanAhead + "] " + hotelTest.hotelName + " at x,y=" + hotelTest.iconX + "," + hotelTest.iconY ); */
				if ( hotelTest.iconX > testX )
				{
					/* console.log("addHotelMarkers::is beyond longitude bounds, skip to next hotel"); */
					break;	/* no more, as hotels are sorted in left-to-right order */
				}
				/* console.log("addHotelMarkers::is within longitude bounds, check unassigned && latitude"); */
				if ( hotelTest.iconY > testY1 && hotelTest.iconY < testY2 && hotelTest.lMarkerIndex == '' )
				{
					/* console.log("addHotelMarkers::is within latitude bounds, assigning as cluster"); */
					/* OK, we have a toucher */
					lMarker.isCluster = true;
					numberOfHotelsInMarker++;
					lMarker.mainIcon = lMarker.clusterIcon;
					lMarker.hoverIcon = lMarker.clusterHoverIcon;
					lMarker.mainPrintIcon = lMarker.clusterPrintIcon;
					lMarker.mainFFPrintIcon = lMarker.clusterFFPrintIcon;
					lMarker.title = "This cluster contains " + numberOfHotelsInMarker + " hotels";
					hotelTest.lMarkerIndex = mIndex;					
				}
			}
		}
		else
		{
			/* console.log("addHotelMarkers::bypassing hotel " + i + ", already is in a cluster"); */
		}
	}
	/* console.timeEnd("addHotelMarkers::scan"); */ 
	/* console.log("addHotelMarkers::created " + lMarkerList.length + " markers"); */
	/* console.time("addHotelMarkers::makeMarker list"); */ 
	for (i in lMarkerList)
	{
		makeMarker(lMarkerList[i], lMarkerList[i].mainIcon, lMarkerList[i].mainPrintIcon, lMarkerList[i].mainFFPrintIcon);
	}
	/* console.timeEnd("addHotelMarkers::makeMarker list"); */ 

	GEvent.addListener(map,"click", clickMarker);
	GEvent.addListener(map,"infowindowclose", closeMarker);
	/* console.timeEnd("addHotelMarkers"); */ 
	cursor_clear();	
}


function removeAllHotelMarkers()
{
	/* console.log("removeAllHotelMarkers::removing " + lMarkerList.length + " markers"); */
	/* console.time("removeAllHotelMarkers"); */ 
	while ( lMarkerList.length > 0)
	{
		var lMarker = lMarkerList.pop();
		map.removeOverlay(lMarker.marker);
	}
	lMarkerList = new Array();
	for (i in hotelList)
	{
		hotelList[i].lMarkerIndex = '';
	}
	/* console.timeEnd("removeAllHotelMarkers"); */ 
}

/* makes a string that we use when setting up cookies to restore the map state.  As we only want to restore map state if we're effectively on the same map */
function makePageRestoreCookieMatcher()
{
	var str = city + dsdRef + F;
	str = str.replace(/;/g,"-");
	str = str.replace(/:/g,"-");
	return str;
}

function event_pan()
{
	/* console.log("event_pan::"); */
	checkTakeMeTo("");
	setPositionCookie();
}

function event_zoom()
{
	/* console.log("event_zoom::"); */
	checkTakeMeTo("");
	addHotelMarkers();
	setPositionCookie();
}

function setPositionCookie(label)
{
	/* console.log("setPositionCookie::"); */
	if ( label != null )
	{
		var cookieString = makePageRestoreCookieMatcher() + "_" + label;
		/* console.log("setPositionCookie::cookieString=" + cookieString); */
		createCookie(site + '_MAP_POS', cookieString);
	}
	else
	{
		var currentZoom = map.getZoom();
		var currentPos = map.getCenter();
		var cookieString = makePageRestoreCookieMatcher() + "_POS_" + new String(currentZoom) + "_" + new String(currentPos.lat()) + "_" + new String(currentPos.lng());
		/* console.log("setPositionCookie::cookieString=" + cookieString); */
		createCookie(site + '_MAP_POS', cookieString);
	}
}

function testPositionCookie()
{
	/* console.log("testPositionCookie::"); */
	var positionCookie = readCookie(site + '_MAP_POS');
	/* console.log("testPositionCookie::positionCookie = " + positionCookie); */
	createCookie(site + '_MAP_POS', '', -1);	/* erase it, we will create it again shortly if need be */
	if ( restoreView )
	{
		if ( positionCookie != null )
		{
			var parts = positionCookie.split('_');
			if ( parts.length > 1 )
			{
				var checkKey = parts[0];
				/* console.log("testPositionCookie::checkKey = " + checkKey + " vs " + makePageRestoreCookieMatcher()); */
				if ( checkKey == makePageRestoreCookieMatcher())
				{
					var type = parts[1];
					if ( type == 'POS' )
					{
						pageRecentering = positionCookie;
					}
					else
					{
						/* console.log("testPositionCookie::calling = " + type); */
						pageRecentering = type;
					}
				} 
			}
		}	
	}
}

/* this will only be called if pageRecentering contains _POS_ */
function repositionOnCookie()
{
	/* console.log("repositionOnCookie::pageRecentering = " + pageRecentering); */
	var parts = pageRecentering.split('_');
	if ( parts.length == 5 )
	{
		var type = parts[1];
		var zoom = parseInt(parts[2]);
		var latitude = parseFloat(parts[3]);
		var longitude = parseFloat(parts[4]);
		/* console.log("repositionOnCookie::panning to " + new GLatLng(latitude, longitude) + " with zoom=" + zoom); */
		map.setCenter(new GLatLng(latitude, longitude), zoom);
		popupInfoWindowOnPageReload();
	}
}

function highlightMarker(hotelIndex)
{
	/* console.log("highlightMarker::hotelIndex=" + hotelIndex); */
	// find the marker, and change the icon to hover -- but NOT if an info window is still open!
	for (i in lMarkerList)
	{
		var lMarker = lMarkerList[i];
		if ( lMarker.infoWindowOpen )
		{
			return;	/*  Don't reset marker if the info window is still open*/
		}
	}

	var h = hotelList[hotelIndex];
	var lMarker = lMarkerList[h.lMarkerIndex];
	var marker = lMarker.marker;
	if ( marker != "" ) {
		/* console.log("highlightMarker::highlighting marker=" + marker); */
		marker.setImage(lMarker.hoverIcon);
	}
}

function unHighlightMarker(hotelIndex)
{
	/* console.log("unHighlightMarker::hotelIndex=" + hotelIndex); */
	// find the marker, and change the icon to standard -- but NOT if an info window is still open!
	for (i in lMarkerList)
	{
		var lMarker = lMarkerList[i];
		if ( lMarker.infoWindowOpen )
		{
			return;	/*  Don't reset marker if the info window is still open*/
		}
	}
	
	var h = hotelList[hotelIndex];
	var lMarker = lMarkerList[h.lMarkerIndex];
	var marker = lMarker.marker;
	if ( marker != "" ) {
		/* console.log("highlightMarker::unHighlighting marker=" + marker); */
		marker.setImage(lMarker.mainIcon);
	}
}

function clickMarker(overlay,point)
{
	/* console.log("clickMarker::"); */
	// find the marker
	var lMarker = 0;
	for (i1 in lMarkerList)
	{
		var lMarker = lMarkerList[i1];
		if ( lMarker.marker === overlay )
		{
			if ( !lMarker.infoWindowOpen )
			{
				/* console.log("clickMarker::matched marker " + i1); */
				popupInfoWindow(i1, -1); /* -1 = show all items in cluster */
				// if the marker is for a hotel, we also scroll to that hotel
				if ( !lMarker.isCluster )
				{
					for (j in hotelList)
					{
						if ( hotelList[j].lMarkerIndex == i1 )
						{
							/* console.log("clickMarker::scrolling to hotel[" + j + "] " + hotelList[j].hotelName); */
							scrollHotelList(j);
							break;
						}
					}
				}
			}
			break;
		}
	}
}

function scrollHotelList(hotelIndex)
{
	/* console.log("scrollHotelList::hotelIndex=" + hotelIndex); */
	/* console.log("scrollHotelList::navigating to HOTEL" + hotelList[hotelIndex].queryIndex + " = " + hotelList[hotelIndex].hotelName); */
    var locationInfoDiv = document.getElementById("locationInfo");
    var theAnchor = document.getElementById("HOTEL" + hotelList[hotelIndex].queryIndex);
    locationInfoDiv.scrollTop = theAnchor.offsetTop - locationInfoDiv.offsetTop;
	/* console.log("scrollHotelList::navigating to scrollTop = " + (theAnchor.offsetTop - locationInfoDiv.offsetTop)); */
	highlightHotelList(hotelIndex);
}

var lastHighlightHotelList = null;
function highlightHotelList(hotelIndex)
{
	/* console.log("highlightHotelList::hotelIndex=" + hotelIndex); */
	unhighlightHotelList();
    lastHighlightHotelList = document.getElementById("HOTELNAME" + hotelList[hotelIndex].queryIndex);
    lastHighlightHotelList.style.color = "#FF7F22";
}

function unhighlightHotelList()
{
	/* console.log("unhighlightHotelList::"); */
	if ( lastHighlightHotelList != null )
	{
		/* console.log("unhighlightHotelList::resetting " + lastHighlightHotelList); */
	    lastHighlightHotelList.style.color = "";
	}
}

function closeMarker()
{
	/* console.log("closeMarker::"); */
	for (i in lMarkerList)
	{
		var lMarker = lMarkerList[i];
		if ( lMarker.infoWindowOpen )
		{
			lMarker.infoWindowOpen = false;
			map.setCenter(new GLatLng(lMarker.latitude, lMarker.longitude));
		}
	}
	resetMarkers();
	/* console.log("closeMarker::deleting popup cookie"); */
	createCookie(site + '_MAP_HOTELPOPUP', '', -1);
}

function resetMarkers()
{
	/* console.log("resetMarkers::"); */
	ew.hide();
	for (i in lMarkerList)
	{
		var lMarker = lMarkerList[i];
		lMarker.infoWindowOpen = false;
		if ( lMarker.marker != "" )
		{
			if ( lMarker.marker.getIcon().image != lMarker.mainIcon )
			{
				/* console.log("resetMarkers::resetting marker " + i + " from " + lMarker.marker.getIcon().image); */
				makeMarker(lMarker, lMarker.mainIcon, lMarkerList.mainPrintIcon, lMarkerList.mainFFPrintIcon);
			}
		} 
	}
	unhighlightHotelList();
}

function toggleShortListMarker(hotelIndex)
{
	/* console.log("toggleShortlistMarker::hotelIndex = " + hotelIndex); */
	/* don't worry about actually changing the marker - we can only shortlist a hotel when we're in the infoopup, in which case the marker is already highlighted.
		Just prepare the marekr for when it is reset back to normal. 
	*/
	var lMarker = lMarkerList[hotelList[hotelIndex].lMarkerIndex];
	/* console.log("toggleShortlistMarker::lMarkerIndex = " + hotelList[hotelIndex].lMarkerIndex); */
	if ( !lMarker.isCluster )
	{
		if ( lMarker.mainIcon == lMarker.shortlistIcon ) /* so we're turning the shortlist OFF */
		{
			lMarker.mainIcon = lMarker.standardIcon; 
		}
		else  /* so we're turning the shortlist ON */
		{
			lMarker.mainIcon = lMarker.shortlistIcon; 
		}
		/* console.log("toggleShortlistMarker::set marker icon to " + lMarker.mainIcon); */
	}
}

function makeMarker(lMarker, iconImage, printImage, ffPrintImage)
{
	/* console.log("makeMarker::for " + lMarker.title + " at " + lMarker.latitude + "," + lMarker.longitude); */
	var marker = lMarker.marker;
	lMarker.marker = "";
	if ( marker != "" ) {
		map.removeOverlay(marker);
	}
	var myPoint = new GLatLng(lMarker.latitude, lMarker.longitude);
	var myIcon = new GIcon(G_DEFAULT_ICON);
	myIcon.image = iconImage;
	myIcon.printImage = printImage;
	myIcon.mozPrintImage = ffPrintImage;
	myIcon.printShadow = "";
	if ( lMarker.isCluster )
	{
		myIcon.iconSize = new GSize(20,40);
		myIcon.iconAnchor = new GPoint(10,40);
		myIcon.infoWindowAnchor = new GPoint(10,0);
		marker = new GMarker(myPoint, {title:lMarker.title, icon: myIcon});
	}
	else
	{
		myIcon.iconSize = new GSize(20,34);
		myIcon.iconAnchor = new GPoint(10,34);
		myIcon.infoWindowAnchor = new GPoint(10,0);
		if ( lMarker.iconNum > 99 )
		{
			marker = new LabeledMarker(myPoint,{"title":lMarker.title,"icon": myIcon,"labelText": new String(lMarker.iconNum),"labelOffset": new GSize(-8,-30), "labelClass": "LabeledMarker_markerLabel_small"});
		}
		else
		{
			marker = new LabeledMarker(myPoint,{"title":lMarker.title,"icon": myIcon,"labelText": (lMarker.iconNum > 9 ? new String(lMarker.iconNum): "<font size=\"1\">&nbsp;</font>" + new String(lMarker.iconNum)),"labelOffset": new GSize(-7,-31)});
		}
	}
	map.addOverlay(marker);
	lMarker.marker = marker;
	return marker;
}

function popupInfoWindow(lMarkerIndex, selectedHotelIndex)
{
	/* hotelIndex = -1 means that this could be a cluster, in which case we show ALL hotels in that cluster. */
	/* console.log("popupInfoWindow::lMarkerIndex=" + lMarkerIndex + ", selectedHotelIndex=" + selectedHotelIndex); */
	resetMarkers();
	var popupList = new Array();
	for (i in hotelList)
	{
		/* console.log("popupInfoWindow::debug:hotel[" + i + "] queryIndex " + hotelList[i].queryIndex + " is in marker " + hotelList[i].lMarkerIndex); */
		if ( hotelList[i].lMarkerIndex == lMarkerIndex )
		{
			/* console.log("popupInfoWindow::found hotelIndex=" + i); */
			if ( selectedHotelIndex == -1 || selectedHotelIndex == i )
			{
				popupList[popupList.length] = hotelList[i];
			}
			if ( selectedHotelIndex == i )
			{
				break;	/* stop if we only want to show one hotel*/
			}
		}
	}
	/* console.log("popupInfoWindow::popupList.length=" + popupList.length); */
	if ( popupList.length > 1 )
	{
		/* console.log("popupInfoWindow::sorting hotel results"); */
		popupList.sort(sortHotelByQueryIndex);
	}
	/* make the marker highlighted  */
	var marker = makeMarker(lMarkerList[lMarkerIndex], lMarkerList[lMarkerIndex].hoverIcon, lMarkerList[lMarkerIndex].mainPrintIcon, lMarkerList[lMarkerIndex].mainFFPrintIcon); 
	/* open the winfo window  */
	if ( popupList.length > 1 )
	{
		marker.openInfoWindowHtml(makePopupHTML(popupList));
	}
	else
	{ 
		ew.openOnMarker(marker,makePopupHTML(popupList));
		/* when we move to a marker well off the map, some sort of sync error occurs, where the popup doesnt get shown.  Wait .5 sec, then redraw it. */
		window.setTimeout("ew.redraw(true)", 500);
	}
	
	lMarkerList[lMarkerIndex].infoWindowOpen = true;
	
	/* pan the map so that the info window is vaguely centered */
	var gPoint = map.fromLatLngToDivPixel(marker.getLatLng());
	var gLatLng = map.fromDivPixelToLatLng(new GPoint(gPoint.x,gPoint.y-MARKER_DISPLACEMENT));
	map.panTo(gLatLng);
	
	if ( selectedHotelIndex > -1 )
	{
		highlightHotelList(selectedHotelIndex);
	}

	var cookieString = makePageRestoreCookieMatcher() + "_" + new String(lMarkerIndex + "_" + selectedHotelIndex);
	/* console.log("popupInfoWindow::creating popup cookie:" + cookieString); */
	createCookie(site + '_MAP_HOTELPOPUP', cookieString);
}

function makePopupHTML(popupList)
{
	/* console.log("makePopupHTML::popupList.length=" + popupList.length); */
	var html = ""; 
	if ( popupList.length == 1 )
	{
		var hotel = popupList[0];
		html = makeHotelPopupHTML(hotel.index, true); 
		return html;
	}
	else
	{
		// have moved to std google popup for cluster : html = "<div class=\"popup_clusterborder\"><img src=\ siteBaseURI + "/images/googleMaps/clusterpopup_top.png\" border=\"0\"/></div>";
		html = "<div class=\"popup_clusterbody\">";
		html += "<div class=\"popup_clusterheader\"><span class=\"popup_clusterheadertext\">This cluster contains " + popupList.length + " hotels:</span>";
		// have moved to std google popup for cluster : html += "<span class=\"popup_closeButton\"><a href=\"javascript:closeMarker()\"><img src=\ siteBaseURI + "/images/googleMaps/map_popup_close.gif\" alt=\"close\" width=\"12\" height=\"12\" border=\"0\"/></a></span>\n";
		html += "</div> ";
		html += "<div class=\"popup_clusterscrollarea\">";
		for (i in popupList)
		{
			if ( i > 0 )
			{ 
				html += "<div class=\"popup_clusterbreak\"></div>";
			} 
			html += makeHotelPopupHTML(popupList[i].index, false);
		}
		html += "</div></div>";  
		// have moved to std google popup for cluster : html += "<div class=\"popup_clusterborder\"><img src=\ siteBaseURI + "/images/googleMaps/clusterpopup_bottom.png\" border=\"0\"/></div>";
	}
	/* console.log("makePopupHTML::html=" + html); */
	return html;
}

function makeHotelPopupHTML(hotelIndex, singleHotel)
{
	/* console.log("makeHotelPopupHTML::hotelIndex=" + hotelIndex + ", singleHotel=" + singleHotel); */
	var hotel = hotelList[hotelIndex];
	
	var isIE = (navigator.userAgent.indexOf("MSIE") > 0 && navigator.userAgent.indexOf("MSIE 8") == 0);

	var html = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n <tr>\n";
	if ( singleHotel )
	{
		/* Find this hotel in userSortedHotelList, get the previous hotelID, and then find *that* in the hotelList  */
		for (i in userSortedHotelList)
		{
			if (hotel.hotelID == userSortedHotelList[i])
			{
				if ( i == 0 )
				{	/* no more hotels to the left */
					if(isIE)
					{
						html += "<td><div title=\"Previous hotel\" style=\"cursor:pointer;height:247px; width:21px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"" + siteBaseURI + "/images/googleMaps/map_popup_left.png', sizingMethod='scale');\" ></div>";
					}
					else
					{
						html += "<td><img src=\"" + siteBaseURI + "/images/googleMaps/map_popup_left.png\" width=\"21\" height=\"247\" border=\"0\" style=\"cursor:pointer;\" title=\"Previous hotel\"/>";
					}
				}
				else
				{
					var prevHotelID = userSortedHotelList[parseInt(i) - 1];
					/* console.log("makePopupHTML::prevHotelID = " + prevHotelID); */
					for ( j in hotelList )
					{
						if ( hotelList[j].hotelID == prevHotelID )
						{
							if(isIE)
							{
								html += "<td><div title=\"Previous hotel\" onClick=\"javascript: popupInfoWindow(hotelList[" + String(j) + "].lMarkerIndex, " + String(j) + "); scrollHotelList(" + String(j) + ");\" style=\"cursor:pointer;height:247px; width:21px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"" + siteBaseURI + "/images/googleMaps/map_popup_left.png', sizingMethod='scale');\" ></div>";
							}
							else
							{
								html += "<td><img src=\"" + siteBaseURI + "/images/googleMaps/map_popup_left.png\" width=\"21\" height=\"247\" border=\"0\" style=\"cursor:pointer;\" onClick=\"javascript: popupInfoWindow(hotelList[" + String(j) + "].lMarkerIndex, " + String(j) + "); scrollHotelList(" + String(j) + ");\" title=\"Previous hotel\"/>";
							}
							break;
						}  
					}
				}
				break;
			}
		}
		html +="</td>\n";
	}
	if ( singleHotel )
	{
		html += " <td class=\"popup_mapTable\"><div class=\"popup_body\">";
		html += "<span class=\"popup_closeButton\"><a href=\"javascript:closeMarker()\"><img src=\"" + siteBaseURI + "/images/googleMaps/map_popup_close.gif\" alt=\"close\" width=\"12\" height=\"12\" border=\"0\"/></a></span>\n";
	}
	else
	{
		html += " <td class=\"popup_mapTable popup_mapClusterTable\"><div class=\"popup_body\">";
	}
	html += " <p class=\"popup_hotelName\">"; 
	if ( hotel.hasAvailable )
	{
		html += "<b>" + (parseInt(hotel.queryIndex) + 1) + ". <a href=\"" + hotel.selectRoomURL + "\" >"+ hotel.hotelName +"</a> ";
	}
	else
	{
		html += (parseInt(hotel.queryIndex) + 1) + ". " + hotel.hotelName;
	}
	
	html = html + "</b>&nbsp;" + hotel.locality;
	html = html + "&nbsp;&nbsp;<a href=\"#\" onClick=\"window.open('" + ratingPopUpUrl + "','rating','location=no,toolbar=no,menubar=no,resizable=no,scrollbars=yes,width=750,height=600,top=30,left=30');return false;\">";
	html = html + "<img src=\"" + siteBaseURI + "/images/" + site + "/ratingTails/selectHotel/" + ((hotel.stars.length == 1) ? hotel.stars + ".0" : hotel.stars);
	if ( hotel.isSelfRated ) {
		html = html + "_selfrated";
	}
	html = html + ".gif\" alt=\"Rating " + hotel.stars + "\" title=\"Rating " + hotel.stars + "\" align=\"bottom\" border=\"0\" /></a>";
	console.log("html=" + html);
	
	html +=" </p>\n";

	html += " <div class=\"popup_hotelDetails\">\n";

	html += "<div class=\"popup_hotelPic\"><img src=\""+ hotel.imageName +"\" alt=\"" + hotel.imageAlt + "\" title=\"" + hotel.imageAlt + "\" /></div>\n";

	html += " <div class=\"popup_hotelInfo\" >" + hotel.hotelInfo;
	if ( hotel.hasAvailable ) {
		html += "<br/><a href=\"" + hotel.selectRoomURL + "\"> More information and room types</a>\n";
	}
	html += "</div>";

	var hotelPriceDiv = document.getElementById("HOTEL" + hotel.queryIndex + "_CHEAPESTDAYRATE");
	var hotelPriceDivStandard = document.getElementById("HOTEL" + hotel.queryIndex + "_CHEAPESTDAYRATESTANDARD");
	var hotelPriceDivStandard_nocurr = document.getElementById("HOTEL" + hotel.queryIndex + "_CHEAPESTDAYRATESTANDARD_NOCURR");
	var hotelPriceDivStandard_currOnly = document.getElementById("HOTEL" + hotel.queryIndex + "_CHEAPESTDAYRATESTANDARD_CURRONLY");
	if ( wfeDataSource ) {
		if ( hotelPriceDivStandard != null ) {
			html += " <div class=\"popup_hotelInfo\">\n <p class=\"popup_totalPrice\">From " + hotelPriceDivStandard_currOnly.innerHTML + " <span style=\"text-decoration: line-through\">" + hotelPriceDivStandard_nocurr.innerHTML + "</span> " + hotelPriceDiv.innerHTML + " per night</p>\n </div>\n </div>\n";
		} else {
			html += " <div class=\"popup_hotelInfo\">\n <p class=\"popup_totalPrice\">From " + hotelPriceDiv.innerHTML + " per night</p>\n </div>\n </div>\n";
		}
	} else {
		html += " <div class=\"popup_hotelInfo\">\n <p class=\"popup_totalPrice\">Total price from  " + hotelPriceDiv.innerHTML + "</p>\n </div>\n </div>\n";
	}

	var addedToShortlist = (findInArray(getShortList(), hotel.hotelID) > -1);
	html += " <div class=\"popup_selectInfo\"><span class=\"popup_shortListSelect\">";
	html += "<input type=\"checkbox\" name=\"addToShortlist_" + hotel.hotelID + "\"";
	if ( addedToShortlist )
	{
		html = html + "checked ";
	}
	html = html + "onclick=\"toggleShortList(this); toggleShortListMarker(" + hotelIndex + ")\"/>";
	if ( addedToShortlist )
	{
		html = html + " <label id=\"lbl_addToShortList_" + hotel.hotelID + "\" for=\"addToShortlist_" + hotel.hotelID + "\">Added to shortlist</label></span>";
	}
	else
	{
		html = html + " <label id=\"lbl_addToShortList_" + hotel.hotelID + "\" for=\"addToShortlist_" + hotel.hotelID + "\">Add to shortlist</label></span>";
	}
    if ( hotel.isFF ) 
    {
    	html += "</div><div class=\"popup_selectInfo\">";
		html += "<span class=\"popup_ffImage\"><a href=\"#\" onclick=\"window.open('" + FFPopUpUrl + "','frequentflyer','location=no,toolbar=no,menubar=no,resizable=no,scrollbars=yes,width=990,height=780,top=40,left=40');return false;\">";
		html += "<img alt=\"Qantas Frequent Flyer logo\" title=\"Qantas Frequent Flyer logo\" src=\"" + siteBaseURI + "/red-img/" + site + "/img_ffLogo.gif\" border=\"0\" /></a><br/><a href=\"#\" onclick=\"window.open('" + FFDisclaimerPopUpUrl + "','frequentflyer','location=no,toolbar=no,menubar=no,resizable=no,scrollbars=yes,width=990,height=780,top=40,left=40');return false;\">Conditions apply.</a></span>";
		html += "<span class=\"popup_ffText\">" + hotel.ffOffering + ".</span>";
    }

	if ( hotel.hasAvailable ) 
	{
		html += "<span class=\"popup_selectButton\"><a href=\"" + hotel.selectRoomURL + "\" class=\"button\" title=\"Select Hotel\">Select Hotel</a></span>";
	}
	else
	{
		html += "<span class=\"popup_selectButton\"></span>";
	}
	html += "</div></div></td>\n";
	
	if ( singleHotel ) 
	{
		/* Find this hotel in userSortedHotelList, get the next hotelID, and then find *that* in the hotelList  */
		for (i in userSortedHotelList)
		{
			if (hotel.hotelID == userSortedHotelList[i])
			{
				if ( i == (userSortedHotelList.length - 1) )
				{
					if(isIE)
					{
						html += "<td><div title=\"Next Hotel\" style=\"cursor:pointer;height:247px; width:22px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + siteBaseURI + "/images/googleMaps/map_popup_right.png', sizingMethod='scale');\" ></div>";
					}
					else
					{
						html += "<td><img src=\"" + siteBaseURI + "/images/googleMaps/map_popup_right.png\" width=\"22\" height=\"247\" border=\"0\" style=\"cursor:pointer;\" title=\"Next Hotel\"/>";
					}
				}
				else
				{
					var nextHotelID = userSortedHotelList[parseInt(i) + 1];
					/* console.log("makePopupHTML::nextHotelID = " + nextHotelID); */
					for ( j in hotelList )
					{
						if ( hotelList[j].hotelID == nextHotelID )
						{
							if(isIE)
							{
								html += "<td><div title=\"Next Hotel\" onClick=\"popupInfoWindow(hotelList[" + String(j) + "].lMarkerIndex, " + String(j) + "); scrollHotelList(" + String(j) + ")\" style=\"cursor:pointer;height:247px; width:22px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + siteBaseURI + "/images/googleMaps/map_popup_right.png', sizingMethod='scale');\" ></div>";
							}
							else
							{
								html += "<td><img src=\"" + siteBaseURI + "/images/googleMaps/map_popup_right.png\" width=\"22\" height=\"247\" border=\"0\" onClick=\"popupInfoWindow(hotelList[" + String(j) + "].lMarkerIndex, " + String(j) + "); scrollHotelList(" + String(j) + ")\" style=\"cursor:pointer;\" title=\"Next Hotel\"/>";
							}
							break;
						}  
					}
				}
				break;
			}
		}
		html +="</td>\n";
	}
	html += " </tr>\n</table>\n";

	/* console.log("makeHotelPopupHTML::html=" + html); */
	return html;
}

var cbdLatLong = "";
function takeMeToCBD()
{
	/* console.log("takeMeToCBD::"); */
	/* console.time("takeMeToCBD"); */
	
	cursor_wait();
	clearAddressSearchResults();
	if ( cbdLatLong != "" )
	{
		map.setCenter(cbdLatLong, parseInt(locationGeocoding_cbdZoom));
		checkTakeMeTo("takeMeToCBD");
		setPositionCookie("takeMeToCBD");
	}
	else
	{
		takeMeToDefault();
	}
	if ( pageLoading )
	{
		popupInfoWindowOnPageReload();
	}
	else
	{
		closeMarker();
	}
	pageLoading = false;
	cursor_clear();
	/* console.timeEnd("takeMeToCBD"); */
	/* console.log("takeMeToCBD::exit"); */
}
function setTakeMeToCBD(gLatLng)
{
	/* console.log("setTakeMeToCBD::gLatLng=" + gLatLng + ", pageRecentering = " + pageRecentering); */
	cbdLatLong = gLatLng;
	if ( pageRecentering == 'takeMeToCBD' )
	{
		/* console.log("setTakeMeToCBD::pageRecentering is set, centering to CBD"); */
		takeMeToCBD();
	}
	else if ( pageRecentering == null && locationGeocoding_defaultCBD )
	{
		/* console.log("setTakeMeToCBD::default behaviour, centering to CBD"); */
		takeMeToCBD();
	}
	/* console.log("setTakeMeToCBD::exit"); */
}

function takeMeToDefault()
{
	/* console.log("takeMeToDefault::"); */
	/* calculate the best center and zoom based on all the hotels */
	cursor_wait();
	clearAddressSearchResults();
	var minLongitude = hotelList[0].longitude;
	var maxLongitude = hotelList[hotelList.length - 1].longitude;
	/* For Y, we must find min and max latitude */
	var minLatitude = 180;
	var maxLatitude = -180;
	for (i in hotelList)
	{
		if ( hotelList[i].latitude < minLatitude ) {
			minLatitude = hotelList[i].latitude;
		}
		if ( hotelList[i].latitude > maxLatitude ) {
			maxLatitude = hotelList[i].latitude;
		}
	}
	
	var bnds = new GLatLngBounds(new GLatLng(maxLatitude, minLongitude), new GLatLng(minLatitude, maxLongitude));
	var zoom = map.getBoundsZoomLevel(bnds); 
	/* console.log("takeMeToDefault::google centerPoint=" + bnds.getCenter().lat() + "," + bnds.getCenter().lng() + ", zoom=" + zoom); */
	map.setCenter(bnds.getCenter(), zoom);
	if ( pageLoading )
	{
		popupInfoWindowOnPageReload();
	}
	else
	{
		closeMarker();
	}
	pageLoading = false;
	checkTakeMeTo("takeMeToDefault");
	setPositionCookie("takeMeToDefault");
	cursor_clear();
	/* console.log("takeMeToDefault::exit"); */
}

function clearAddressSearchResults()
{
	/* console.log("clearAddressSearchResults::"); */
	document.getElementById("addresssearchresult").innerHTML = "";
}

function popupInfoWindowOnPageReload()
{
	/* console.log("popupInfoWindowOnPageReload::"); */
	var hotelPopupInf = readCookie(site + '_MAP_HOTELPOPUP');
	/* console.log("popupInfoWindowOnPageReload::hotelPopupInf = " + hotelPopupInf); */
	createCookie(site + '_MAP_HOTELPOPUP', '', -1);	/* erase it, we will create it again shortly if need be */
	if ( restoreView ) {
		if ( hotelPopupInf != null )
		{
			var hpParts = hotelPopupInf.split('_');
			if ( hpParts.length == 3 )
			{
				var checkKey = hpParts[0];
				/* console.log("popupInfoWindowOnPageReload::checkKey = " + checkKey + " vs " + makePageRestoreCookieMatcher()); */
				if ( checkKey == makePageRestoreCookieMatcher())
				{
					var lMarkerIndex = hpParts[1];
					var selectedHotelIndex = hpParts[2];
					/* console.log("popupInfoWindowOnPageReload::calling popupInfoWindow"); */
					popupInfoWindow(lMarkerIndex, selectedHotelIndex);
				} 
			}
		}
	}
}


