
/*****************/
/**** EWindow ****/

function EStyle(stemImage, stemSize, boxClass, boxOffset) {
	this.stemImage = stemImage;
	this.stemSize = stemSize;
	this.boxClass = boxClass;
	this.boxOffset = boxOffset;

	var agent = navigator.userAgent.toLowerCase();

	var fudge = 0;
	this.fudge = fudge;
}

function EWindow(map,estyle) {
	// parameters
	this.map=map;
	this.estyle=estyle;
	// internal variables
	this.visible = false;
	// browser - specific variables
	this.ie = false;
	var agent = navigator.userAgent.toLowerCase();
	if ((agent.indexOf("msie") > -1) && (agent.indexOf("opera") < 1)){ this.ie = true} else {this.ie = false}
} 

EWindow.prototype = new GOverlay();

EWindow.prototype.initialize = function(map) {
	var div1 = document.createElement("div");
	div1.style.position = "absolute";
	map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div1);
	var div2 = document.createElement("div");
	div2.style.position = "absolute";
	div2.style.width = this.estyle.stemSize.width+"px";
	map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div2);
	this.div1 = div1;
	this.div2 = div2;
}

EWindow.prototype.openOnMap = function(point, html, offset) {
	this.offset = offset||new GPoint(0,0);
	this.point = point;
	this.div1.innerHTML = '<div class="' + this.estyle.boxClass + '">' + html + '</div>';
	if (this.ie && this.estyle.stemImage.toLowerCase().indexOf(".png")>-1) {
		var loader = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.estyle.stemImage+"', sizingMethod='scale');";
		this.div2.innerHTML = '<div style="height:' +this.estyle.stemSize.height+ 'px; width:'+this.estyle.stemSize.width+'px; ' +loader+ '" ></div>';
	} else {
		this.div2.innerHTML = '<img src="' + this.estyle.stemImage + '" width="' + this.estyle.stemSize.width +'" height="' + this.estyle.stemSize.height +'">';
	}
	var z = GOverlay.getZIndex(this.point.lat());
	this.div1.style.zIndex = z;
	this.div2.style.zIndex = z+1;
	this.visible = true;
	this.show();
	this.redraw(true);
}

EWindow.prototype.openOnMarker = function(marker,html) {
	var vx = marker.getIcon().iconAnchor.x - marker.getIcon().infoWindowAnchor.x;
	var vy = marker.getIcon().iconAnchor.y - marker.getIcon().infoWindowAnchor.y;
	this.openOnMap(marker.getPoint(), html, new GPoint(vx,vy));
}


EWindow.prototype.redraw = function(force) {
	if (!this.visible) {return;}
	var p = this.map.fromLatLngToDivPixel(this.point);
	this.div2.style.left   = (p.x + this.offset.x) + "px";
	this.div2.style.bottom = (-p.y + this.offset.y -this.estyle.fudge) + "px";
	this.div1.style.left   = (p.x + this.offset.x + this.estyle.boxOffset.x) + "px";
	this.div1.style.bottom = (-p.y + this.offset.y + this.estyle.boxOffset.y) + "px";
}

EWindow.prototype.remove = function() {
	this.div1.parentNode.removeChild(this.div1);
	this.div2.parentNode.removeChild(this.div2);
	this.visible = false;
}

EWindow.prototype.copy = function() {
	return new EWindow(this.map, this.estyle);
}

EWindow.prototype.show = function() {
	this.div1.style.display="";
	this.div2.style.display="";
	this.visible = true;
}

EWindow.prototype.hide = function() {
	this.div1.style.display="none";
	this.div2.style.display="none";
	this.visible = false;
}

EWindow.prototype.isHidden = function() {
	return !this.visible;
}

EWindow.prototype.supportsHide = function() {
	return true;
}

EWindow.prototype.zindex = function(zin) {
	var z = GOverlay.getZIndex(this.point.lat());
	this.div1.style.zIndex = z+zin;
	this.div2.style.zIndex = z+1+zin;
}


EWindow.prototype.getSize = function() {
	if (!this.visible) {
		return null;
	}
	else {
		return new GSize(this.div1.offsetWidth, this.div1.offsetHeight + this.div2.offsetHeight);
	}
}
/**** EWindow ****/
/*****************/

var ICON_DEFAULT;

var ICON_HOUSE;
var ICON_HOUSE_DISCOUNT;
var ICON_MULTIPLE_HOUSES;


var TYPE_DEFAULT = -1;
var TYPE_MULTIPLE_DEFAULT = -2;
var TYPE_HOUSE = 0;
var TYPE_MULTIPLE_HOUSES = 1;
var TYPE_HOUSE_DISCOUNT = 3;


var E_STYLE_DEFAULT;
var E_STYLE_HOUSE;
var E_STYLE_HOUSE_DISCOUNT;
var E_STYLE_MULTIPLE_HOUSES;


var ew = null;
var ewm = null;


if (GBrowserIsCompatible()) {
	ICON_DEFAULT = new GIcon();
	ICON_DEFAULT.image = "/site/images/ICON_DEFAULT.png";
	ICON_DEFAULT.iconSize = new GSize(20, 20);
	ICON_DEFAULT.iconAnchor = new GPoint(0, 20);
	ICON_DEFAULT.infoWindowAnchor = new GPoint(-8, 5);
	ICON_DEFAULT.shadow = "/site/images/ICON_DEFAULT_SHADOW.png";
	ICON_DEFAULT.shadowSize = new GSize(20, 20);


	ICON_HOUSE = new GIcon();
	ICON_HOUSE.image = "/site/images/ICON_HOUSE.png";
	ICON_HOUSE.iconSize = new GSize(16, 16);
	ICON_HOUSE.iconAnchor = new GPoint(8, 16);
	ICON_HOUSE.infoWindowAnchor = new GPoint(8, 8);

	ICON_HOUSE_DISCOUNT = new GIcon();
	ICON_HOUSE_DISCOUNT.image = "/site/images/ICON_HOUSE_DISCOUNT.png";
	ICON_HOUSE_DISCOUNT.iconSize = new GSize(16, 16);
	ICON_HOUSE_DISCOUNT.iconAnchor = new GPoint(8, 16);
	ICON_HOUSE_DISCOUNT.infoWindowAnchor = new GPoint(8, 8)

	ICON_MULTIPLE_HOUSES = new GIcon();
	ICON_MULTIPLE_HOUSES.image = "/site/images/ICON_MULTIPLE_HOUSES.png";
	ICON_MULTIPLE_HOUSES.iconSize = new GSize(16, 16);
	ICON_MULTIPLE_HOUSES.iconAnchor = new GPoint(8, 16);
	ICON_MULTIPLE_HOUSES.infoWindowAnchor = new GPoint(8, 8);

	
	E_STYLE_DEFAULT = new EStyle("/site/images/STEM.png", new GSize(24, 24), "e_style_tgv", new GPoint(-10, 23));
	E_STYLE_HOUSE = new EStyle("/site/images/STEM_HOUSES.png", new GSize(24, 24), "e_style_house", new GPoint(-10, 23));
	E_STYLE_HOUSE_DISCOUNT = new EStyle("/site/images/STEM_DISCOUNT.png", new GSize(24, 24), "e_style_house_discount", new GPoint(-10, 23));
	E_STYLE_MULTIPLE_HOUSES = new EStyle("/site/images/STEM_MULTIPLE_HOUSES.png", new GSize(24, 24), "e_style_multiple_houses", new GPoint(-10, 23));

	GMarker.prototype.type = -1;
}










/* Google Maps wrapper function */
function googleMapsObject() {
	var _this = this;

	this.toggleLoading = function() {
		if (_this.settings.loading) {
			var b = _this.settings.loading.style.display;
			var bLoading = false;

			if (arguments.length > 0) {
				if (arguments[0]) {
					bLoading = true;					
				}
			}
			else {
				bLoading = (b == "" ? true : (b == "block" ? false : true));			
			}

			b = (bLoading ? "block" : "none");

			_this.settings.loading.style.display = b;
			if (b == "block") {
				if (_this.map) {
					var x = Math.round((_this.map.getSize().width - _this.settings.loading.offsetWidth)/ 2);
					var y = Math.round((_this.map.getSize().height - _this.settings.loading.offsetHeight)/ 2);
					_this.settings.loading.style.top = y +"px";
					_this.settings.loading.style.left = x +"px";
				}
			}

		}
	}

	this.mapPoints = Array();
	this.addMapPoint = function(gmPoint) {
		_this.mapPoints[_this.mapPoints.length] = gmPoint;
		_this.initMapPoint(_this.mapPoints[_this.mapPoints.length - 1]);
		return _this.mapPoints.length - 1;
	}

	this.initMapPoint = function(gmPoint) {
		if (gmPoint) {
			var waitObj = new waitForIt();

			waitObj.waitFor = function() {
				return gmPoint.completed();
			}
			waitObj.whenDone = function() {
				if (gmPoint.point) {
					_this.createMarker(gmPoint);
				}
				else {
					//could not find supplied Point
				}
			}

			waitObj.run();
		}
	}


	this.addTGVMapPoint = function(gmPoint) {
		_this.mapPoints[_this.mapPoints.length] = gmPoint;
		_this.initTGVMapPoint(_this.mapPoints[_this.mapPoints.length - 1]);
		return _this.mapPoints.length - 1;
	}

	this.initTGVMapPoint = function(gmPoint) {
		if (gmPoint) {
			var waitObj = new waitForIt();

			waitObj.waitFor = function() {
				return gmPoint.completed();
			}
			waitObj.whenDone = function() {
				if (gmPoint.point) {
					_this.createTGVMarker(gmPoint);
				}
				else {
					//could not find supplied Point
				}
			}

			waitObj.run();
		}
	}

	this.setTGVZoom = function() {
		var _this = this;

		if (_this.mapPoints.length > 0) {
			var oBounds = new GLatLngBounds();

			for (var i = 0; i < _this.mapPoints.length; i++) {
				if (_this.mapPoints[i].point != null) {
					oBounds.extend(_this.mapPoints[i].point);
				}
			}

			_this.map.setCenter(oBounds.getCenter(), _this.map.getBoundsZoomLevel(oBounds));
		}
	}
	

	this.getBounds = function() {
		if (_this.mapPoints.length > 0) {
			var minLat = null;
			var minLng = null;
			var maxLat = null;
			var maxLng = null;

			for (var i = 0; i < _this.mapPoints.length; i++) {
				var p = _this.mapPoints[i].point;
				if (p) {
					minLat = minLat ? (minLat <= p.lat() ? minLat : p.lat()) : p.lat();
					minLng = minLng ? (minLng <= p.lng ? minLng : p.lng) : p.lng();
					maxLat = maxLat ? (maxLat >= p.lat() ? maxLat : p.lat()) : p.lat();
					maxLng = maxLng ? (maxLng >= p.lng() ? maxLng : p.lng()) : p.lng();
				}
			}

			return new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
		}	
		else {
			return null;
		}
	}



	this.map = null;
	this.geocoder = null;
	this.point = null;

	this.settings = {
		enableGeocodeLookup : false,
		zoom : 13,
		center : (GBrowserIsCompatible() ? new GLatLng(56.180211, 10.136023) : null),
		container : null,
		loading : null,
		scrollWheelZoom : true
	};

	this.controls = {
		mapTypeControl : true,
		smallMapControl : false,
		largeMapControl : false,
		overviewMapControl : false
	};

	this.setZoom = function(zoom) {
		if (GBrowserIsCompatible) {
			_this.map.setZoom(zoom);
		}
	};


	this.wheelevent = function(e) {
		if (!e) {
			e = window.event;
		}
		if (e.preventDefault) {
			e.preventDefault();
		}
		e.returnValue = false;
	}

	this.init = function() {
		if (GBrowserIsCompatible()) {
			_this.map = new GMap2(_this.settings.container);

			GEvent.addDomListener(_this.map.getContainer(), "DOMMouseScroll", _this.wheelevent);
			_this.map.getContainer().onmousewheel = _this.wheelevent;

			_this.map.setCenter(_this.settings.center, _this.settings.zoom); 

			if (_this.settings.scrollWheelZoom) {
				_this.map.enableScrollWheelZoom();
			}

			if (_this.controls.smallMapControl) {
				_this.map.addControl(new GSmallMapControl());
			}

			if (_this.controls.largeMapControl) {
				_this.map.addControl(new GLargeMapControl());
			}

			if (_this.controls.overviewMapControl) {
				_this.map.addControl(new GOverviewMapControl());
			}
			
			if (_this.controls.mapTypeControl) {
				_this.map.addControl(new GMapTypeControl());
			}

			ew = new EWindow(oGM.map, E_STYLE_HOUSE);
			_this.map.addOverlay(ew);
		
			/* house "cluster" info window */
			ewm = new EWindow(_this.map, E_STYLE_MULTIPLE_HOUSES);
			_this.map.addOverlay(ewm);

		}
	}





	this.markers = Array();

	this.markerExistsAtPoint = function(point) {
		var _this = this;
		var exists = false;
		for (var i = 0; i < _this.markers.length; i++) {
			mp = _this.markers[i].getLatLng();

			if ((mp.lat() == point.lat()) && (mp.lng() == point.lng())) {
				exists = true;
				break;
			}
		}
		return exists;
	}

	this.getMarkerAtPoint = function(point) {
		var _this = this;
		var res = null;
		for (var i = 0; i < _this.markers.length; i++) {
			latlng = _this.markers[i].getLatLng();
			if ((latlng.lat() == point.lat()) && (latlng.lng() == point.lng())) {
				res = _this.markers[i];
			}
		}

		return res;
	}

	this.removeMarker = function(oMarker) {
		var _this = this;

		var res = Array();
		for (var i = 0; i < _this.markers.length; i++) {
			if (_this.markers[i] != oMarker) {
				res[res.length] = _this.markers[i];
			}
		}
		_this.markers = res;
		_this.map.removeOverlay(oMarker);
	}

	this.addMarker = function(oMarker) {
		var _this = this;
		_this.markers[_this.markers.length] = oMarker;
		_this.map.addOverlay(oMarker);
	}


	this.pointsEqual = function(p1, p2) {
		if ((p1 != null) && (p2 != null)) {
			if ((p1.lat() == p2.lat()) && (p1.lng() == p2.lng())) {
				return true;
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}

	this.getHousesAtPoint = function(point) {
		var _this = this;
		var res = Array();
		var mp = null;
		for (var i = 0; i < _this.mapPoints.length; i++) {
			if (_this.pointsEqual(_this.mapPoints[i].point, point)) {
				res[res.length] = _this.mapPoints[i];
			}
		}
		return res;
	}

	this.getMarkersAtPoint = function(point) {
		var _this = this;
		var res = Array();
		var mp = null;
		for (var i = 0; i < _this.mapPoints.length; i++) {
			if (_this.pointsEqual(_this.mapPoints[i].point, point)) {
				res[res.length] = _this.mapPoints[i];
			}
		}
		return res;
	}


	this.createSimpleHouseMarker = function(oLatLng) {
		var _this = this;
		var oMarker = new GMarker(oLatLng, {icon : ICON_HOUSE, clickable : false});
		_this.map.addOverlay(oMarker);
	}


	this.clearMarkers = function() {
		var _this = this;
		for (var i = 0; i < _this.markers.length; i++) {
			_this.map.removeOverlay(_this.markers[i]);
		}
		_this.markers = Array();
	}

	this.clearMapPoints = function() {
		var _this = this;
		for (var i = 0; i < _this.mapPoints.length; i++) {
			_this.mapPoints[i] = null;
		}
		_this.mapPoints = Array();

	}

	this.clearHouses = function() {
		var _this = this;

		if (ew) {
			_this.map.removeOverlay(ew);
		}
		if (ewm) {
			_this.map.removeOverlay(ewm);
		}
		_this.clearMarkers();
		_this.clearMapPoints();
		return false;
	}
		

		
	this.closeHouse = function() {
		if (ew) {
			ew.hide();
		}
		return false;
	}

	this.closeMultipleHouses = function() {
		if (ew) {
			ew.hide();
		}
		if (ewm) {
			ewm.hide();
		}
		return false;
	}

	this.closeTGV = function() {
		if (ew) {
			ew.hide();
		}
		return false;
	}

	this.showHouseInfo = function(obj, lat, lng, id) {
		var _this = this;

		if (ew != null) {
			_this.map.removeOverlay(ew);
		}

		var objPos = findPos(obj);
		var mapPos = findPos(_this.settings.container);

		var x = objPos[0] - mapPos[0];
		var y = objPos[1] - mapPos[1];


		
		var objectPoint = new GPoint(x, y);
		var objectLatLng = _this.map.fromContainerPixelToLatLng(objectPoint);
		objectPoint = _this.map.fromLatLngToDivPixel(objectLatLng);

		var parentMarkerLatLng = new GLatLng(lat, lng);
		var parentMarkerPoint = _this.map.fromLatLngToDivPixel(parentMarkerLatLng);

		var offsetPoint = new GPoint(objectPoint.x - parentMarkerPoint.x + 8, parentMarkerPoint.y - objectPoint.y - 8);


		var oHouse = _this.getHouse(id);
		html = _this.getHouseHTML(oHouse);

		ew = new EWindow(_this.map, (oHouse.data.discount > 0 ? E_STYLE_HOUSE_DISCOUNT : E_STYLE_HOUSE));
		_this.map.addOverlay(ew);
		ew.openOnMap(parentMarkerLatLng, html, offsetPoint);

		var targetPoint = objectPoint;
		var targetLatLng = null;
		var ewSize = ew.getSize();

		if (ewSize) {
			targetPoint = new GPoint(targetPoint.x + Math.round(ewSize.width / 2), targetPoint.y - Math.round(ewSize.height / 2));
			targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
		}
		else {
			targetLatLng = parentMarkerLatLng;
		}

		_this.map.panTo(targetLatLng);
	}

	


	//Given id - return house from our list
	this.getHouse = function(id) {
		for (var i = 0; i < _this.mapPoints.length; i++) {
			if (_this.mapPoints[i].data.id == id) {
				return _this.mapPoints[i];
			}
		}	
		return null;
	}

	//Given id - return marker item from our list
	this.getMarker = function(id) {
		for (var i = 0; i < _this.mapPoints.length; i++) {
			if (_this.mapPoints[i].id == id) {
				return _this.mapPoints[i];
			}
		}	
		return null;
	}


	this.updateHouseIcon = function(oHouse) {
		var newIcon = null;

		newIcon = (oHouse.data.discount > 0 ? ICON_HOUSE_DISCOUNT : ICON_HOUSE);

		if (newIcon != null) {
			oHouse.icon = newIcon;
			if (oHouse.marker != null) {
				oHouse.marker.setImage(oHouse.icon.image);
			}
			else {
				//Refresh image in parent infowindow:
				var oImg = document.getElementById("house_icon_"+ oHouse.data.id);
				if (oImg != null) {
					oImg.src = oHouse.icon.image;
				}
			}
		}
	}




	this.getHouseHTML = function(oHouse) {

		var html = "";
		html += "<div class=\"content\">";

		html += "<img class=\"close\" src=\"/site/images/close.png\" width=\"10\" height=\"9\" alt=\"\" onclick=\"return oGM.closeHouse();\" />";

		var oImg = null;
		if (oHouse.data) {
			if (oHouse.data.img) {
				if (oHouse.data.img != "") {
					oImg = new Image();
					oImg.src = oHouse.data.img;
				}
			}
		}

		html += (oImg != null ? "<div class=\"img\"><img src=\""+ oImg.src +"\" width=\"165\" alt=\"\" /></div>" : "");
		
		html += "<div class=\"area\"><a href=\""+  oHouse.data.url +"\">"+ oHouse.address.street +"<br />"+ oHouse.address.area +"</a></div>";

		html += "<div class=\"number\"><a href=\""+ oHouse.data.url +"\">Feriehus "+ oHouse.data.number +"</a></div>";

		html += "<div class=\"price\">";
		if (oHouse.data.discount > 0) {
			html += "<del>"+ (oHouse.data.price +",00").formatFloat() +" "+ oHouse.data.currency +"</del><br />";
			html += (oHouse.data.totalPrice +",00").formatFloat() +" "+ oHouse.data.currency;
		}
		else {
			html += (oHouse.data.totalPrice +",00").formatFloat() +" "+ oHouse.data.currency +"<br />&nbsp;";
		}
		html += "</div>";

		html += "<div class=\"capacity\">Max. "+ oHouse.data.capacity +" personer</div>";
		html += "<div class=\"m2\">"+ (oHouse.data.m2 != "" ? oHouse.data.m2 +" m&#xb2" : "&nbsp;") +"</div>";

		
	
		html += "</div>";

		
		return html;
	}


	this.showMarkerInfo = function(oMarker) {
		var _this = this;

		var myHouses = _this.getHousesAtPoint(oMarker.getLatLng());

		switch (oMarker.type) {
			case TYPE_HOUSE :

				if (ew != null) {
					_this.map.removeOverlay(ew);
				}

				if (ewm != null) {
					_this.map.removeOverlay(ewm);
				}

				myHouse = myHouses[0];
				html = _this.getHouseHTML(myHouse);


				ew = new EWindow(_this.map, (myHouse.data.discount > 0 ? E_STYLE_HOUSE_DISCOUNT : E_STYLE_HOUSE));
				_this.map.addOverlay(ew);
				ew.openOnMarker(oMarker, html);


				var targetPoint = _this.map.fromLatLngToDivPixel(oMarker.getLatLng());
				var targetLatLng = null;
				var ewSize = ew.getSize();

				if (ewSize) {
					targetPoint = new GPoint(targetPoint.x + Math.round(ewSize.width / 2), targetPoint.y - Math.round(ewSize.height / 2));
					targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
				}
				else {
					targetLatLng = oMarker.getLatLng;
				}

				_this.map.panTo(targetLatLng);
				break;

			case TYPE_MULTIPLE_HOUSES :
				if (ew != null) {
					_this.map.removeOverlay(ew);
				}

				if (ewm != null) {
					_this.map.removeOverlay(ewm);
				}

				var str = "";
				for (var i = 0; i < myHouses.length; i++) {
					myHouse = myHouses[i];
					str += "<img id=\"house_icon_"+ myHouse.data.id +"\" class=\"house\" onclick=\"oGM.showHouseInfo(this, "+ oMarker.getLatLng().lat() +", "+ oMarker.getLatLng().lng() +", '"+ myHouse.data.id +"');\" src=\""+ myHouse.icon.image +"\" width=\""+ myHouse.icon.iconSize.width +"\" height=\""+ myHouse.icon.iconSize.height +"\" />";
				}
				
				
				html = ""
				html += "<div class=\"content\">";
				html += "<img class=\"close\" onclick=\"return oGM.closeMultipleHouses();\" src=\"/site/images/close.png\" width=\"10\" height=\"9\" alt=\"\" />";
				html += myHouses.length +" feriehuse fundet<br />"+ str;
				html += "</div>";


				ewm = new EWindow(_this.map, E_STYLE_MULTIPLE_HOUSES);
				_this.map.addOverlay(ewm);

				ewm.openOnMarker(oMarker, html);

				var targetPoint = _this.map.fromLatLngToDivPixel(oMarker.getLatLng());
				var targetLatLng = null;
				var ewmSize = ewm.getSize();

				if (ewmSize) {
					targetPoint = new GPoint(targetPoint.x + Math.round(ewmSize.width / 2), targetPoint.y - Math.round(ewmSize.height / 2));
					targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
				}
				else {
					targetLatLng = oMarker.getLatLng;
				}

				_this.map.panTo(targetLatLng);
				break;
		}
	}


	this.createMarker = function(gmPoint) {
		var _this = this;

		var addNewMarker = true;

		var oMarker = _this.getMarkerAtPoint(gmPoint.point);

		//marker found at this coordinate:
		if (oMarker) {
			addNewMarker = false;

			//Replace marker object
			_this.removeMarker(oMarker);


			//Remove reference to marker objects:
			var myHouses = _this.getHousesAtPoint(gmPoint.point);
			for (var i = 0; i < myHouses.length; i++) {
				myHouses[i].marker = null;
			}

			oMarker = new GMarker(gmPoint.point, ICON_MULTIPLE_HOUSES);
			oMarker.type = TYPE_MULTIPLE_HOUSES;

			GEvent.addListener(oMarker, "click", function() {
				_this.showMarkerInfo(this);
			});

			_this.addMarker(oMarker);

		}

		//no marker found at specified coordinate, create one:
		if (addNewMarker) {
			oMarker = new GMarker(gmPoint.point, gmPoint.icon);
			oMarker.type = TYPE_HOUSE;

			GEvent.addListener(oMarker, "click", function() {
				_this.showMarkerInfo(this);
			});
			
			_this.addMarker(oMarker);

			gmPoint.marker = oMarker;

		}
		

	}


	this.showTGVInfo = function(obj, lat, lng, id) {
		var _this = this;
		
		if (cXMLHttp != null) {
			cXMLHttp.abort();
			_this.toggleLoading(0);
		}

	
		var rx = /.*idd(\d+)\.asp.*?$/i;
		var dest = window.document.location.pathname;
		dest = dest.replace(rx, "$1");

		var objPos = findPos(obj);
		var mapPos = findPos(_this.settings.container);

		var x = objPos[0] - mapPos[0];
		var y = objPos[1] - mapPos[1];

		var objectPoint = new GPoint(x, y);
		var objectLatLng = _this.map.fromContainerPixelToLatLng(objectPoint);
		objectPoint = _this.map.fromLatLngToDivPixel(objectLatLng);

		var parentMarkerLatLng = new GLatLng(lat, lng);
		var parentMarkerPoint = _this.map.fromLatLngToDivPixel(parentMarkerLatLng);

		var offsetPoint = new GPoint(objectPoint.x - parentMarkerPoint.x + 8, parentMarkerPoint.y - objectPoint.y - 8);

		var oMarker = _this.getMarker(id);



		var oXML = new XMLObject();
		var oXMLHttp = new XMLHttpRequestObject();
		oXMLHttp.src = "/site/custom/customerXML.asp";
		oXMLHttp.args = "doc="+ dest +"&tgvid="+ oMarker.id +"&language_id=1";
		oXMLHttp.async = true;

		cXMLHttp = oXMLHttp;

		var waitObj = new waitForIt();
		
		waitObj.waitFor = function() {
			return oXMLHttp.completed();
		}

		waitObj.whenDone = function() {
			if (ew != null) {
				_this.map.removeOverlay(ew);
			}

			if (oXML.loadXML(oXMLHttp.xml)) {

				var oHTML = oXML.selectSingleNode("//html");
				var sHTML = oXML.getText(oHTML);
				sHTML = "<div class=\"content\">"+ sHTML + "<img class=\"close\" onclick=\"return oGM.closeTGV();\" src=\"/site/images/close.png\" width=\"10\" height=\"9\" alt=\"\" /></div>";

				if (oHTML != null) {
					ew = new EWindow(_this.map, E_STYLE_DEFAULT);
					_this.map.addOverlay(ew);

					//ew.openOnMarker(oMarker, sHTML);
					ew.openOnMap(parentMarkerLatLng, sHTML, offsetPoint);

					var targetPoint = objectPoint;// _this.map.fromLatLngToDivPixel(oMarker.getLatLng());

					var targetLatLng = null;
					var ewSize = ew.getSize();
					if (ewSize) {
						targetPoint = new GPoint(targetPoint.x + Math.round(ewSize.width / 2), targetPoint.y - Math.round(ewSize.height / 2));
						targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
					}
					_this.map.panTo(targetLatLng);
				}
			}
			else {
				//data not found ... do nothing
			}
			_this.toggleLoading(0);
		}

		_this.toggleLoading(1);
		oXMLHttp.load();
		waitObj.run();
	}

	this.closeMultipleTGV = function() {
		if (ew) {
			ew.hide();
		}
		if (ewm) {
			ewm.hide();
		}
		return false;
	}

	this.showTGVMarkerInfo = function(gmPoint) {
		var _this = this;

		var rx = /.*idd(\d+)\.asp.*?$/i;
		var dest = window.document.location.pathname;
		dest = dest.replace(rx, "$1");




		var oMarker = gmPoint.marker;
		var myMarkers = _this.getMarkersAtPoint(oMarker.getLatLng());

		switch (oMarker.type) {
			case TYPE_DEFAULT :

				if (cXMLHttp != null) {
					cXMLHttp.abort()
					_this.toggleLoading(0);
				}

				myMarker = myMarkers[0];

				var oXML = new XMLObject();
				var oXMLHttp = new XMLHttpRequestObject();
				oXMLHttp.src = "/site/custom/customerXML.asp";
				oXMLHttp.args = "doc="+ dest +"&tgvid="+ gmPoint.id +"&language_id=1";
				oXMLHttp.async = true;

				cXMLHttp = oXMLHttp;

				var waitObj = new waitForIt();
				
				waitObj.waitFor = function() {
					return oXMLHttp.completed();
				}

				waitObj.whenDone = function() {
					if (ew != null) {
						_this.map.removeOverlay(ew);
					}

					if (ewm != null) {
						_this.map.removeOverlay(ewm);
					}

					if (oXML.loadXML(oXMLHttp.xml)) {

						var oHTML = oXML.selectSingleNode("//html");
						var sHTML = oXML.getText(oHTML);
						sHTML = "<div class=\"content\">"+ sHTML + "<img class=\"close\" onclick=\"return oGM.closeTGV();\" src=\"/site/images/close.png\" width=\"10\" height=\"9\" alt=\"\" /></div>";

						if (oHTML != null) {
							ew = new EWindow(_this.map, E_STYLE_DEFAULT);
							_this.map.addOverlay(ew);

							ew.openOnMarker(oMarker, sHTML);

							var targetPoint = _this.map.fromLatLngToDivPixel(oMarker.getLatLng());

							var targetLatLng = null;
							var ewSize = ew.getSize();
							if (ewSize) {
								targetPoint = new GPoint(targetPoint.x + Math.round(ewSize.width / 2), targetPoint.y - Math.round(ewSize.height / 2));
								targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
							}
							_this.map.panTo(targetLatLng);
						}
					}
					else {
						//data not found ... do nothing
					}
					_this.toggleLoading(0);
				}

				_this.toggleLoading(1);
				oXMLHttp.load();
				waitObj.run();



				break;

			case TYPE_MULTIPLE_DEFAULT :
				if (ew != null) {
					_this.map.removeOverlay(ew);
				}

				if (ewm != null) {
					_this.map.removeOverlay(ewm);
				}


				var str = "";
				for (var i = 0; i < myMarkers.length; i++) {
					myMarker = myMarkers[i];
					str += "<img id=\"tgv_icon_"+ myMarker.id +"\" class=\"tgv_icon\" onclick=\"oGM.showTGVInfo(this, "+ myMarker.point.lat() +", "+ myMarker.point.lng() +", "+ myMarker.id +");\" src=\""+ myMarker.icon.image +"\" width=\""+ myMarker.icon.iconSize.width +"\" height=\""+ myMarker.icon.iconSize.height +"\" />";
				}

				html = "";
				html += "<div class=\"content\">";
				html += "<img class=\"close\" onclick=\"return oGM.closeMultipleTGV();\" src=\"/site/images/close.png\" width=\"10\" height=\"9\" alt=\"\" />";
				html += myMarkers.length +" emner fundet<br />"+ str;
				html += "</div>";

				ewm = new EWindow(_this.map, E_STYLE_DEFAULT);
				_this.map.addOverlay(ewm);

				ewm.openOnMarker(oMarker, html);
				var targetPoint = _this.map.fromLatLngToDivPixel(oMarker.getLatLng());
				var targetLatLng = null;
				var ewmSize = ewm.getSize();

				if (ewmSize) {
					targetPoint = new GPoint(targetPoint.x + Math.round(ewmSize.width / 2), targetPoint.y - Math.round(ewmSize.height / 2));
					targetLatLng = _this.map.fromDivPixelToLatLng(targetPoint);
				}
				else {
					targetLatLng = oMarker.getLatLng;
				}

				_this.map.panTo(targetLatLng);

				break;
		
		}




	}

	this.createTGVMarker = function(gmPoint) {
		var _this = this;

		var addNewMarker = true;
		
		var oMarker = _this.getMarkerAtPoint(gmPoint.point);

		//marker found at this coordinate:
		if (oMarker) {
			addNewMarker = false;

			//Replace marker object
			_this.removeMarker(oMarker);

			//Remove references to marker objects:
			var myMarkers = _this.getMarkersAtPoint(gmPoint.point);
			for (var i = 0; i < myMarkers.length; i++) {
				myMarkers[i].marker = null;
			}

			oMarker = new GMarker(gmPoint.point, ICON_DEFAULT);
			oMarker.type = TYPE_MULTIPLE_DEFAULT;

			gmPoint.marker = oMarker;

			GEvent.addListener(oMarker, "click", function() {
				_this.showTGVMarkerInfo(gmPoint);
			});

			_this.addMarker(oMarker);


		}

		//no marker found at specified coordinate, create one:
		if (addNewMarker) {
			oMarker = new GMarker(gmPoint.point, gmPoint.icon);
			oMarker.type = TYPE_DEFAULT;

			GEvent.addListener(oMarker, "click", function() {
				_this.showTGVMarkerInfo(gmPoint);
			});

			gmPoint.marker = oMarker;
			_this.addMarker(oMarker);
		}
	}



	this.createMapPoint = function() {
		var gmPoint  = new googleMapPoint();
		gmPoint.map = _this;
		return gmPoint;
	}




}


GClientGeocoder.prototype.statusDescription = function(id) {
	switch (id) {
		case G_GEO_SUCCESS :
			return "200: No errors occurred; the address was successfully parsed and its geocode has been returned.";
			break;
		case G_GEO_BAD_REQUEST :
			return "400: A directions request could not be successfully parsed.";
			break;
		case G_GEO_SERVER_ERROR :
			return "500: A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.";
			break;
		case G_GEO_MISSING_QUERY :
			return "601: The HTTP q parameter was either missing or had no value. For geocoding requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.";
			break;
		case G_GEO_MISSING_ADDRESS :
			return "601: Synonym for G_GEO_MISSING_QUERY.";
			break;
		case G_GEO_UNKNOWN_ADDRESS :
			return "602: No corresponding geographic location could be found for the specified address. This may be due to the fact that the address is relatively new, or it may be incorrect.";
			break;
		case G_GEO_UNAVAILABLE_ADDRESS :
			return "603: The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.";
			break;
		case G_GEO_UNKNOWN_DIRECTIONS :
			return "604: The GDirections object could not compute directions between the points mentioned in the query. This is usually because there is no route available between the two points, or because we do not have data for routing in that region.";
			break;
		case G_GEO_BAD_KEY :
			return "610: The given key is either invalid or does not match the domain for which it was given.";
			break;
		case G_GEO_TOO_MANY_QUERIES :
			return "620: The given key has gone over the requests limit in the 24 hour period.";
			break;
		default :
			return "unknown status";
			break;
	}
}


var oGeocoder = (GBrowserIsCompatible() ? new GClientGeocoder() : null);




function googleMapPoint() {
	var _this = this;

	this.map = null;
	this.icon = null;
	this.type = "";

	this.data = null;

	this.point = null;
	this.marker = null;

	this.accuracy = 0;
	this.getPoint = function() {
		return _this.point;
	}
	
	this.html = "";

	this.toggleLoading = function() {
		if (_this.map) {
			_this.map.toggleLoading();
		}
	}

	this.address = {
		street : "",
		street2 : "",
		zipcode : "",
		city : "",
		area : "",
		region : "",
		state : "",
		country : "",
		longitude : "",
		latitude : ""
	}

	this.addressStr = "";

	this.stripBadChars = function(s) {
		var rx = /[\*]/gi;
		return _this.trim(s.replace(rx, ""));
	}

	this.trim = function(s) {
		return s.replace(/^\s+|\s+$/g, "");
	}

	this.pointLoading = true;
}

googleMapPoint.prototype.geocodeEquals = function(lat, lng) {
	var _this = this;
	return ((_this.address.lat == lat) && (_this.address.lng == lng));
}

googleMapPoint.prototype.getAddress = function() {
	var _this = this;
	var str = "";

	if (_this.addressStr != "") {
		str = _this.addressStr;
	}
	else {
		str += _this.address.street;
		str += (str != "" ? (_this.address.street2 != "" ? ", "+ _this.address.street2 : "") : "");
		str += (str != "" ? (_this.address.zipcode != "" ? ", "+ _this.address.zipcode : "") : "");
		str += (str != "" ? (_this.address.city != "" ? ", "+ _this.address.city : "") : "");
		str += (str != "" ? (_this.address.area != "" ? ", "+ _this.address.area : "") : "");
		str += (str != "" ? (_this.address.region != "" ? ", "+ _this.address.region : "") : "");
		str += (str != "" ? (_this.address.state != "" ? ", "+ _this.address.state : "") : "");
		str += (str != "" ? (_this.address.country != "" ? ", "+ _this.address.country : "") : "");
	}

	return str;
}

googleMapPoint.prototype.getSearchAddress = function() {
	var _this = this;
	var str = "";

	if (_this.addressStr != "") {
		str = _this.addressStr;
	}
	else {
		str += _this.address.street;
		str += (str != "" ? (_this.address.street2 != "" ? ", "+ _this.address.street2 : "") : "");
		str += (str != "" ? (_this.address.zipcode != "" ? ", "+ _this.address.zipcode : "") : "");
		str += (str != "" ? (_this.address.city != "" ? ", "+ _this.address.city : "") : "");
	}
	return str;
}


googleMapPoint.prototype.completed = function() {
	var _this = this;
	return !_this.pointLoading;
}

googleMapPoint.prototype.setPoint = function(oPoint) {
	var _this = this;
	_this.pointLoading = false;
	_this.point = oPoint;
}

googleMapPoint.prototype.setAddress = function(strAddress) {
	var _this = this;
	_this.addressStr = strAddress;
}

googleMapPoint.prototype.findAddress = function() {
	var _this = this;

	if (oGeocoder != null) {
		_this.pointLoading = true;

		//Load by geographical coordinates:
		if ((_this.address.lat != "") && (_this.address.lng != "")) {
			_this.setPoint(new GLatLng(_this.address.lat, _this.address.lng, true));
		}

		//Attempt to find geographical coordinates by address string:
		else {

			if (_this.map != null) {
				if (_this.map.settings.enableGeocodeLookup) {
					oGeocoder.getLatLng(_this.getSearchAddress(), function(point) {
						if (!point) {
							//address not found
							_this.pointLoading = false;
						}
						else {
							_this.setPoint(point);
							_this.cachePoint();
						}
					});
				}
				else {
					_this.pointLoading = false;
				}
			}
			else {
				_this.pointLoading = false;
			}
		}
	}		
}
googleMapPoint.prototype.cachePoint = function() {
	//Default: no caching - depends on current implementation
}

window.onunload = GUnload;











function parseMapHousesXML(params, oXML) {
	if (oXML != null) {
		var oRoot = oXML.selectSingleNode("//houses");
		if (oRoot) {
			total = parseInt(oXML.getText(oRoot.selectSingleNode("@total")), 10);
			offset = parseInt(oXML.getText(oRoot.selectSingleNode("@first")), 10);
			count = parseInt(oXML.getText(oRoot.selectSingleNode("@count")), 10);

			var oHouseCount = document.getElementById("houseCount");
			if (oHouseCount) {
				oHouseCount.innerHTML = "<strong>"+ total +"</strong> feriehuse fundet";
			}

			var oHouses = oRoot.selectNodes("house");

			var mp = null;
			var oGeocode = null;
			var lat = "";
			var lng = "";
			var accuracy = 0;
			var oHouse = null;

			for (var i = 0; i < oHouses.length; i++) {
				oHouse = oHouses[i];
				oGeocode = oHouse.selectSingleNode("geocode");

				mp = oGM.createMapPoint();

				mp.data = {
					id : oXML.getText(oHouse.selectSingleNode("@id")),
					number: oXML.getText(oHouse.selectSingleNode("@number")),
					agency : oXML.getText(oHouse.selectSingleNode("@agency")),
					url : oXML.getText(oHouse.selectSingleNode("url")),
					price : parseFloat(oXML.getText(oHouse.selectSingleNode("price"))),
					currency : oXML.getText(oHouse.selectSingleNode("currency")),
					discount : parseFloat(oXML.getText(oHouse.selectSingleNode("discount"))),
					totalPrice : parseFloat(oXML.getText(oHouse.selectSingleNode("totalprice"))),
					arrival : oXML.getText(oHouse.selectSingleNode("arrival")),
					duration : oXML.getText(oHouse.selectSingleNode("duration")),
					capacity : oXML.getText(oHouse.selectSingleNode("capacity")),
					m2 : oXML.getText(oHouse.selectSingleNode("m2")),
					img : oXML.getText(oHouse.selectSingleNode("img"))
				};

				mp.icon = (mp.data.discount > 0 ? ICON_HOUSE_DISCOUNT : ICON_HOUSE);

				
			
				mp.address.street = oXML.getText(oHouse.selectSingleNode("address"));
				mp.address.area = oXML.getText(oHouse.selectSingleNode("area"));

				if (oGeocode != null) {
					lat = oXML.getText(oGeocode.selectSingleNode("@lat"));
					lng = oXML.getText(oGeocode.selectSingleNode("@lng"));
					accuracy = parseInt(oXML.getText(oGeocode.selectSingleNode("@accuracy")), 10);

					mp.address.lat = lat;
					mp.address.lng = lng;
					mp.accuracy = accuracy;

					mp.findAddress();
					oGM.addMapPoint(mp);
				}
				else {
					//geocode not found ...
				}
			}

			if (offset + count - 1 < total) {
				fetchMapHousesXML(params, Math.ceil(offset / 30) + 1); 
			}
			else {
				cXMLHttp = null;
				oGM.toggleLoading();
			}
		}
	}	
}


function fetchMapHousesXML(params, p) {
	var oXML = new XMLObject();
	var oXMLHttp = new XMLHttpRequestObject();
	oXMLHttp.src = "/site/custom/booking/houseSearchXML.asp";
	oXMLHttp.args = params + "&page=" + p;
	oXMLHttp.async = true;

	cXMLHttp = oXMLHttp;

	var waitObj = new waitForIt();
	waitObj.waitFor = function() {
		return oXMLHttp.completed();
	}
	waitObj.whenDone = function() {
		if (oXMLHttp.xml != null) {
			if (oXML.loadXML(oXMLHttp.xml)) {
				parseMapHousesXML(params, oXML);
			}
			else {
				//error in XML;
			}
		}
		else {
			//error in HTTP request
		}
	}

	oXMLHttp.load();
	waitObj.run();

}



function paramSelected(obj) {
	if (obj != null) {
		if (obj.type == "checkbox") {
			return obj.checked;
		}
		else {
			return (obj.value == "1");
		}
	}
	else {
		return false;
	}
}

function getHouseSearchParams() {
	var objForm = document.forms["booking_list_filter"];
	var objMode = objForm.mode;
	var objAproxy = objForm.aproxydate;
	var objStartdate = objForm.startdate;
	var objDuration = objForm.duration;
	var objVisitors = objForm.visitors;
	var objBedrooms = objForm.bedrooms;
	var objArea = objForm.area;

	var objPetsallowed = objForm.petsallowed;
	var objPool = objForm.pool;
	var objSpa = objForm.spa;
	var objSauna = objForm.sauna;
	var objStove = objForm.stove;
	var objWasher = objForm.washer;
	var objDryer = objForm.dryer;
	var objDishwasher = objForm.dishwasher;
	var objSeaview = objForm.seaview;

	var objDistBeach = objForm.distbeach;
	var objDistShop = objForm.distshop;
	var objDistRest = objForm.distrest;

	var params = "";
	params += "language_id=1";
	params += "&doc="+ window.location.pathname;
	params += (objMode != null ? "&mode=" + objMode.value : "");
	params += (objStartdate != null ? "&startdate=" + objStartdate.value : "");

	if (objAproxy != null) {
		if (objAproxy.type == "checkbox") {
			if (objAproxy.checked) {
				params += "&aproxydate=1";						
			}
		}
		else if (objAproxy.value == "1") {
			params += "&aproxydate=1";					
		}
	}

	
	params += (objDuration != null ? "&duration= "+ objDuration.value : "");
	params += (objVisitors != null ? "&visitors=" + objVisitors.value : "");
	params += (objBedrooms != null ? "&bedrooms=" + objBedrooms.value : "");
	params += (objArea != null ? "&area=" + objArea.value : "");


	params += (paramSelected(objPetsallowed) ? "&petsallowed=1" : "");
	params += (paramSelected(objPool) ? "&pool=1" : "");
	params += (paramSelected(objSpa) ? "&spa=1" : "");
	params += (paramSelected(objSauna) ? "&sauna=1" : "");
	params += (paramSelected(objStove) ? "&stove=1" : "");
	params += (paramSelected(objWasher) ? "&washer=1" : "");
	params += (paramSelected(objDryer) ? "&dryer=1" : "");
	params += (paramSelected(objDishwasher) ? "&dishwasher=1" : "");
	params += (paramSelected(objSeaview) ? "&seaview=1" : "");

	params += (objDistBeach != null ? "&distbeach=" + objDistBeach.value : "");
	params += (objDistShop != null ? "&distshop=" + objDistShop.value : "");
	params += (objDistRest != null ? "&distrest=" + objDistRest.value : "");

	return params;
}

function loadMapHouses() {
	fetchMapHousesXML(getHouseSearchParams(), 1);
}

function refreshMapHouses() {
	if (GBrowserIsCompatible()) {
		if (cXMLHttp != null) {
			cXMLHttp.abort();
			oGM.toggleLoading(0);
		}
		
		oGM.clearHouses();
		oGM.toggleLoading(1);
		loadMapHouses();
	}
}

var cXMLHttp = null;



function adjustMapSize(obj, refObj) {
	if ((obj != null) && (refObj != null)) {
		obj.style.height = refObj.offsetHeight +"px";	
	}
}







function TGVPoint(id, lat, lng, accuracy) {
	this.id = id;
	this.lat = lat;
	this.lng = lng;
	this.accuracy = accuracy;
}


function loadTGVPoints() {
	var mp = null;
	for (var i = 0; i < oTGVPoints.length; i++) {
		mp = oGM.createMapPoint();
		mp.id = oTGVPoints[i].id;
		mp.icon = ICON_DEFAULT; //B, C, D?
		mp.address.lat = oTGVPoints[i].lat;
		mp.address.lng = oTGVPoints[i].lng;
		mp.address.accuracy = oTGVPoints[i].accuracy;
		mp.findAddress();
		oGM.addTGVMapPoint(mp);
	}
	oGM.setTGVZoom();
	oGM.toggleLoading();
}


