
var searchexamplestr = "eg. Liverpool or SW19";
var savedlocation = {type:"uk", id:"", name:"", parent:"", lat:54, lng:-2, zoom:6};
var savedvalues = {minbeds: 0, maxbeds: 99, minprice: 0, maxprice: 10000, proptype: "", proxdistance: 0, proxmultiplier: 0.000568181818, proxtype: "", maptype: "Sales"};
var user = {id:0, username:"", firstname:"", loginhash:"", prefsearchtype:"place", enabletips:1, layers:"", mapoptions:1, panelsclosed:""};
var experience = {search:0, filter:0, zoom:0, sidebar:0, layers:0, bubble:0, shortlist:0, directory:0};
var blacklist = {};
var cliwidth;
var cliheight;
var setfiltertimer;
var limouseovertimer;
var filtersupdated = 0;
var sltitlebuffer = "";
var mailpropidbuffer = 0;
var sortableinprog = 0;
var currenttip = false;
var tips = new Array();
tips["rss"] = {title:"Subscribe to a feed",text:"<p>Using a program called a <strong>news reader</strong>, you can get updated property information from OnOneMap as soon as it comes in.  See our <a href=\"/about/rssinfo\">list of recommended news readers</a> or <a href=\"http://news.bbc.co.uk/1/hi/help/3223484.stm\">the BBC's guide to news feeds</a></p>"};
tips["search"] = {title:"Try searching for a place",text:"<p>Town, county, postcode, tube or train station, school, university campus, or even a motorway junction - we'll find it for you</p>",redisplaydelay:180000, lastshown:0};
tips["zoomcluster"] = {title:"You need to zoom in",text:"<p>There are too many properties to display <img src=\"/lib/img/logo_tiny.png\" width=\"50\" height=\"13\" /></p><p>Zoom in to see the properties, or click on one of the \"cluster\" labels to zoom in towards that cluster.</p>",redisplaydelay:90000, lastshown:0};
tips["zoom"] = {title:"You need to zoom in",text:"<p>There are too many properties to display <img src=\"/lib/img/logo_tiny.png\" width=\"50\" height=\"13\" />.</p><p>Zoom in to see the properties.</p>",redisplaydelay:90000, lastshown:0};
tips["filter"] = {title:"Set your requirements",text:"<p>Try clicking on these yellow buttons or the <strong>Change</strong> button at the end to set your property criteria.</p>",redisplaydelay:60000, lastshown:0};
tips["fewprops"] = {title:"Why can't I see all the properties?",text:"<p>Although we're able to show you some of the property for sale in this area, we can't show you all of it because some properties are too close together to represent on the map. In fact, some may actually be in exactly the same spot, perhaps because they are houses on opposite sides of the same street, or apartments in the same building.</p><p>To see the properties, zoom in - they'll then be able to separate and show up individually. When you're fully zoomed in you'll always see every property available for sale.</p>"};
tips["noprops"] = {title:"Why can't I see any properties?",text:"<p>There are lots of properties that match your criteria available for sale in the area covered by the map that you currently have on the screen. We can't let your computer download more than 300 properties at once because it may cause the site to slow down and become unusable.</p><p>Try zooming in or being more specific with your requirements</p><p>As soon as the number of potential properties is low enough, you'll start to see house icons on the map.</p>"};
tips["shortlistlink"] = {title:"Add it to your shortlist?",text:"<p>Keep all your favourite properties together on a shortlist. Click the <strong>Shortlist</strong> link in the property bubble to get started, then go here to see all your shortlisted properties.</p>",redisplaydelay:300000, lastshown:0};
tips["copysold"] = {title:"Sold property",text:"<p>Sold property data courtesy of Estate Angels.  OnOneMap displays a selection of recent sold property and links to further information on the Estate Angels website.</p><p>Some sold properties may be hidden if you have other markers on the map or if there are more than 40 sold properties in the map area displayed.</p>"};
tips["copymast"] = {title:"Mobile phone masts",text:"<p>&copy; Ofcom.  Information reproduced accurately and in context from the Mobile Phone Base Station Database and with adherence to the spirit of the Freedom of Information Act 2000. OnOneMap displays the mast information as per the aforementioned database as of December 2006. The network operators supply Ofcom with updates from time to time. This means that there is sometimes a time lag between sites being developed and the availability of the data, and Ofcom, and therefore OnOneMap, cannot accept liability for any inaccuracies or omissions in the data thus provided, or its currency.</p><p>Some masts may be hidden by other information you select to plot on the map or if there are more than 40 transmitters in the map area displayed.</p>"};
tips["copyschool"] = {title:"Schools",text:"<p>&copy; 2007 Crown Copyright.  Information reproduced from the Department for Education and Skills.  OnOneMap displays all secondary schools, with academic results from 2006.</p><p>Some schools may be hidden if you have other markers on the map or if there are more than 40 schools in the map area displayed.</p>"};
tips["copysuperm"] = {title:"Supermarkets",text:"<p>OnOneMap displays all supermarkets belonging to Tesco, Asda, Sainsbury's and Morrisons.</p><p>Some supermarkets may be hidden if you have other markers on the map or if there are more than 40 locations in the map area displayed.</p>"};
tips["copyflood"] = {title:"Flood map removed",text:"<p>The Environment Agency has directed us to withdraw our flood map layer as they claim, amongst other things, copyright over the data. See what we think of this <a href=\"http://www.ononeblog.com/?p=28\">on our blog</a>. To access flood information in the meantime, visit the <a href=\"http://www.environment.gov.uk\">Environment Agency's maps</a>."};
tips["copysupermarket"] = {title:"Supermarkets",text:"<p>OnOneMap displays the locations of supermarkets owned by Tesco, Sainsbury's, Morrisons, Asda, Somerfield and Waitrose.  Data reproduced with permission from the supermarkets.</p>"};
tips["rssnotloaded"] = {title:"No RSS available yet",text:"<p>The map has not yet fully loaded so there is no news feed available for this view yet.  Wait a few seconds and this should disappear...</p>"};
tips["login"] = {title:"Login or register",text:"<p>Enter the email address you registered with to login.  Haven't registered yet?  Enter your email address to start the free and simple registration process.</p>"};

function cmnInit() {
	cmnResize();

	// REVIEW:RB Intending to create a global AJAX timeout.  Needs work
	//$.ajaxSetup({timeout: 30000, error: function(ajaxObj, errorType, exception) { ajaxError(ajaxObj, errorType, exception) }});

	var newloc = readCookie("oomlocateresult");
	if (newloc) {
		var data = $.parseJSON(newloc);
		eraseCookie("oomlocateresult");
		showNewLocNotification(data);
	}
	if (window.attachEvent) { 
		window.attachEvent("onresize", cmnResize);
	} else {
		window.addEventListener("resize", cmnResize, false);
	}

	initMouseoverButtons();

	setTimeout(tipJar, 30000);
	setInterval(tipJar, 60000);
}

function initMouseoverButtons() {
	$("li.sl").mouseover(function() {
		if (limouseovertimer) clearTimeout(limouseovertimer);
		var f = mouseoverButtons("shortlist", this);
		limouseovertimer = setTimeout(f, 1);
	});
	$("li.prop").mouseover(function() {
		if (limouseovertimer) clearTimeout(limouseovertimer);
		var f = mouseoverButtons("directory", this);
		limouseovertimer = setTimeout(f, 1);
	});
}
function mouseoverButtons(type, obj) {
	return (function() {
		var id = $(obj).attr("id").replace(/[^0-9]/g, "");
		if (type=="shortlist" && $("div.shortlistbuttons", obj).length == 0 && sortableinprog==0) {
			$("div.shortlistbuttons").remove();
			$(obj).prepend("<div class=\"shortlistbuttons slb_sl\"><a href=\"javascript:void(0);\" onclick=\"slEditTitle(this);\" class=\"edit\" title=\"Edit title\"><span>Edit title</span></a><a href=\"javascript:void(0);\" onclick=\"slAddNote(this)\" class=\"note\" title=\"Add a note\"><span>Add note</span></a><a href=\"javascript:void(0);\" onclick=\"slRemove(this)\" class=\"del\" title=\"Delete this property from your shortlist\"><span>Delete property</span></a><a href=\"javascript:void(0);\" onclick=\"openMail(this);\" class=\"mail\" title=\"Send to a friend\"><span>Send to a friend</span></a><a href=\"/map/?id="+id+"\" class=\"map\" title=\"Display on the map\"><span>Display on the map</span></a><br /><a href=\"javascript:void(0)\" onclick=\"slMoveUp(this)\" class=\"moveup\" title=\"Move up\"><span>Move up</span></a><br /><a href=\"javascript:void(0)\" onclick=\"slMoveDown(this)\" class=\"movedown\" title=\"Move down\"><span>Move down</span></a></div>");
		} else if (type=="directory" && $("div.shortlistbuttons", obj).length == 0) {
			$("div.shortlistbuttons").remove();
			$(obj).prepend("<div class=\"shortlistbuttons slb_dir\"><a href=\"javascript:void(0);\" onclick=\"addShortlist(0, this, 'dir');\" class=\"add\" title=\"Add to shortlist\"><span>Add to shortlist</span></a><a href=\"javascript:void(0);\" onclick=\"openMail(this);\" class=\"mail\" title=\"Send to a friend\"><span>Send to a friend</span></a><a href=\"javascript:void(0);\" onclick=\"toggleBlacklist(this, 'dir');\" class=\"bl\" title=\"Blacklist this property, making it less visible\"><span>Blacklist</span></a><a href=\"javascript:void(0);\" onclick=\"toggleBlacklist(this, 'dir');\" class=\"ubl\" title=\"Restore this property to its former glory!\"><span>Remove from blacklist</span></a><a href=\"/map/?id="+id+"\" class=\"map\" title=\"Display on the map\"><span>Display on the map</span></a></div>");
		}
	});
}

function cmnResize() {
	if (document.body.clientHeight) {
		cliheight = document.body.clientHeight;
		cliwidth = document.body.clientWidth;
	} else {
		cliheight = window.innerHeight;
		cliwidth = window.innerWidth;
	}
	if (typeof(map) != "undefined") {
		mapResize();
	}
}

function setLoc(locstr) {
	closeTip("search");
	$("#disambig").remove();
	$("#newlocnotifier").animate({right: -(cliwidth-270)}, 200, "easeout", function() { $("#newlocnotifier").remove();});
	if (!locstr.length) locstr = $("#txtlocation").val();
	if (!locstr.length || locstr.indexOf("eg.") != -1) {
		alert("Please enter a location");
		$("#txtlocation").get(0).focus();
	} else {
		$("#txtlocation").get(0).blur();
		var url = "/lib/ajx/locset?s="+encodeURIComponent(locstr);
		$("#btnsearch").get(0).disabled = true;
		$.getJSON(url, function(response) {
			$("#btnsearch").get(0).disabled = false;
			if (response.msg) {
				alert(response.msg);
				$("#txtlocation").get(0).select();
			} else if (response.type) {
				experience = response.experience;
				if (location.pathname.indexOf("/directory") == 0 || location.pathname.indexOf("/about") == 0 || location.pathname.indexOf("/shortlist") == 0) {
					createCookie("oomlocateresult", $.toJSON(response));
					location.href = response.dirlink;
				} else {
					savedlocation = response;
					$("#location").html(decodeURIComponent(savedlocation.loclinks));
				$("#btnsearch").get(0).disabled = false;
					showNewLocNotification(response);
					if (!isNaN(response.numresults)) {
						delete savedlocation.numresults;
						delete savedlocation.locations;
					}
					setTimeout('mapSyncLocation()', 700);
				}
			}
		});
	}
}

function showNewLocNotification(locobj) {
	if (!isNaN(locobj.numresults)) {
		var dishtml = "<strong>Did you mean:</strong> <span class=\"links\">";
		for (var i=0; i<locobj.locations.length; i++) {
			dishtml += " <a href=\"javascript:setLoc('"+locobj.locations[i].locstr+"')\">" + decodeURIComponent(locobj.locations[i].fullname) + "</a>";
		}
		dishtml += "</span><p class=\"cancel\"><a href=\"javascript:closeNewLocNotifier()\">Close</a></p>";
	}
	$("#newlocnotifier").remove();
	$("<div id=\"newlocnotifier\"><span>Displaying "+decodeURIComponent(locobj.fullname)+"</span></div>").appendTo($(document.body)).css("width", (cliwidth-270)+"px").css("right", "-"+(cliwidth-270)+"px").animate({right: 10}, 500, "easeout", function() { $("#disambig").css("top", ($("#newlocnotifier").height())); $("#disambig").slideDown(600); } );
	$("#disambig").css("top", ($("#newlocnotifier").height())).show();
	if (!isNaN(locobj.numresults)) $("<div id=\"disambig\"><div>"+dishtml+"</div></div>").appendTo($("#newlocnotifier"));
	setTimeout("closeNewLocNotifier()", 8000);
}

function closeNewLocNotifier() {
	if ($("#disambig").length) $("#disambig").animate({height: 0}, 500, "easeout", function() { $("#disambig").remove(); $("#newlocnotifier").animate({right: -(cliwidth-270)}, 600, "easeout", function() { $("#newlocnotifier").remove();})});
	else $("#newlocnotifier").animate({right: -(cliwidth-270)}, 600, "easeout", function() { $("#newlocnotifier").remove();});

}

function searchFocus() {
	$("#txtlocation").css("color", "black");
	$("#txtlocation").val("");
}
function searchBlur() {
	if (!$("#txtlocation").val()) $("#txtlocation").css("color", "#888").val(searchexamplestr);
}

function updateFilters() {
	if (filtersupdated == 1) {
		if (location.pathname.indexOf("/directory") == 0) {
			location.href = "/directory/";
		} else if (location.pathname.indexOf("/about") != 0) {
			if (typeof(mapNewFilters) == "function") {
				mapNewFilters();
			}
			filtersupdated = 0;
		}
	}
}
function setFilters() {
	closeTip("filter");
	closeFilterSelect();
	centreDialog($("#dlgfilter"));
	showOverlay();
	$("#lnkchangefilters").TransferTo({to:'dlgfilter',className:'transferer1',duration:400,complete:function(to) { $(to).css('visibility', 'visible') }});
}
function closeFilters() {
	closeFilterSelect();
	if ($("#txtloginemail").val()) {

	}
	$("#dlgfilter").css('visibility', 'hidden').TransferTo({to:'lnkchangefilters',className:'transferer1',duration:400,complete:updateFilters});
	$("#overlay").remove();
}
function changeFilter(filname, mode) {
	closeTip("filter");
	closeFilterSelect();
	clearTimeout(setfiltertimer);
	if (mode == "bar") {
		$("#filbar"+filname).css("border-color", "black").get(0).blur();
		var offsets = $("#filbar"+filname).offset("body");
	} else {
		$("#fil"+filname).css("border-color", "black").get(0).blur();
		var offsets = $("#fil"+filname).offset("body");
	}
	if ($("#filselect_"+filname).outerWidth() < offsets.width) $("#filselect_"+filname).css("width", (offsets.width-2)+"px");
	var toppx = offsets.top + offsets.height - 2;
	var leftpx = (((2*offsets.left)+offsets.width-$("#filselect_"+filname).outerWidth()) / 2) - 1;
	if (leftpx + $("#filselect_"+filname).outerWidth() > cliwidth) leftpx = cliwidth - $("#filselect_"+filname).outerWidth() - 10;
	if (filname == "price") {
		$("#txtminprice").val(savedvalues.minprice);
		$("#txtmaxprice").val(savedvalues.maxprice);
		$("span.typespecific").css("display", "none");
		$("span.ts"+savedvalues.maptype).css("display", "inline");
	} else if (filname == "numbeds") {
		$("#selminbeds").val(savedvalues.minbeds);
		$("#selmaxbeds").val(savedvalues.maxbeds);
	} else if (filname == "prox") {
		$("#txtproxdistance").val(savedvalues.proxdistance);
		$("#selproxmultiplier").val(savedvalues.proxmultiplier);
		$("#selproxtype").val(savedvalues.proxtype);
	}
	$("#filselect_"+filname).css('top', toppx+"px").css('left', leftpx+'px').css('visibility','visible');
}
function closeFilterSelect() {
	$("a.filter").css("border-color", "#FFFFCC");
	$("p.filterlinks a").css("border-color", "#FFFFCC");
	$("div.filselect").css('visibility', 'hidden');
	if (filtersupdated == 1) {
		clearTimeout(setfiltertimer);
		setfiltertimer = setTimeout("updateFilters()", 2000);
	}
}
function selectFilter(filname, newvalue) {
	var url = "/lib/ajx/setfil?fil="+filname;
	if (filname=="maptype") {
		url += "&new="+newvalue;
	} else if (filname=="proptype") {
		url += "&new="+newvalue;
	} else if (filname=="numbeds") {
		var min = parseInt((isNaN($("#selminbeds").val())) ? 0 : $("#selminbeds").val());
		var max = parseInt((isNaN($("#selmaxbeds").val())) ? 0 : $("#selmaxbeds").val());
		if (min > max) {
			alert("It is not possible to set your minimum number of bedrooms higher than the maximum - please try again!");
			url = "";
		} else {
			url += "&min="+min+"&max="+max;
		}
	} else if (filname=="price") {
		var min = parseInt((isNaN($("#txtminprice").val())) ? 0 : $("#txtminprice").val());
		var max = parseInt((isNaN($("#txtmaxprice").val())) ? 0 : $("#txtmaxprice").val());
		if (min > max) {
			alert("It is not possible to set your minimum price higher than the maximum - please try again!");
			url = "";
		} else if (min > 100000 || max > 100000) {
			alert("You've entered prices of more than a hundred million pounds.  Either you're a very wealthy individual or you've entered three too many zeros.  If you need to change the filter, just click the price again!");
		}
		url += "&min="+min+"&max="+max;
	} else if (filname=="prox") {
		var pd = $("#txtproxdistance").val();
		var pm = $("#selproxmultiplier").val();
		var pt = $("#selproxtype").val();
		url += "&pd="+pd+"&pm="+pm+"&pt="+pt;
	}
	if (url.length > 0) {
		$("#filselect_"+filname).css('visibility', 'hidden');
		$.getJSON(url, function(response) {
			processFilterResponse(response, filname, true);
		});
	}
}
function processFilterResponse(response, filname, updatemap) {
	if (response.msg) {
		alert(response.msg);
	} else {
		filtersupdated = 1;
		experience = response.experience;
		$("#fil"+filname).css("border-color", "#FFFFCC").html(decodeURIComponent(response.linktext));
		$("#filbar"+filname).css("border-color", "#FFFFCC").html(decodeURIComponent(response.bartext));
		if (filname != "price") {
			$("#filprice").css("border-color", "#FFFFCC").html(decodeURIComponent(response.pricelink));
			$("#filbarprice").css("border-color", "#FFFFCC").html(decodeURIComponent(response.pricebar));
		}
		if (filname == "maptype") {
			if (response.newfilters.maptype == "Rentals") $("#layersproplabel").html("<img alt=\"Properties for rent\" src=\"/lib/img/markers/house2.png\"/>Properties for rent");
			else $("#layersproplabel").html("<img alt=\"Properties for sale\" src=\"/lib/img/markers/house.png\"/>Properties for sale");
		}
		savedvalues = response.newfilters;
		if (updatemap && $("#dlgfilter").css("visibility") != "visible") {
			clearTimeout(setfiltertimer);
			setfiltertimer = setTimeout("updateFilters()", 2000);
		}
	}
}
function centreDialog(jqo) {
	jqo.css("left", ((cliwidth-jqo.outerWidth())/2)+"px").css("top", ($(document).scrollTop()+((cliheight-jqo.outerHeight())/3))+"px");
}
function showOverlay() {
	$("<div id='overlay'></div>").appendTo("body").css("height", $(document).height()+"px");
}

function showTip(tipname, obj, direction, offsetx, offsety) {
	var d = new Date();
	if (isNaN(tips[tipname].redisplaydelay) ||  tips[tipname].lastshown+tips[tipname].redisplaydelay < d.getTime()) {
		closeTip();
		$("<div id=\"tip\"><div class=\"tip_top\"><div class=\"tip_tl\"></div><div class=\"tip_tr\"></div><div class=\"tip_tm\"></div></div><div class=\"tip_content\"><h3>"+tips[tipname].title+"</h3>"+tips[tipname].text+"</div><div class=\"tip_btm\"><div class=\"tip_bl\"></div><div class=\"tip_br\"></div><div class=\"tip_bm\"></div></div><div class=\"tip_arrow\"></div><a class=\"close\" href=\"javascript:closeTip()\"><img src=\"/lib/img/closewindowbtn2.png\" width=\"14\" height=\"14\" /></a></div>").appendTo(document.body).click(closeTip);
		var boxwidth = $("#tip").outerWidth();
		var boxheight = $("#tip").outerHeight();
		var objoffset = $(obj).offset();
		if (isNaN(offsetx) && isNaN(offsety)) {
			var objwidth = $(obj).outerWidth();
			var objheight = $(obj).outerHeight();
			var objleft = objoffset.left;
			var objtop = objoffset.top;
		} else {
			var objwidth = 1;
			var objheight = 1;
			var objleft = objoffset.left + offsetx;
			var objtop = objoffset.top + offsety;
		}

		if (direction == "down") {
			var arrwidth = 50; var arrheight = 47;
			var wfactor = objleft/(cliwidth-objwidth);
			$("#tip").css({top:(objtop-arrheight-boxheight)+"px",left:((cliwidth-boxwidth)*wfactor)+"px"});
			$("#tip .tip_arrow").addClass("down").css({top:(boxheight-1)+"px", left:((objleft-((cliwidth-boxwidth)*wfactor))+(objwidth/2)-(arrwidth/2))+"px"});
		} else if (direction == "up") {
			var arrwidth = 50; var arrheight = 47;
			var wfactor = objleft/(cliwidth-objwidth);
			$("#tip").css({top:(objtop+objheight+arrheight)+"px",left:((cliwidth-boxwidth)*wfactor)+"px"});
			$("#tip .tip_arrow").addClass("up").css({top:(1-arrheight)+"px", left:((objleft-((cliwidth-boxwidth)*wfactor))+(objwidth/2)-(arrwidth/2))+"px"});
		} else if (direction == "left") {
			var arrwidth = 47; var arrheight = 50;
			var hfactor = objtop/(cliheight-objheight);
			$("#tip").css({top:((cliheight-boxheight)*hfactor)+"px",left:(objleft+objwidth+arrwidth)+"px"});
			$("#tip .tip_arrow").addClass("left").css({top:((objtop-((cliheight-boxheight)*hfactor))+(objheight/2)-(arrheight/2))+"px", left:(1-arrwidth)+"px"});
		} else if (direction == "right") {
			var arrwidth = 47; var arrheight = 50;
			var hfactor = objtop/(cliheight-objheight);
			$("#tip").css({top:((cliheight-boxheight)*hfactor)+"px",left:(objleft-boxwidth-arrwidth)+"px"});
			$("#tip .tip_arrow").addClass("right").css({top:((objtop-((cliheight-boxheight)*hfactor))+(objheight/2)-(arrheight/2))+"px", left:(boxwidth-1)+"px"});
		}
		$("#tip").css("visibility", "visible");
		$(obj).get(0).blur();
		currenttip = tipname;
		tips[tipname].lastshown = d.getTime();
	};
}
function closeTip(tipname) {
	if (!tipname || currenttip == tipname) {
		currenttip = false;
		$("#tip").remove();
	}
}
function tipJar() {
	if (user.enabletips == 1 && !currenttip) {
		if ($("div.propdesc").length > 0 && experience.bubble > 2 && experience.shortlist < 1) {
			showTip("shortlistlink", $("#mainnav").get(0), "up", 270, 20);
		} else if (experience.search < 1 && savedlocation.type=="uk") {
			showTip("search", $("#txtlocation").get(0), "up");
		} else if (experience.filter < 1 && $("#disambig").length==0) {
			showTip("filter", $("#filbarprice").get(0), "up");
		}
	}
}
function addShortlist(propid, sourceobj, mode) {
	closeTip("shortlistlink");
	if (mode=="dir") {
		while(sourceobj.tagName != "LI") sourceobj = sourceobj.parentNode;
		propid = $(sourceobj).attr("id");
	} else {
		var uuid = false;
		if (markers["saleprop"+propid]) uuid = "saleprop"+propid;
		if (markers["rentalprop"+propid]) uuid = "rentalprop"+propid;
		if (uuid && markers[uuid].obj) {
			map.removeOverlay(markers[uuid].obj);
			var marker = markers[uuid];
			marker.t = "fave"+marker.t;
			markers["fave"+uuid] = marker;
			delete(markers[uuid]);
			mapCreateMarker("fave"+uuid);
			map.addOverlay(markers["fave"+uuid].obj);
		}
	}
	$.getJSON("/lib/ajx/shortlistadd?id="+propid, function(response) {
		if (response.msg) {
			alert(decodeURIComponent(response.msg));
		} else {
			$(sourceobj).TransferTo({to:'mnushortlist',className:'transferer2',duration:800,complete:function(to) { $(to).Highlight(1500, "#FF9900"); }});
			experience = response.experience;
			if (mode != "dir") {
				$("#lnkmapblacklprop/..").css("display", "none");			
				if (!$("#sllink"+propid).length) {
					if ($("#sbslnone").css("display") != "none") {
						$("#sbslnone").slideUp(200);
						$("#sbslsome").slideDown(200);
					}
					$("<li style=\"display: none;\"><a id=\"sllink"+propid+"\" href=\"javascript:moveToProp("+propid+")\">"+decodeURIComponent(response.title)+"</a></li>").appendTo("#sidebarsl").show(300);
					$("#sbslcount").html($("#sidebarsl li").length);
					$("#sbslwordend").html(($("#sidebarsl li").length == 1)?"y":"ies");
				}
			} else {
				$("#"+propid).addClass("favprop");
				$("div.shortlistbuttons").remove();
			}
		}
	});
}
function moveToProp(propid, e) {
	var e = ((window.event)?window.event:e);
	if (e) {
		var ele = ((e.target)?e.target:e.srcElement);
		if ($(ele).get(0).length) $(ele).get(0).blur();
	}
	var uuid = false;
	var prepends = ["favesaleprop", "saleprop", "faverentalprop", "rentalprop"];

	// First see if the property is onscreen and show it directly if so
	for (var i in prepends) {
		if (markers[prepends[i]+propid]) uuid = prepends[i]+propid;
	}
	if (uuid) {
		if (!markers[uuid].obj) {
			mapCreateMarker(uuid);
			map.addOverlay(markers[uuid].obj);
		}
		mapMarkerClick(markers[uuid]);
		return;
	}
	
	// If not, request the location and filters.  Check to change filters if
	// it would not be displayed, then finally pan and zoom.
	$.getJSON("/lib/ajx/movetoprop/"+propid, function(response) {
		if (response.msg) {
			alert(decodeURIComponent(response.msg));
		} else {
			var filterstochange = new Array();
			var filchanges = 0;
			if (response.maptype != savedvalues.maptype) filterstochange["maptype"] = "new="+response.maptype;
			if (response.maptype == "Sales") response.price = response.price/1000;
			if (response.price < savedvalues.minprice) filterstochange["price"] = "min="+Math.floor(response.price)+"&max="+savedvalues.maxprice;
			if (response.price > savedvalues.maxprice) filterstochange["price"] = "min="+savedvalues.minprice+"&max="+Math.ceil(response.price);
			if (response.numbeds < savedvalues.minbeds) filterstochange["numbeds"] = "min="+response.numbeds+"&max="+savedvalues.maxbeds;
			if (response.numbeds > savedvalues.maxbeds) {
				if (response.numbeds > 5) filterstochange["numbeds"] = "min="+savedvalues.minbeds+"&max=99";
				else filterstochange["numbeds"] = "min="+savedvalues.minbeds+"&max="+response.numbeds;
			}
			if (savedvalues.proptype && savedvalues.proptype != response.proptype) filterstochange["proptype"] = "new=";
			if (savedvalues.proxtype) {
				if ((savedvalues.proxtype == "tube") && ((savedvalues.proxdistance*savedvalues.proxmultiplier)<response.milestotube)) {
					if ((savedvalues.proxdistance*savedvalues.proxmultiplier*3)>response.milestotube) filterstochange["prox"] = "pd="+Math.ceil(response.milestotube/savedvalues.proxmultiplier)+"&pm="+savedvalues.proxmultiplier+"&pt=tube";
					else filterstochange["prox"] = "pd="+savedvalues.proxdistance+"&pm="+savedvalues.proxmultiplier+"&pt=";
				}
				if ((savedvalues.proxtype == "train") && ((savedvalues.proxdistance*savedvalues.proxmultiplier)<response.milestotrain)) {
					if ((savedvalues.proxdistance*savedvalues.proxmultiplier*3)>response.milestotrain) filterstochange["prox"] = "pd="+Math.ceil(response.milestotrain/savedvalues.proxmultiplier)+"&pm="+savedvalues.proxmultiplier+"&pt=train";
					else filterstochange["prox"] = "pd="+savedvalues.proxdistance+"&pm="+savedvalues.proxmultiplier+"&pt=";
				}
				if ((savedvalues.proxtype == "moto") && ((savedvalues.proxdistance*savedvalues.proxmultiplier)<response.milestomotorway)) {
					if ((savedvalues.proxdistance*savedvalues.proxmultiplier*3)>response.milestomotorway) filterstochange["prox"] = "pd="+Math.ceil(response.milestomotorway/savedvalues.proxmultiplier)+"&pm="+savedvalues.proxmultiplier+"&pt=moto";
					else filterstochange["prox"] = "pd="+savedvalues.proxdistance+"&pm="+savedvalues.proxmultiplier+"&pt=";
				}
			}
			for (var i in filterstochange) if (i != "indexOf") filchanges++;
			if (filchanges) {
				if (confirm("That property is excluded by your current filters.  Extend your filters automatically to include the property?")) {
					var func = moveToPropSetFilters(filterstochange, propid, response.lat, response.lng);
					setTimeout(func, 25);
				}
			} else {
				doMoveToProp(propid, response.lat, response.lng);
			}
		}
	});
}
function moveToPropSetFilters(filterstochange, propid, lat, lng) {
	return (function() {
		var filchanges = 0;
		var filter = false;
		for (var i in filterstochange) {
			if (i == "indexOf") continue;
			if (!filter) filter = i;
			filchanges++;
		}
		if (!filter || !filchanges) {
			doMoveToProp(propid, lat, lng);
			return;
		}
		$.getJSON("/lib/ajx/setfil?fil="+filter+"&"+filterstochange[filter], function(response) {
			processFilterResponse(response, filter, false);
			delete(filterstochange[filter]);
			if (filchanges == 1) doMoveToProp(propid, lat, lng);
			else {
				var func = moveToPropSetFilters(filterstochange, propid, lat, lng);
				setTimeout(func, 25);
			}
		});	
	});
}
function doMoveToProp(propid, lat, lng) {
	autodisplay = propid;
	firstplot = 0;
	if (map.getZoom() == 17) {
		var bounds = map.getBounds();
		var vdist = Math.abs((bounds.getNorthEast().lat() - bounds.getSouthWest().lat()) / 2);
		var hdist = Math.abs((bounds.getNorthEast().lng() - bounds.getSouthWest().lng()) / 2);
		var percentmoved_vertically = Math.abs((bounds.getSouthWest().lat() - (lat-vdist)) / (bounds.getNorthEast().lat()-bounds.getSouthWest().lat()));
		var percentmoved_horizontally = Math.abs((bounds.getSouthWest().lng() - (lng-hdist)) / (bounds.getNorthEast().lng()-bounds.getSouthWest().lng()));
		if (percentmoved_vertically < 0.02 && percentmoved_horizontally < 0.02) mapLoadMarkers();
	} else {
		map.setZoom(17);
	}
	map.panTo(new GLatLng(lat, lng));
}
function slEditTitle(li) {
	while(li.tagName != "LI") li = li.parentNode;
	if ($("#frmsltitle").length != 0) slSetTitle($("#frmsltitle").get(0));
	sltitlebuffer = $("p.title", li).html();
	$("p.title", li).html("<form id=\"frmsltitle\" onsubmit=\"slSetTitle(this); return false;\"><input type=\"text\" id=\"txtsltitle\" value=\""+$("p.title strong", li).html()+"\" /> <a href=\"javascript:void(0)\" onclick=\"slSetTitle(this)\" class=\"btnlink btnok\"><span>OK</span></a></form>");
	setTimeout("$('#txtsltitle').get(0).select();", 10);
}
function slSetTitle(li) {
	while(li.tagName != "LI") li = li.parentNode;
	var newtitle = $("#txtsltitle").val();
	$("p.title", li).html(sltitlebuffer);
	sltitlebuffer = "";
	if (newtitle.length > 0 && newtitle != $("p.title strong", li).html()) {
		$("p.title strong", li).html(newtitle);
		$.get("/lib/ajx/shortlistedittitle?id="+$(li).attr("id")+"&newtitle="+encodeURIComponent(newtitle));
	}
}
function slRemove(li) {
	while(li.tagName != "LI") li = li.parentNode;
	if (confirm("Are you sure you want to remove '"+$("p.title strong", li).html()+"' from your shortlist?")) {
		$.get("/lib/ajx/shortlistremove?id="+$(li).attr("id"));
		$(li).css("background-color", "#FFC4C4").slideUp(300, function() { 
			$(this).remove();
			var cnt = $("li.sl").length;
			if (cnt == 0) {
				location.reload();
			} else {
				var newtext = ((cnt==1)?"There is one property":"There are "+cnt+" properties")+" in your shortlist";
				$("h2").html(newtext);
			}
		});
	}
}
function slAddNote(li) {
	if (isNaN(user.id) || user.id < 1) {
		alert("You must login or register if you want to save notes on your shortlist.\n\nThis is a great idea, because you can then use your shortlist to remember important details that you find out about the property, like service charge, local facilities, refurbishment ideas, or what friends and family thought.\n\nTo register or login, use the form on the right of this page!");
		return false;
	}
	while(li.tagName != "LI") li = li.parentNode;
	if ($("#frmslnote").length != 0) slCancelNote($("#frmslnote").get(0));
	$(li).append("<form id=\"frmslnote\" onsubmit=\"slSetNote(this); return false;\"><textarea id=\"txtslnote\" rows=\"3\" cols=\"25\">Type your notes here</textarea><div class=\"buttonarea\"><div class=\"buttons\"><a href=\"javascript:void(0)\" onclick=\"slSetNote(this)\" class=\"btnlink btnok\"><span>OK</span></a> <a href=\"javascript:void(0)\" onclick=\"slCancelNote(this)\" class=\"btnlink btncancel\"><span>Cancel</span></a></div></div></form>");
	$("#txtslnote").get(0).select();
}
function slCancelNote() {
	$("#frmslnote").remove();
}
function slSetNote(li) {
	while(li.tagName != "LI") li = li.parentNode;
	var note = $("#txtslnote").val();
	$("#frmslnote").remove();
	if (note.length > 0 && note != "Type your notes here") {
		$.post("/lib/ajx/shortlistaddnote", {id:$(li).attr("id"),note:note}, function(html) {
			html = decodeURIComponent(html);
			if (html.substr(0,1)=="<") {
				$(li).append(html);
			} else {
				alert(html);
			}
		});
	}
}
function slDelNote(noteobj, noteid) {
	while(noteobj.tagName != "P") noteobj = noteobj.parentNode;
	$(noteobj).css("background-color", "#FFC4C4");
	if (confirm('Are you sure you want to remove this note?')) {
		$(noteobj).remove();
		$.get("/lib/ajx/shortlistdelnote?id="+noteid);
	} else {
		$(noteobj).css("background-color", "#f0f0f0");
	}
}
function slMoveUp(li) {
	while(li.tagName != "LI") li = li.parentNode;
	var li = $(li);
	var prevli = li.prev();
	var id = li.attr("id");
	if (prevli.length > 0) {
		var buf = li.html();
		$(li).remove();
		prevli.before("<li class=\"sl\" id=\""+id+"\">"+buf+"</li>");
		$.get("/lib/ajx/shortlistmove?id="+id+"&dir=up");
		initMouseoverButtons();
	}
}
function slMoveDown(li) {
	while(li.tagName != "LI") li = li.parentNode;
	var li = $(li);
	var nextli = li.next();
	var id = li.attr("id");
	if (nextli.length > 0) {
		var buf = li.html();
		$(li).remove();
		nextli.after("<li class=\"sl\" id=\""+id+"\">"+buf+"</li>");
		$.get("/lib/ajx/shortlistmove?id="+id+"&dir=down");
		initMouseoverButtons();
	}
}
function checkLogin() {
	$("#grplogin1").css("visibility", "hidden");
	$.get("/lib/ajx/logincheck?u="+encodeURIComponent($("#txtloginemail").val()), function(response) {
		if (response == "KNOWN") {
			$("#grplogin1").css("display", "none");
			$("#grplogin2").css("display", "block");
			$("#returninguser").html($("#txtloginemail").val());
			$("#txtloginpassword").width($("#contextualinfo").outerWidth() - 190).get(0).focus();
			if ($("#txtloginpassword").outerWidth() < 100) $("#txtloginpassword").width(100);
		} else if (response == "UNKNOWN") {
			$("#grplogin1").css("display", "none");
			$("#grplogin3").css("display", "block");
			$("#txtfirstname").get(0).focus();
		} else {
			alert(response);
			$("#grplogin1").css("visibility", "visible");
			$("#txtloginemail").get(0).focus();
		}
	});
}
function doRegister() {
	$("#grplogin2").css("visibility", "hidden");
	$.post("/lib/ajx/loginregister", {u:$("#txtloginemail").val(), p:$("#txtpassword").val(), n:$("#txtfirstname").val()}, function(response) {
		if (response == "OK") {
			location.reload();
		} else {
			alert(response);
			$("#grplogin2").css("visibility", "visible");
			$("#txtfirstname").get(0).focus();
		}
	});
}
function cancelRegister() {
	$("#grplogin1").css("display", "block").css("visibility", "visible");
	$("#grplogin2").css("display", "none");
	$("#grplogin3").css("display", "none");
}
function cancelLogin() {
	$("#grplogin2").css("display", "none");
	$("#grplogin1").css("display", "block").css("visibility", "visible");
}
function doLogin() {
	$("#grplogin3").css("visibility", "hidden");
	$.post("/lib/ajx/login", {u:$("#txtloginemail").val(), p:$("#txtloginpassword").val()}, function(response) {
		if (response == "OK") {
			location.reload();
		} else {
			alert(response);
			$("#txtloginpassword").get(0).focus();
		}
	});
}
function dirShowSources(id) {
	$("#sourcelinks"+id).css("display", "block");
	$.getJSON("/lib/ajx/sourcelinks/"+id, function(response) {
		$("#sourcelinks"+id).html(decodeURIComponent(response.sourcelist));
	});
}
function openMail(liorid) {
	if (isNaN(liorid)) {
		while(liorid.tagName != "LI") liorid = liorid.parentNode;
		mailpropidbuffer = $(liorid).attr("id");
		title = $("p.title strong", liorid).html();
	} else {
		mailpropidbuffer = liorid;
		title = $("div.propdesc strong").html();
	}
	centreDialog($("#dlgmaillayer"));
	showOverlay();
	$("#emlpropname").html(title);
	$("#dlgmaillayer").css("visibility", "visible").fadeIn(500, function() {
		if (user.id > 0) {
			if ($("#txtuname").val().length == 0) {
				$("#txtuname").val(user.firstname);
				$("#txtuemail").val(user.username);
			}
			if ($("#txtfname").val().length > 0) {
				$("#txtmsg").get(0).focus();
			} else {
				$("#txtfname").get(0).focus();
			}
		} else {
			$("#txtuname").get(0).focus();
		}
	});
}
function sendMail() {
	$("#grpmail1").css("display", "none");
	$("#grpmail2").css("display", "block");
	$.post("/lib/ajx/email", {uname:$("#txtuname").val(), uemail:$("#txtuemail").val(), fname:$("#txtfname").val(), femail:$("#txtfemail").val(), msg:$("#txtmsg").val(), id:mailpropidbuffer, title:$("#emlpropname").html()}, function(response) {
		if (response == "OK") {
			$("#grpmail2").css("display", "none");
			$("#grpmail3").css("display", "block");
			setTimeout(cancelMail, 1500);
		} else {
			alert(response);
			$("#grpmail2").css("display", "none");
			$("#grpmail1").css("display", "block");
		}
	});
}
function cancelMail() {
	$("#overlay").remove();
	$("#dlgmaillayer").fadeOut(500, function() {
		$(this).css({visibility:"hidden",display:"block"});
		$("#grpmail1").css("display", "block");
		$("#grpmail2").css("display", "none");
		$("#grpmail3").css("display", "none");
	});
}
function toggleBlacklist(propid, mode) {
	var blaction = false;
	var etime = (new Date()).getTime();
	if (mode == "dir") {
		$(propid).get(0).blur();
		while(propid.tagName != "LI") propid = propid.parentNode;
		var propli = propid;
		propid = $(propli).attr("id").replace(/propid/, "");
	} else {
		$("#lnkmapblacklprop").get(0).blur();
		$("#lnkmapunblacklprop").get(0).blur();
	}
	if (!propid) return false;
	if (blacklist[propid]) {
		if ((etime - blacklist[propid]) > 1000) { // Doubleclick check
			delete(blacklist[propid]);
			if (mode != "dir") $("div.propdesc").removeClass("bl");
			blaction = "remove";
		}
	} else {
		blacklist[propid] = etime;
		blaction = "add";
		if (mode != "dir") $("div.propdesc").addClass("bl");
	}
	if (blaction) {
		$.get("/lib/ajx/blacklist?action="+blaction+"&id="+propid, function(response) {
			if (response != "OK") {
				alert(response);
			} else {
				if (blaction == "add") {
					if (mode != "dir") {
						$("#lnkaddshortlist/..").css("display", "none");
						map.getInfoWindow().hide();
						var uuid = false;
						if (markers["saleprop"+propid]) uuid = "saleprop"+propid;
						if (markers["rentalprop"+propid]) uuid = "rentalprop"+propid;
						if (uuid && markers[uuid].obj) {
							map.removeOverlay(markers[uuid].obj);
							var marker = markers[uuid];
							marker.t = "bl"+marker.t;
							markers["bl"+uuid] = marker;
							delete(markers[uuid]);
							mapCreateMarker("bl"+uuid);
							map.addOverlay(markers["bl"+uuid].obj);
						}
					} else {
						$.getJSON("/lib/ajx/getprophtml?action="+blaction+"&id="+propid, function(response) {
							if (response.htmlc) {
								$(propli).fadeOut("fast", function() { $(propli).html("&nbsp;"); setTimeout("$('#propid"+propid+"').html($('"+decodeURIComponent(response.htmlc)+"').html()).addClass('bl').fadeIn('normal')", 20); });
							} else {
								alert(response);
							}
						});
					}
				} else {
					if (mode != "dir") {
						$("#lnkaddshortlist/..").css("display", "block");
						var propt = false;
						if (markers["blsaleprop"+propid]) propt = "saleprop";
						if (markers["blrentalprop"+propid]) propt = "rentalprop";
						if (propt && markers["bl"+propt+propid].obj) {
							map.removeOverlay(markers["bl"+propt+propid].obj);
							var marker = markers["bl"+propt+propid];
							marker.t = propt;
							markers[propt+propid] = marker;
							delete(markers["bl"+propt+propid]);
							mapCreateMarker(propt+propid);
							map.addOverlay(markers[propt+propid].obj);
						}
					} else {
						$.getJSON("/lib/ajx/getprophtml?action="+blaction+"&id="+propid, function(response) {
							if (response.htmlc) {
								$(propli).fadeOut("fast", function() { $(propli).html("&nbsp;"); setTimeout("$('#propid"+propid+"').html($('"+decodeURIComponent(response.htmlc)+"').html()).removeClass('bl').fadeIn('normal')", 20); });
							} else {
								alert(response);
							}
						});
					}
				}
			}
		});
	}
}
function forgotPass() {
	if (!$("#txtloginemail").val()) {
		alert("Please complete your email address, so we can send you a reminder of your password");
	} else {
		$.get("/lib/ajx/sendpassreminder?email="+encodeURIComponent($("#txtloginemail").val()), function(response) {
			alert(response);
		});
	}
}
function sendShortlist() {
	$.get("/lib/ajx/sendshortlist?email="+encodeURIComponent($("#txtslsendemail").val()), function(response) {
		alert(response);
	});
}
function ajaxError(ajaxObj, errorType, exception) {
	alert("AJAX error: "+errorType);
}


function CommaFormatted(amount, delimiter, symbol) {
	var amountstr = amount+"";
	var a = amountstr.split('.',2);
	var i = parseInt(a[0]);
	if(isNaN(i)) { return ''; }
	var minus = '';
	if(i < 0) { minus = '-'; }
	i = Math.abs(i);
	var n = new String(i);
	var b = [];
	while(n.length > 3) {
		var nn = n.substr(n.length-3);
		b.unshift(nn);
		n = n.substr(0,n.length-3);
	}
	if(n.length > 0) { b.unshift(n); }
	n = b.join(delimiter);
	if (a.length == 1) { amount = n; }
	else { amount = n + '.' + a[1]; }
	amount = minus + symbol + amount;
	return amount;
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

$(document).ready(cmnInit);
$(window).load(cmnResize);
$(document).resize(cmnResize);