
// build a HotelMapSearch object
function HotelsMapSearch(divMapId) {
	var mapOptions = {mapTypes:[G_NORMAL_MAP, G_HYBRID_MAP]};
	this.map = new GMap2(document.getElementById(divMapId), mapOptions);
	this.arrayHotelMarkers = [];
	this.hotelMarkerToKeep = null;
	this.geoCoder = new GClientGeocoder();
	this.markerSet = new HashSet();
	this.loadHotelsList = true;
}


// initialize the map and download hotels markers
HotelsMapSearch.prototype.initMap = function() {
	this.map.setCenter(new GLatLng(46.628475943661385, 0.06837538454580816), 3);
	G_HYBRID_MAP.getMinimumResolution = function() { return 2; }; 
	G_NORMAL_MAP.getMinimumResolution = function() { return 2; }; 
	this.map.setMapType(G_HYBRID_MAP);
  	this.map.enableDoubleClickZoom();
	this.map.enableContinuousZoom();
	this.map.enableScrollWheelZoom();
	this.map.addControl(new GScaleControl());
	this.hotelsControl = new HotelsControl();
	//this.map.addControl(this.hotelsControl);
	GEvent.bind(this.map, 'moveend', this, this.onMapMoveEnd);
	
	// This is a feature to automatically load a location
	// http://localhost:8080/walbrowser/?search=Nice
	// this will centralise automatically on Nice on loading of the application
	var theUrl = window.location.href;
	//alert("The Url: " +theUrl);
	var theSearchLocation = gup2(theUrl, "search");
	//alert("The searchLocation : " + theSearchLocation);
	if(theSearchLocation != "")
	{
		document.getElementById("searchInput").value = theSearchLocation;
		this.search();
	}
	this.downloadHotels();
}

// on map move end event...
HotelsMapSearch.prototype.onMapMoveEnd = function() {
	if(walDebug)
		GLog.write(">>> onMapMoveEnd");
		//alert("Map moving");
	if (this.loadHotelsList == true) {
		this.downloadHotels();
		this.selectAndFocusSearch();
	}
	this.loadHotelsList = true;
	
	if(walDebug)
		GLog.write("<<< onMapMoveEnd");
}

// ask for hotels in the current viewport to the server and download results
HotelsMapSearch.prototype.downloadHotels = function() {
	//alert("downloadingHotels..");
	if(walDebug)
		GLog.write(">>> downloadHotels");
	var bounds = this.map.getBounds();
	var relevantViewport = this.map.fromContainerPixelToLatLng(new GPoint(220, 65));
						// gastronomy waterfront internet parking 'sport activities' 'pets allowed'
	var amenities = new Array('1',        '2',     '99',    '6',          '9',           '4');
	var services = "";
	for (var i in amenities) {
		if (service[i] == 1) {
			services = services + "&amenities=" + amenities[i];
		}
	}
	
	var url = "Search"; 
	if (this.map.getZoom() < 3) {
		url += "?minlongitude=" + -180.0 + "&maxlongitude=" + 180.0;
	} else {
		url += "?minlongitude=" + relevantViewport.lng() + "&maxlongitude=" + bounds.getNorthEast().lng();
	}
	
	url +=	"&minlatitude=" + bounds.getSouthWest().lat() + "&maxlatitude=" + relevantViewport.lat() +
			"&checkInDate=" + document.getElementById('checkInDate').value +
			"&checkOutDate=" + document.getElementById('checkOutDate').value + 
			services +
			"&correlationId=" + correlationId;

	if(document.getElementById('searchChain') && document.getElementById('searchChain').value != ""){
	// make sure it is uppercase
		url += "&chainCode=" + document.getElementById('searchChain').value.toUpperCase();
	}

	expectedCorrelationId = correlationId;
	correlationId++;
	
	if (minPrice >= 0 && maxPrice > minPrice) {
		url += "&minPrice=" + minPrice +
			  "&maxPrice=" + maxPrice;
	}
	
	if(walDebug)
		GLog.write("URL: " + url);
		
	//alert("URL: " +url);
	
	GDownloadUrl(url, processDownloadResponse);
	
	if(walDebug)
		GLog.write("<<< downloadHotels");
}

HotelsMapSearch.prototype.procesAvailabilityResponse = function(data, status) {
	if (status != -1) {
		if (data) {
			var xml = GXml.parse(data);
			var error = xml.firstChild.tagName;
			if (error != 'error') {
			}
		}
	}
}

HotelsMapSearch.prototype.returnNotEmpty = function(node) {
	if (node != null && node.firstChild != null) {
		return node.firstChild.nodeValue;
	}
	return '';
}

HotelsMapSearch.prototype.readAndSetStatistics = function(xml) {
	var root = xml.documentElement.getElementsByTagName("TPA_Extensions");
	var stats = root[0]
	if (root.length > 1) {
		stats = root[root.length - 1];
	}
	
	var unit = '';
	var duration = '';
	if (stats != null) {
		unit = stats.getAttribute("ProcessTimeUnit");
		duration = stats.getAttribute("ProcessTime");
	}
	var count = 0; // stats.getAttribute("Count");
	var selectionCount =  0; //stats.getAttribute("SelectionCount");
	
	if (parseInt(count) > 0) {
		document.getElementById("count1").innerHTML = selectionCount + " out of " + count;
		if (parseInt(duration) > 0) {
			if (parseInt(duration) > 10) {
				document.getElementById("count2").innerHTML = "computed in 10" + unit;
			} else {
				document.getElementById("count2").innerHTML = "computed in " + duration + unit;
			}
		} else {
			document.getElementById("count2").innerHTML = "in less than 1" + unit;
		}
	} else {
		document.getElementById("count1").innerHTML = "";
		//document.getElementById("count2").innerHTML = "Information not available";
	}
}

// load hotels markers, display them in the map and pictures
HotelsMapSearch.prototype.loadHotels = function(xml) {
	if(walDebug)
		GLog.write(">>> loadHotels");
	if (xml.documentElement.getElementsByTagName('CorrelationId').length == 1) {
		var corId = this.returnNotEmpty(xml.documentElement.getElementsByTagName('CorrelationId')[0]);
		if (corId != expectedCorrelationId) {
			return;
		}
	}

	this.readAndSetStatistics(xml);
	var xmlHotels = xml.documentElement.getElementsByTagName('RoomStays');
	
	if (xmlHotels.length <= 0){
		this.resetMap();
	}
	else /*(xmlHotels.length != 0)*/ {
		// reset map and internal hotel markers list
		this.resetMap();
		
		// parse xml...
		xmlHotels = xmlHotels[0].getElementsByTagName("RoomStay");
		//alert("Number of hotels returned: " +xmlHotels.length);
			for (i=0;i<xmlHotels.length;i++)
			{ 
				var roomRateNodeList = xmlHotels[i].getElementsByTagName("RoomRates")[0].getElementsByTagName("RoomRate");
				var totalValue = 0;
				var currency = "$";
				var theLowestDailyPrice = 0;
				for(l=0;l<roomRateNodeList.length;l++)
				{
					var ratesNode = roomRateNodeList[l].getElementsByTagName("Rates")[0];
					var theRateNodeList = ratesNode.getElementsByTagName("Rate");
					for(k=0;k<theRateNodeList.length;k++)
					{					
												
						var theBaseNodeList = theRateNodeList[k].getElementsByTagName("Base");
						if(theBaseNodeList){
							for(m=0;m<theBaseNodeList.length;m++){
								var theBasePrice = theBaseNodeList[m].getAttribute("AmountBeforeTax");
								//alert("Base price: " + theBasePrice);
								if( (theBasePrice < theLowestDailyPrice && theBasePrice > 0) 
									|| (theBasePrice > 0 && theLowestDailyPrice == 0) ) {
									
										theLowestDailyPrice = theBasePrice;
									}
							}
						
						}
					}
					var TotalNodeList = roomRateNodeList[l].getElementsByTagName("Total");
					totalValue = TotalNodeList[0].getAttribute("AmountBeforeTax");
					currency = TotalNodeList[0].getAttribute("CurrencyCode");
				}
				//var startingPrice = totalValue;
				var startingPrice = theLowestDailyPrice;
				var basicPropertyInfoNode  = xmlHotels[i].getElementsByTagName("BasicPropertyInfo")[0];
				var chainCode =  basicPropertyInfoNode.getAttribute("ChainCode");
				var hotelCode =  basicPropertyInfoNode.getAttribute("HotelCode");
				var theCityCode =  basicPropertyInfoNode.getAttribute("HotelCityCode");
				var hotelName =  basicPropertyInfoNode.getAttribute("HotelName");
				
				var addressNode = basicPropertyInfoNode.getElementsByTagName("Address")[0];
				var address = addressNode.getElementsByTagName("AddressLine")[0].childNodes[0].nodeValue;
				var zip = "";
				try {
				zip = addressNode.getElementsByTagName("PostalCode")[0].childNodes[0].nodeValue;
				}
				catch (ex)
				{
				zip = "";
				}
				var countryCode = addressNode.getElementsByTagName("CountryName")[0].getAttribute("Code");
				
				var positionNode = basicPropertyInfoNode.getElementsByTagName("Position")[0];
				var hotelLng = positionNode.getAttribute("Longitude");
				var hotelLat = positionNode.getAttribute("Latitude");
				
				var latlng = new GLatLng(parseFloat(hotelLat), parseFloat(hotelLng));
				
				// get Hotel Description
				var theHotelDescriptionTxt = "";				
				try {
					theHotelDescriptionTxt = basicPropertyInfoNode.getElementsByTagName("VendorMessages")[0].getElementsByTagName("Text")[0].childNodes[0].nodeValue;
					//alert("DESCRIPTION : " + theHotelDescriptionTxt);
				}
				catch (ex)	{
					theHotelDescriptionTxt = "";
				}
				
				// get Img Url
				var theImgUrl = "images/metal/small_wallaby.gif";
				//var theImgUrl = "http://post-development.multimedia.testing.amadeus.com/hotel/retrieveHotelDescriptionItem?cos=2&req=nam@wallaby&htl=chn@RT,prp@RTNCEARE&ent=RTNCEARE_EXT_01_A.JPG";
				//var theImgUrlNodeArray = basicPropertyInfoNode.getElementsByTagName("VendorMessages")[0].getElementsByTagName("VendorMessage")[0];
				if (basicPropertyInfoNode.getElementsByTagName("VendorMessages")[0] ){
					var theVendorMessageNode = basicPropertyInfoNode.getElementsByTagName("VendorMessages")[0].getElementsByTagName("VendorMessage")[0];
					if(theVendorMessageNode != null) {	
						if(theVendorMessageNode.getElementsByTagName("URL")[0]){			
							theImgUrl = theVendorMessageNode.getElementsByTagName("URL")[0].childNodes[0].nodeValue;
						}
					}
				}
				// end Img URL
				
				
				var hotelMarker = new HotelMarker(chainCode, hotelCode, theCityCode, hotelName, theHotelDescriptionTxt,  
												  address, zip, 5.0, startingPrice, /*imgUrl*/ theImgUrl, "", 
												  true, latlng, this);
				// same as the marker selected if one?
				if (this.hotelMarkerToKeep == null ||
					hotelCode != this.hotelMarkerToKeep.hotelCode) {
					
					this.arrayHotelMarkers.push(hotelMarker);
					hotelMarker.display(this.map);
					
					var key = this.map.fromLatLngToDivPixel(latlng).toString();
					if (this.markerSet.exists(key) == true) {
						hotelMarker.duplicates = this.markerSet.getItem(key);
						this.markerSet.getItem(key).push(hotelMarker);
					} else {
						this.markerSet.add(key, [hotelMarker]);
					}
				}
				
			}
		
		this.arrayHotelMarkers.reverse();
		for (var i = 0; i < this.arrayHotelMarkers.length; i++) {
			this.hotelsControl.displayHotelInfo(this.arrayHotelMarkers[i]);
		}
		
		if (this.hotelMarkerToKeep != null) {
			//this.hotelsControl.displayHotelInfo(this.hotelMarkerToKeep);
	    	this.hotelMarkerToKeep = null;
		}
	
	}
	if(walDebug)
		GLog.write("<<< loadHotels");
	
}

HotelsMapSearch.prototype.getAttributeValueFromTag = function(xml, tagName, attributeName) {
	if (xml == null 
		|| xml.getElementsByTagName(tagName) == null 
		|| xml.getElementsByTagName(tagName)[0] == null
		|| xml.getElementsByTagName(tagName)[0].getAttribute(attributeName) == null) {
		
		return null;
	}
	return xml.getElementsByTagName(tagName)[0].getAttribute(attributeName);
}

// reset the map and internal markers structure, except the hotel marker selected (info window)
HotelsMapSearch.prototype.resetMap = function() {
	if(walDebug)
		GLog.write(">>> Reset map");

	this.hotelsControl.reset();
	this.markerSet = new HashSet();
	
	for (var i = 0; i < this.arrayHotelMarkers.length; i++) {
		// do not remove from the map selected marker if one
		if (this.arrayHotelMarkers[i].isClickedOn == false || this.arrayHotelMarkers[i].marker.deployed == true) {
			this.arrayHotelMarkers[i].unDisplay(this.map);
		} else {
			this.hotelMarkerToKeep = this.arrayHotelMarkers[i];
		}
	}
	
	// reset the internal array this.hotelMarkerToKeep: if a marker is selected
	// then this.hotelMarkerToKeep contains only the selected marker, otherwise
	// make this.hotelMarkerToKeep empty
	if (this.hotelMarkerToKeep) {
		this.arrayHotelMarkers = [this.hotelMarkerToKeep];
	} else {
		this.arrayHotelMarkers = [];
	}
	
	if(walDebug)
		GLog.write("<<< Reset map");
}

HotelsMapSearch.prototype.selectAndFocusSearch = function() {
	var input = document.getElementById("searchInput");
	if (input != null && input.visibility != "hidden" && !input.disabled && input.style.display != "none") {
		try {
			input.focus();
			input.select();
		} catch(err) {
		}
	}
}

HotelsMapSearch.prototype.search = function() {
	var input = document.getElementById("searchInput").value;
	
	// dirty-hack to trim the string
	if (input != null && input.replace( /^\s+/g, "" ).replace( /\s+$/g, "" ).length == 0) {
		return;
	}

	var tmpMap = this.map;
	this.geoCoder.getLocations(
		  input,
		  function(response) {
			  if (!response || response.Status.code != 200) {
			  	alert("Sorry, we were unable to find that address");
			  } else {
			  	place = response.Placemark[0];
			    point = new GLatLng(place.Point.coordinates[1],
		                            place.Point.coordinates[0]);
				tmpMap.setCenter(point);
				var zoom = 2;
				switch(place.AddressDetails.Accuracy) {
					case 1:
						zoom = 6;
						break;
					case 2:
						zoom = 8;
						break;
					case 3:
						zoom = 10;
						break;
					case 4:
						zoom = 12;
						break;
					case 5:
						zoom = 14;
						break;
					case 6:
						zoom = 16;
						break;
					default:
						zoom = 17;
				}
				tmpMap.setZoom(zoom);
		      }
		  }
	);
}

HotelsMapSearch.prototype.moveUp = function() {
	this.map.panDirection(0, 1);
}

HotelsMapSearch.prototype.moveDown = function() {
	this.map.panDirection(0, -1);
}

HotelsMapSearch.prototype.moveLeft = function() {
	this.map.panDirection(1, 0);
}

HotelsMapSearch.prototype.moveRight = function() {
	this.map.panDirection(-1, 0);
}

HotelsMapSearch.prototype.zoomIn = function() {
	this.map.zoomIn();
}

HotelsMapSearch.prototype.zoomOut = function() {
	this.map.zoomOut();
}

HotelsMapSearch.prototype.changeMapType = function() {
	if (this.map.getCurrentMapType() == G_NORMAL_MAP) {
		document.getElementById('navImg').setAttribute("src", "images/metal/nav_map_on.png");
		this.map.setMapType(G_HYBRID_MAP);
	} else {
		document.getElementById('navImg').setAttribute("src", "images/metal/nav_map_off.png");
		this.map.setMapType(G_NORMAL_MAP);
	}
}

// check the status of the response, load xml response and call
// HotelsMapSearch.loadHotels to load hotel markers if everything is fine
function processDownloadResponse(data, status) {
	if(walDebug)
		GLog.write(">>> processDownloadResponse");
	if (status != -1) {
		if (data) {
			var xml = GXml.parse(data);
			
			var error = '';
			if (xml.firstChild == null || xml.firstChild.tagName == null) {
				error = 'error';
			} else {
				error = xml.firstChild.tagName.toLowerCase();
			}
			
			if (error != 'error' && error != 'errors') {
				document.title = "Wallaby Browser";
				hotelMap.loadHotels(xml);
			} else {
				document.title = "Wallaby Browser (could not load properties into the map)"
			}
		}
	}
	if(walDebug)
		GLog.write("<<< processDownloadResponse");
}
