

function rpwGmap(div){
	
	this.mapDiv = div;
	this.googleMap = null;
	this.xmlObj = null;
	this.mgr = null;
	this.zoom = null;
	this.listDiv = null;
	this.listArray = new Array();
	this.toolTip = null;
	this.messageOverlay = null;
	this.saveMapPosition = true;
	
	var loadTimer;
	
	this.attributes = new Object();
	
	this.setAttribute = function(a,v){
		this.attributes[a] = v;
	}
	
	this.setAttributes = function(){
		for(var i=0;i<arguments.length;i+=2){
			this.attributes[arguments[i]] = arguments[i+1];
		}
	}
	
	this.getAttribute = function(a){
		return this.attributes[a];
	}
	
	
	this.init = function(lat,lng,zoom){
		
		if (GBrowserIsCompatible()) {
			
			this.unLoadMap();

			zoom = (zoom == null) ? 14 : zoom;
			this.googleMap = new GMap2(document.getElementById(this.mapDiv));
			this.googleMap.setCenter(new GLatLng(lat, lng), zoom);
			
			if(this.getAttribute("zoomType") == "large"){
				this.googleMap.addControl(new GLargeMapControl3D());
			}else{
				this.googleMap.addControl(new GSmallMapControl());
			}
			
			if(this.getAttribute("showMapType")){
				this.googleMap.addControl(new GMenuMapTypeControl());
			}
			
			// add street view
			
			
			//this.googleMap.disableDragging();
			//setGMapZoomGraphic();
	
			// define icons
			this.loadingIcon = new GIcon();
			this.loadingIcon.image = pathToRoot+"images/gmap-loading-icon.gif";
			this.loadingIcon.iconSize = new GSize(36, 36);
			this.loadingIcon.iconAnchor = new GPoint(18, 18);
	
			this.highlightIcon = new GIcon();
			this.highlightIcon.image = pathToRoot+"images/gmap-highlight.png";
			this.highlightIcon.iconSize = new GSize(44, 44);
			this.highlightIcon.iconAnchor = new GPoint(23, 29);

			this.propertyIcon = new GIcon();
			this.propertyIcon.image = pathToRoot+"images/gmap-house.png";
			this.propertyIcon.shadow = pathToRoot+"images/gmap-house-shadow.png";
			this.propertyIcon.iconSize = new GSize(29, 25);
			this.propertyIcon.shadowSize = new GSize(29, 25);
			this.propertyIcon.iconAnchor = new GPoint(13, 20);
			this.propertyIcon.infoWindowAnchor = new GPoint(10, 17);

			this.propertiesIcon = new GIcon();
			this.propertiesIcon.image = pathToRoot+"images/gmap-2house.png";
			this.propertiesIcon.shadow = pathToRoot+"images/gmap-2house-shadow.png";
			this.propertiesIcon.iconSize = new GSize(36, 26);
			this.propertiesIcon.shadowSize = new GSize(36, 26);
			this.propertiesIcon.iconAnchor = new GPoint(14, 15);
			this.propertiesIcon.infoWindowAnchor = new GPoint(17, 10);

			this.officeIcon = new GIcon();
			this.officeIcon.image = pathToRoot+"images/gmap-office.png";
			this.officeIcon.shadow = pathToRoot+"images/gmap-house-shadow.png";
			this.officeIcon.iconSize = new GSize(29, 25);
			this.officeIcon.shadowSize = new GSize(29, 25);
			this.officeIcon.iconAnchor = new GPoint(13, 20);
			this.officeIcon.infoWindowAnchor = new GPoint(10, 17);
			
			var thisObj = this;
			
			GEvent.addListener(this.googleMap, "moveend", function(){ thisObj.savePosition(); });
			GEvent.addListener(this.googleMap, "zoomend", function(){ thisObj.onZoomEnd(); });
			
			//GEvent.addListener(this.googleMap, "movestart", this.saveGMapPosition);
			//var thisObj = this;
			//GEvent.addListener(this.googleMap, "zoomend", function(){ alert(thisObj.googleMap.getZoom()); });
			
			this.initialised = true;
			
		}
	}
	
	this.getMarkerManager = function(){
		
		if(this.markerManager == null){
			this.markerManager = new MarkerManager(this.googleMap);
		}
		
		return this.markerManager;
	}

	this.showPropertyList = function(div){
		
		this.listDiv = div;
		
	}
	
	this.onZoomEnd = function(){
		/*if(this.markerManager != null){
			this.markerManager.refresh();
		}*/
		this.savePosition();
	}
	
	this.savePosition = function(){
		
		if(this.googleMap != null){
		
			var center = this.googleMap.getCenter();
			
			params = "id="+this.getAttribute("id")+"&lat="+center.lat()+"&lng="+center.lng()+"&zoom="+this.googleMap.getZoom();
			
			if(this.saveMapPosition){
			
				ajaxServerProcess("savegmapposition",params);
				
			}
		
		}
	}
	
	this.setPosition = function(lat,lng,zoom){
		
		this.lat = lat;
		this.lng = lng;
		this.zoom = zoom;
		
	}
	
	this.loadProperties = function(url){
		
		// check for existing requests
		if(this.xmlObj!=null&&this.xmlObj.readyState!=0&&this.xmlObj.readyState!=4){
			this.xmlObj.abort();
		}
		try{
			// instantiate object for Mozilla, Nestcape, etc.
			this.xmlObj=new XMLHttpRequest();
		}
		catch(e){
			try{
				// instantiate object for Internet Explorer
				this.xmlObj=new ActiveXObject('Microsoft.XMLHTTP');
			}
			catch(e){
				// Ajax is not supported by the browser
				this.xmlObj=null;
				return false;
			}
		}
		
		// assign state handler
		var thisObj = this;
		this.xmlObj.onreadystatechange=function(){ thisObj.displayGMapProperties() };
		// open socket connection
		this.xmlObj.open('GET',url,true);
		// send GET request
		this.xmlObj.send(null);
		
		var thisObj = this;
		
		this.loadTimer = window.setTimeout(function(){ thisObj.operationTimedOut() },15000);
	
	}
	
	this.displayGMapProperties = function(){
		
		window.clearTimeout(this.loadTimer);
		
		if (this.xmlObj.readyState==4) {
			if (this.xmlObj.status==200) {
	
				this.showStatus("Displaying . . .",true);
	
				// show totals
				var pTotal;
				pTotal=Number(this.xmlObj.responseXML.getElementsByTagName('propertyTotal')[0].firstChild.nodeValue);
				
				if(pTotal == 0){
					this.displayMessage("Sorry, no properties matched your search");

					var div = document.getElementById(this.mapDiv);
					if(div != null){
						div.className = "googleMap noResults";
					}
					
					return;
				}
				
				if (this.xmlObj.responseXML.getElementsByTagName('zoomLevel') != null && this.xmlObj.responseXML.getElementsByTagName('zoomLevel')[0] != null) {
					this.zoom = Number(this.xmlObj.responseXML.getElementsByTagName('zoomLevel')[0].firstChild.nodeValue);
				}
				
				if(this.lat == null || this.lng == null && this.xmlObj.responseXML.getElementsByTagName('lat1') != null){
					// resize map if required
					var lat1 = Number(this.xmlObj.responseXML.getElementsByTagName('lat1')[0].firstChild.nodeValue);
					var lng1 = Number(this.xmlObj.responseXML.getElementsByTagName('lng1')[0].firstChild.nodeValue);
					var lat2 = Number(this.xmlObj.responseXML.getElementsByTagName('lat2')[0].firstChild.nodeValue);
					var lng2 = Number(this.xmlObj.responseXML.getElementsByTagName('lng2')[0].firstChild.nodeValue);
					
					if(lat1 == lat2 && lng1 == lng2){// one property
						this.zoom = 15;
					}
					
					this.lat = lat1+((lat2-lat1)/2);
					this.lng = lng1+((lng2-lng1)/2);
					
				}
				

				if(this.googleMap == null){
					this.init(this.lat,this.lng,this.zoom);
				}else{
					var center = new GLatLng(this.lat,this.lng);
					this.googleMap.setCenter(center);
				}
				
				
				if(this.zoom == null){

					var boundingBox = new GLatLngBounds(new GLatLng(lat1,lng1), new GLatLng(lat2,lng2));
					this.zoom = this.googleMap.getBoundsZoomLevel(boundingBox);
				
				}
				
				this.googleMap.setZoom(this.zoom);

	
	
				// create marker managers 
				var markerSets, data, batch, maxZoom;
				var properties;

				if(markerSets = this.xmlObj.responseXML.getElementsByTagName('markerSet')){
					
					this.mgr = this.getMarkerManager();
					
					for(var i=0;i<markerSets.length;i++){
						
						if(data = markerSets[i].getElementsByTagName('point')){
							
							batch = new Array();

							maxZoom = (markerSets[i].getAttribute("maxZoom")) ? markerSets[i].getAttribute("maxZoom") : null;

							for(var j=0;j<data.length;j++){
				
								batch.push(this.createPropertyMarker(data[j],maxZoom));
								
								if(this.listDiv != null && i == markerSets.length-1){// add property to list if there is one
									
									if(properties = data[j].getElementsByTagName('property')){
										
										for(var k=0;k<properties.length;k++){
											
											this.addPropertyToList(properties[k],data[j].getAttribute("latitude"),data[j].getAttribute("longitude"));
											
										}
										
									}
									
								}
								
							}
							
							
							this.mgr.addMarkers(batch, markerSets[i].getAttribute("minZoom"), maxZoom);
						
						}
		
		
					}
					
					this.mgr.refresh();


				}
				
				/*if(data = this.xmlObj.responseXML.getElementsByTagName('point')){

					for(var i=0;i<data.length;i++){
		
						this.pMarkerArr[i] = this.createPropertyMarker(data[i]);
						this.googleMap.addOverlay(this.pMarkerArr[i]);
		
					}
					
				}*/
				
				this.xmlObj = null;
				
				this.displayPropertyList();
	
	
				if(pTotal == 1){
					this.showStatus("1 property");
				}else if(pTotal>0){
					this.showStatus(pTotal+" properties");
				}else{
					this.showStatus("No properties");
				}
	
			}
		}
		// load results sheet
		//loadGList("search-results-frame.php?searchobj=gmapsearch&display=10");
	}
	
	this.createPropertyMarker = function(dataObj,zoomLimit){
		// assemble html for info window
		var infoHTML = "<div class='gMapInfoWindow clearfix'>";
		var detailsLink;
		var imgHTML;

		
		if(String(this.getAttribute("detailsPage")).substr(0,7) != "http://" && typeof(window["pathToRoot"]) != "undefined"){
			detailsLink = pathToRoot;
		}else{
			detailsLink = "";
		}
		
		detailsLink += this.getAttribute("detailsPage");
		// properties
		var properties;
		if(properties = dataObj.getElementsByTagName('property')){
			
			if(properties.length > 10 && zoomLimit != null){
				infoHTML += "<p><strong>"+properties.length+" properties</strong><br /><br />";
				infoHTML += "<a href='javascript:void(0);' class='zoom detail' onclick='resultsMap"+this.getAttribute("id")+".mapObj.zoomInTo("+dataObj.getAttribute('latitude')+","+dataObj.getAttribute('longitude')+","+((zoomLimit) ? Number(zoomLimit)+1 : "null")+");'>Zoom in</a>";
				infoHTML += "</p>";
			}else{
				for(var j=0;j<properties.length;j++){
	
					infoHTML += "<p>";
					if(properties.length <= 7 && properties[j].getElementsByTagName('image')[0]){
						imgHTML = "<image src='"+properties[j].getElementsByTagName('image')[0].getAttribute('src')+"' width='"+properties[j].getElementsByTagName('image')[0].getAttribute('width')+"' height='"+properties[j].getElementsByTagName('image')[0].getAttribute('height')+"' />";
						infoHTML += this.createDetailsLink(detailsLink,properties[j].getElementsByTagName('requestString')[0].firstChild.nodeValue,imgHTML,"thumbnail");
					}
					infoHTML += "<strong>"+properties[j].getElementsByTagName('price')[0].firstChild.nodeValue+"</strong>";
					infoHTML += " "+properties[j].getElementsByTagName('address')[0].firstChild.nodeValue+"<br />";
					if(properties[j].getElementsByTagName('rooms')[0]){
						infoHTML += properties[j].getElementsByTagName('rooms')[0].firstChild.nodeValue+"<br />";
					}
					if(this.getAttribute("showStatus") && properties[j].getElementsByTagName('status')[0]){
						infoHTML += "<span class='status'>"+properties[j].getElementsByTagName('status')[0].firstChild.nodeValue+"</span> ";
					}
					
					infoHTML += this.createDetailsLink(detailsLink,properties[j].getElementsByTagName('requestString')[0].firstChild.nodeValue)+"<br/>";
					infoHTML += "</p>";
	
				}
			}
		}

		// office
		var offices;
		if(offices = dataObj.getElementsByTagName('office')){
			for(var j=0;j<offices.length;j++){

				infoHTML += "<p>";
				if(offices[j].getElementsByTagName('image')[0]){
					infoHTML += "<image src='"+offices[j].getElementsByTagName('image')[0].getAttribute('src')+"' width='"+offices[j].getElementsByTagName('image')[0].getAttribute('width')+"' height='"+offices[j].getElementsByTagName('image')[0].getAttribute('height')+"' />";
				}
				infoHTML += "<strong>"+offices[j].getElementsByTagName('name')[0].firstChild.nodeValue+"</strong><br />";
				infoHTML += " "+offices[j].getElementsByTagName('address')[0].firstChild.nodeValue+"<br />";
				infoHTML += "Telephone: <strong>"+offices[j].getElementsByTagName('telephone')[0].firstChild.nodeValue+"</strong><br />";
				if(offices[j].getElementsByTagName('email') != null && typeof offices[j].getElementsByTagName('email')[0].firstChild != 'undefined'){
					infoHTML += "E-mail: <a href=\"mailto:"+offices[j].getElementsByTagName('email')[0].firstChild.nodeValue+"\">"+offices[j].getElementsByTagName('email')[0].firstChild.nodeValue+"</a><br/>";
				}
				infoHTML += "</p>";

			}
		}




		//infoHTML += "<a href=\"javascript:doNothing();\" onclick=\"toggleGMapZoom(this);this.blur();\" class=\"zoom detail\" title=\"Zoom in\"><span>Zoom in</span></a>";
		infoHTML += "</div>";

		var point = new GLatLng(dataObj.getAttribute('latitude'),dataObj.getAttribute('longitude'));
		var icon;
		if(properties.length > 1){
			icon =  this.propertiesIcon;
		}else if(offices.length > 0){
			icon = this.officeIcon;
		}else{
			icon = this.propertyIcon;
		}
		
		return this.createGMapMarker(point,infoHTML,icon);
	}
	
	this.createDetailsLink = function(page,vars,inner,className){

		var link = "<a href=\""+page;
		link += (String(page).substr(0,7) == "http://") ? "?pagevars="+vars+"\"" : vars+"\"";
		link += (className != null) ? " class=\""+className+"\"" : "";
		link += ">";
		link += (inner == null) ? "More Details" : inner;
		link += "</a>";
		return link;
		
	}
	
	this.createGMapMarker = function(point,html,icon){
		var marker = new GMarker(point, icon);
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml(html,{maxWidth:300} );
		});
		return marker;
	}
	
	this.addPropertyToList = function(dataObj,lat,lng){
		
		var divObj;
		
		if(this.listDiv != null && (divObj = document.getElementById(this.listDiv))){
			
			this.listArray.push({data:dataObj,lat:lat,lng:lng});
	
		}
		
	}
	
	this.displayPropertyList = function(){
		
		if(this.listDiv != null && this.listArray.length > 0 && (divObj = document.getElementById(this.listDiv))){
			
			var html = "<ul class=\"googleMapList\">";
			
			for(var i=0;i<this.listArray.length;i++){

				html += "<li><a href=\"javascript:resultsMap" + this.getAttribute("id") +".mapObj.displayPropertyFromList("+i+");\"";
				html += " onmouseover=\"resultsMap" + this.getAttribute("id") +".mapObj.displayToolTipFromList("+i+");\"";
				html += " onmouseout=\"resultsMap" + this.getAttribute("id") +".mapObj.hideToolTip();\">";
				html += this.listArray[i].data.getElementsByTagName('shortAddress')[0].firstChild.nodeValue + " <strong>"+this.listArray[i].data.getElementsByTagName('price')[0].firstChild.nodeValue+"</strong>";
				html += "</a></li>\n";
				
			}
			
			html += "</ul>";
			
			divObj.innerHTML = html;
			
		}
		
	}
	
	this.displayPropertyFromList = function(index){
		
		this.hideToolTip();
		
		if(this.listArray[index] != null){
			
			var point = new GLatLng(this.listArray[index].lat,this.listArray[index].lng);
			var infoHTML = "<div class='gMapInfoWindow clearfix'>";
			
			infoHTML += "<p>";
			if(this.listArray[index].data.getElementsByTagName('image')[0]){
				infoHTML += "<image src='"+this.listArray[index].data.getElementsByTagName('image')[0].getAttribute('src')+"' width='"+this.listArray[index].data.getElementsByTagName('image')[0].getAttribute('width')+"' height='"+this.listArray[index].data.getElementsByTagName('image')[0].getAttribute('height')+"' />";
			}
			infoHTML += "<strong>"+this.listArray[index].data.getElementsByTagName('price')[0].firstChild.nodeValue+"</strong>";
			infoHTML += " "+this.listArray[index].data.getElementsByTagName('address')[0].firstChild.nodeValue+"<br />";
			if(this.listArray[index].data.getElementsByTagName('rooms')[0]){
				infoHTML += this.listArray[index].data.getElementsByTagName('rooms')[0].firstChild.nodeValue+"<br />";
			}
			if(this.listArray[index].data.getElementsByTagName('status')[0]){
				infoHTML += "<span class='status'>"+this.listArray[index].data.getElementsByTagName('status')[0].firstChild.nodeValue+"</span> ";
			}
			infoHTML += "<a href=\"";
			
			if(String(this.getAttribute("detailsPage")).substr(0,7) != "http://" && typeof(window["pathToRoot"]) != "undefined"){
				infoHTML += pathToRoot;
			}
			
			infoHTML += this.getAttribute("detailsPage")+this.listArray[index].data.getElementsByTagName('requestString')[0].firstChild.nodeValue+"\">More Details</a><br/>";
			infoHTML += "</p>";
			infoHTML += "</div>";

			this.googleMap.openInfoWindow(point,infoHTML);
			
		}
		
	}
	
	this.displayToolTipFromList = function(index){
		
		this.hideToolTip();
		
		if(this.listArray[index] != null){
			
			var point = new GLatLng(this.listArray[index].lat,this.listArray[index].lng);
			var text = this.listArray[index].data.getElementsByTagName('shortAddress')[0].firstChild.nodeValue;
			this.toolTip = new Tooltip(point,text,5);
			this.googleMap.addOverlay(this.toolTip);
			this.toolTip.show();
			
		}
		
	}
	
	this.hideToolTip = function(){
		
		if(this.toolTip != null){
			
			this.toolTip.remove();
			this.toolTip = null;
		}
		
	}
	
	this.displayMessage = function(text){
		
		var div = document.getElementById(this.mapDiv);
		if(div != null){
			div.innerHTML = "<div class=\"message\">"+text+"</div>"; 
		}
	}
	
	this.operationTimedOut = function(){
		
		this.displayMessage("Operation timed out, please try again");
		
		var div = document.getElementById(this.mapDiv);
		
		if(div != null){
			div.className = "googleMap noResults";
		}
		
		if(this.xmlObj != null){
			
			this.xmlObj.onreadystatechange=null;
			
		}
		
	}
	
	
	this.unLoadMap = function(){
		
		if(this.googleMap != null){
			GUnload();
			this.googleMap = null;
		}
	
	}
	
	this.showStatus = function(str){
		
	}
	
	this.pan = function(dx,dy){
		if(this.googleMap != null){
			this.googleMap.panDirection(dx,dy);
		}
	}
	
	this.zoomInTo = function(lat,lng,zoomLevel){
		
		var centre = new GLatLng(lat,lng);
		this.googleMap.panTo(centre);
		if(zoomLevel){
			this.googleMap.setZoom(zoomLevel);
		}else{
			this.googleMap.zoomIn();
		}
	}


}


function Tooltip(point, text, padding){
	GOverlay.call(this);
	this.point_ = point;
	this.text_ = text;
	this.padding_ = padding;
	
	this.initialize = function(map){
		var div = document.createElement("div");
		div.appendChild(document.createTextNode(this.text_));
		div.className = 'tooltip';
		div.style.position = 'absolute';
		div.style.visibility = 'hidden';
		map.getPane(G_MAP_FLOAT_PANE).appendChild(div);
		this.map_ = map;
		this.div_ = div;
	}

	this.remove = function(){
		this.div_.parentNode.removeChild(this.div_);
	}

	this.copy = function(){
		return new Tooltip(this.marker_,this.text_,this.padding_);
	}

	this.redraw = function(force){
		if (!force) return;
		var markerPos = this.map_.fromLatLngToDivPixel(this.point_);
		var xPos = Math.round(markerPos.x - this.div_.clientWidth / 2);
		var yPos = markerPos.y - this.div_.clientHeight - this.padding_;
		this.div_.style.top = yPos + 'px';
		this.div_.style.left = xPos + 'px';
	}

	this.show = function(){
		this.div_.style.visibility = 'visible';
	}

	this.hide = function(){
		this.div_.style.visibility = 'hidden';
	}
	
}


Tooltip.inherits(GOverlay)