if (typeof Prototype != 'undefined') {

	Object.extend(Function.prototype, {
		onLoad: function() {
			Event.observe(window, "load", this);
		}
	});

	window.loading = true;
	(function() { window.loading = false }).onLoad();

	Object.extend(Element, {
		withinViewport: function(el) {
			var elOffset = el.cumulativeOffset();
			var vpOffset = document.viewport.getScrollOffsets();
			var elDim = el.getDimensions();
			var vpDim = document.viewport.getDimensions();
			if (elOffset[1] + elDim.height < vpOffset[1] || elOffset[1] > vpOffset[1] + vpDim.height ||
				elOffset[0] + elDim.width < vpOffset[0]  || elOffset[0] > vpOffset[0] + vpDim.width) {
					return false;
				}
			return true;
		}
	});

	(function() {
		$$("input.label-is-value").each(function(el) {
			var original_value = el.defaultValue;
			el.observe("focus", function() {
				if ($F(el) == original_value)
					el.value = "";
			});
			el.observe("blur", function() {
				if ($F(el) == '')
					el.value = original_value;
			});
			el.up("form").observe("submit", function() {
				if ($F(el) == original_value)
					el.value = "";
			});
		});

		$$("img.mouseover, input.mouseover").each(function(el) {
			el.src_ = el.getAttribute("src");
			el.observe("mouseover", function() {
				el.src = el.src_.replace(/(\.(jpg|gif|png))$/, "-on$1");
			});
			el.observe("mouseout", function() {
				el.src = el.src_;
			});
		});
	}).onLoad();
}
if((typeof tinyMCE!='undefined')) {
	Event.observe(window, "load", function() {
			if ($$("textarea.auto-tinymce")) {
				tinyMCE.init({
						mode:"specific_textareas",
						editor_selector:"auto-tinymce",
						theme:"advanced",
						theme_advanced_buttons1:"bold,italic,underline,separator,strikethrough,undo,redo,bullist,numlist,link,unlink,formatselect",
						theme_advanced_buttons2:"",
						theme_advanced_buttons3:"",
						theme_advanced_path_location:"none",
						theme_advanced_blockformats:"p,h1,h2,preformatted",
						valid_elements:"strong,b,em,i,u,ul,ol,li,a,p,h1,h2,pre,br",
						paste_create_paragraphs : true,
						paste_auto_cleanup_on_paste : true,
						paste_convert_middot_lists : true,
						paste_unindented_list_class : "unindentedList",
						paste_convert_headers_to_strong : false,
						imagemanager_document_base_url: "/",
						imagemanager_relative_urls: false,
						imagemanager_remove_script_host: true,
						content_css:"/property_editor_styles.css"
				});
		}
	});
}

if (!salePrices)
	var salePrices = [75000, 100000, 125000, 150000, 175000, 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000, 500000, 750000, 1000000];
if (!letPrices)
	var letPrices = [350, 450, 500, 550, 600, 650, 700, 800, 1000, 1500, 2000];

if (typeof(Array.prototype.strInArray) == "undefined") {
	Array.prototype.strInArray = function (value) {
		// Returns true if the passed string is found in the
		// array. Returns false if it is not.
		var i;
		var tl = this.length;
		for (i=0; i < tl; i++) {
			if (this[i]==value) {
				return true;
			}
		}
		return false;
	};
}
if (typeof(Array.prototype.inArray) == "undefined")
	Array.prototype.inArray = Array.prototype.strInArray;


function mapLayerCheckboxes() {
	if (typeof Prototype == 'undefined')
		return;
	$$("input.maplayercheckbox").each(function(el) {
			name = el.id;
			switchLayer(name, $F(el));
	});
}

function chainedSelect(self, children, options) {
	var self = $(self);
	var value = $F(self);
	var options = Object.extend({
		label: "All"
	}, options || {});
	if (!(children instanceof Array))
		children = [children];

	var from_name = self.getAttribute("name");

	var count = children.length;
	for (var n = 0; n < count; n++) {
		(function(target) { // called below
			var target_name = target.getAttribute("name");

			Element.infanticide(target);
			target.appendChild(Builder.node("option", "Loading..."));

			new Ajax.Request("/ajax/distinct_select_tree", {
				method:"post",
				postBody:"from_field="+escape(from_name)+"&from_value="+escape(value)+"&to_field="+escape(target_name),
				onSuccess:function(t) {
					Element.infanticide(target);
					target.options[target.options.length] = new Option(options.label, "");

					data = eval("("+t.responseText+")");
					data.each(function(v) {
						target.options[target.options.length] = new Option(v);
					});
					target.selectedIndex = 0;
				}
			});
		})($(children[n]));
	}
}

function updateDistinctSelectTree(from_id, to_update, from_field, to_field_name) {
	value = $F(from_id);
	if (!(to_update instanceof Array))
		to_update = [to_update];

	var count = to_update.length;
	for (var n = 0; n < count; n++) {
		(function(to) {
			if (typeof from_field == "undefined") {
				from_field = $(from_id).getAttribute("name")
			}
			if (typeof to_field_name == "undefined")
				to_field = to.getAttribute("name")
			else to_field = to_field_name;

			Element.infanticide(to);

			to.appendChild(Builder.node("option", "Loading..."));
			new Ajax.Request("/ajax/distinct_select_tree", {
				method:"post",
				postBody:"from_field="+escape(from_field)+"&from_value="+escape(value)+"&to_field="+escape(to_field),
				onSuccess:function(t) {
					Element.infanticide(to);
					to.options[to.options.length] = new Option("All", "");

					data = eval("("+t.responseText+")");
					data.each(function(v) {
						to.options[to.options.length] = new Option(v);
					});
					to.selectedIndex = 0;
				}
			});
		})($(to_update[n]));
	}
}

if (typeof(Element) == "undefined")
	Element = {}

Element.infanticide = function(node) {
	node = $(node)
		if (node)
			while (node.hasChildNodes())
				node.removeChild(node.firstChild)
}
Element.staticize = function(element) {
	element = $(element);
	if (element.getStyle('position') == 'static') return;

	element.style.position = 'static';
	element.style.top    = "";
	element.style.left   = "";
	element.style.width  = "";
	element.style.height = "";
	return element;
};

// the following is for FSBO stuff
function fetchXmlData(id,source,elem,num) {
    new Ajax.Updater(elem,"/propertyEditor/fetchXml", {
      asynchronous:true, method:"post",
      postBody:"source="+source+"&elem="+elem+"&id="+id,
      onSuccess: function() { count++; if(count==num) Effect.Appear('viewlisting'); },
      onFailure: function() { alert('Error'); }
    });
}
function deleteImage (id) {
  if(window.confirm('Are you sure you want to delete this image?')){
    handler = function () {
      victim = $('image'+id);
      $(victim).style.display='none';
    }
    new Ajax.Request("/propertyEditor/deleteImage", {
      asynchronous:true, method:"post",
      postBody:"id="+id,
      onSuccess:handler,
      onFailure: function() { alert('Error'); }
    });
    
  }
}
function deleteProperty (id) {
  if(window.confirm('Are you sure you want to delete this property? If it is live, you will no longer be billed for this property, it will be completely unlisted from this site and all our partners.')){
    handler = function () {
      window.location.reload();
    }
    new Ajax.Request("/hub/deleteProperty", {
      asynchronous:true, method:"post",
      postBody:"id="+id,
      onSuccess:handler,
      onFailure: function() { alert('Error'); }
    });
  }
}
function deleteFromWatchList (id) {
	handler = function () {
		window.location.reload();
	}
	new Ajax.Request("/hub/deleteFromWatchList", {
		asynchronous:true, method:"post",
		postBody:"id="+id,
		onSuccess:handler,
		onFailure: function() { alert('Error'); }
	});
}
function numsToHtml() {
  html='<h3>Overview</h3><p>&nbsp;</p>';
  for(i=0;i<$('bedrooms').value;i++)
    html += '<h3>Bedroom '+(i+1)+'</h3><p>&nbsp;</p>';
  for(i=0;i<$('receptions').value;i++)
    html += '<h3>Reception Room '+(i+1)+'</h3><p>&nbsp;</p>';
  for(i=0;i<$('kitchens').value;i++)
    html += '<h3>Kitchen '+(i+1)+'</h3><p>&nbsp;</p>';
  for(i=0;i<$('otherrooms').value;i++)
    html += '<h3>Other room '+(i+1)+'</h3><p>&nbsp;</p>';
  html+='<h3>Further information</h3><p>&nbsp;</p>';
  return html;
}

var rotators = []

function rotateItems(els, num, options) {
	if (typeof(els) != "object")
		els = [els];
	els.each(function(el) {
		r = new ItemRotator(el, num, options || {})
		rotators.push(r);
	});
}

if (typeof(Class) != "undefined") {
	var ItemRotator = Class.create({
		pos: 0,
		visible: [],
		initialize: function (el, num) {
			this.options = Object.extend({
				num: num,
				duration: 10,
				fade_duration: 1,
				async: false,
				absolutize: false,
				parallel: false,
				shuffle: false,
				parallel: false,
				beforeFadeIn: function(div) {},
				beforeFadeOut: function(div) {},
				afterFadeIn: function(div) {},
				afterFadeOut: function(div) {},
				fadeInDelay: 0,
				fadeOutDelay: 0
			}, arguments[2] || { });
			this.el = $(el);
			if (!this.el)
				return;
			this.items = this.el.select(".rotate_item");
			if (this.items.length <= this.options.num) {
				this.items.each(function(el) {
					Element.show(el);
				});
				return;
			}

			this.items.each(function(el) {
				el.hide();
				Element.remove(el);
			});
			//var shown = [];
			for (var n = 0; n < this.options.num; n++) {
				/* // Not sure of the purpose of this code?
				if (this.options.shuffle) {
					do {
						n = this.randItem();
					} while (n in shown);
					shown.push(n);
				}
				*/
				this.el.appendChild(this.items[n]);
				Element.show(this.items[n]);
				this.visible.push(n);
			}
			if (!this.options.async)
				this.pos = n;
			window.setTimeout(this.performRotate.bind(this), this.options.duration * 1000);
			if (this.options.async)
				this.options.duration /= this.options.num;
		},
		performRotate: function() {
			this.options.async ? this.asyncRotate() : this.syncRotate();
		},

		// {{{
		syncRotate: function() {
			var to_hide = [];
			var to_show = [];
			this.items.each(function(el, n) { // Hide all items
				if (Element.visible(el))
					to_hide.push(n);
			});
			var hide_effects = [];
			var show_effects = [];

			to_hide.each(function(n) {
				if (this.options.shuffle) do {
					var next_el = this.randItem();
				} while (next_el in to_show || next_el == n)
					else var next_el = this.loop(n+this.options.num, this.items.length);

				hide_effects.push(new Effect.Fade(this.items[n], {
					sync: true,
					afterFinish: function() {
						this.items[n].insert({ before: this.items[next_el] });
						Element.remove(this.items[n]);
						Element.hide(this.items[n]);
					}.bind(this)
				}));
				to_show.push(next_el);
			}.bind(this));
			to_show.each(function(n) {
				show_effects.push(new Effect.Appear(this.items[n], { sync: true }));
			}.bind(this));

			if (this.options.parallel) {
				var to_show_divs = [];
				var to_hide_divs = [];

				to_show.each(function(n) {
					this.el.appendChild(this.items[n]);
					to_show_divs.push(this.items[n]);
				}.bind(this));

				to_hide.each(function(n) {
					to_hide_divs.push(this.items[n]);
				}.bind(this));

				this.options.beforeFadeOut(to_hide_divs);
				this.options.beforeFadeIn(to_show_divs);

				(function(self) { new Effect.Parallel(hide_effects.concat(show_effects), {
					duration: self.options.fade_duration,
					afterFinish: function() {
						self.options.afterFadeOut(to_hide_divs);
						self.options.afterFadeIn(to_show_divs);
						window.setTimeout(self.performRotate.bind(self), self.options.duration * 1000);
					}.bind(self)
				}); }).delay(this.options.fadeInDelay + this.options.fadeOutDelay, this);
			} else {
				new Effect.Parallel(hide_effects, {
					duration: this.options.fade_duration,
					afterFinish: function() {
						new Effect.Parallel(show_effects, {
							duration: this.options.fade_duration,
							afterFinish: function() {
								window.setTimeout(this.performRotate.bind(this), this.options.duration * 1000);
							}.bind(this)
						});
					}.bind(this)
				});
			}
		},
		// }}}
		asyncRotate: function(inc) {
			if (this.timer) {
				window.clearTimeout(this.timer);
				this.timer = false
			}
			var num = inc ? inc : this.options.num;
			// This should be easy
			if (this.options.absolutize)
				$A(this.el.getElementsByClassName("rotate_item")).reverse().each(function(el) { el.absolutize() });

			cb2 = function() {
				this.timer = window.setTimeout(this.performRotate.bind(this), this.options.duration * 1000);
				this.pos = inc ? next_el : this.loop(this.pos+1, this.items.length); // XXX: May need to set this beforeStart
			}
			cb1 = function() {
				// Append next
				if (this.options.shuffle) do {
					var next_el = this.randItem();
				} while (next_el in this.visible || next_el == this.pos)
				else var next_el = this.loop(this.pos + num, this.items.length);

				this.items[this.pos].insert({ before: this.items[next_el]});
				Element.remove(this.items[this.pos]);
				var idx = this.visible.indexOf(this.pos);
				if (idx != -1) this.visible.splice(idx, 1);

				this.items[next_el].setOpacity(0);
				Element.show(this.items[next_el]);
				this.visible.push(next_el);

				if (this.options.absolutize)
					$A(this.el.getElementsByClassName("rotate_item")).reverse().each(function(el) { Element.staticize(el); });

				if (this.options.duration)
					new Effect.Appear(this.items[next_el], {
						duration: this.options.fade_duration,
						afterFinish: cb2.bind(this)
					});
				else
					cb2.bind(this)();
			}

			if (this.options.duration)
				new Effect.Fade(this.items[this.pos], {
					duration: this.options.fade_duration,
					afterFinish: cb1.bind(this)
				});
			else
				cb1.bind(this)();
		},
		randItem: function() {
			return Math.floor(Math.random() * (this.items.length));
		},
		prev: function() {
			this.asyncRotate(-1);
		},
		next: function() {
			this.asyncRotate();
		},
		loop: function(n, max) {
			if (n >= max)
				n -= max;
			if (n < 0)
				n += max;
			return n;
		}
	});

	var Carousel = Class.create({
		offset: 0,
		initialize: function(el, options) {
			this.options = Object.extend({
				speed: 2,
				delay: 1000/30
			}, arguments[2] || { });
			this.el = $(el);
			this.inner = Builder.node("div");
			this.el.style.overflow = "hidden";
			this.el.style.whiteSpace = "nowrap";
			var height = 0;
			var width = 0;
			$A(this.el.childNodes).each(function(c) {
				if (c.nodeName == "#text" && c.nodeValue.strip().length == 0)
					c.parentNode.removeChild(c);
				else {
					height = Math.max($(c).getHeight(), height);
					width += $(c).getWidth();
					this.inner.appendChild(c);
				}
			}.bind(this));
			this.el.appendChild(this.inner);
			this.el.style.height = height+"px";
			this.inner.style.height = height+"px";
			this.inner.style.width = width+"px";

			this.cur = $(this.inner.firstChild);
			this.curwidth = this.cur.getWidth();

			window.setTimeout(this.scroll.bind(this), this.options.delay);
		},
		scroll: function() {
			this.el.scrollLeft += this.options.speed;

			if (this.el.scrollLeft > this.curwidth) {
				var el = Element.remove(this.cur);
				this.inner.appendChild(el);
				this.el.scrollLeft -= this.curwidth;

				this.cur = $(this.inner.firstChild);
				this.curwidth = this.cur.getWidth();
			}

			window.setTimeout(this.scroll.bind(this), this.options.delay);
		}
	});
}

function selectInstructionType(el_it, el_minprice, el_maxprice, cb) {
	el_it = $(el_it);
	el_minprice = $(el_minprice);
	el_maxprice = el_maxprice ? $(el_maxprice) : false;

	if (!el_it)
		return;
	var value = $F(el_it);

	if (selectInstructionType.custom) {
		var data = selectInstructionType.custom[value];
		if (el_minprice) populatePrices(el_minprice, data.prices, "min", data.format);
		if (el_maxprice) populatePrices(el_maxprice, data.prices, "max", data.format);
	} else switch (value) {
		case "Letting":
			if (el_minprice) populatePrices(el_minprice, letPrices, "min", selectInstructionType.format.let);
			if (el_maxprice) populatePrices(el_maxprice, letPrices, "max", selectInstructionType.format.let);
			break;
		default:
			if (el_minprice) populatePrices(el_minprice, salePrices, "min", selectInstructionType.format.sale);
			if (el_maxprice) populatePrices(el_maxprice, salePrices, "max", selectInstructionType.format.sale);
			break;
	}
	if (typeof(cb) == "function")
		cb(value.toLowerCase());

	Plugin.hook("select_instruction_type", {
		instruction_type: value.toLowerCase()
	});
	return value;
}

selectInstructionType.format = {};
selectInstructionType.format.sale = selectInstructionType.format.let = "&pound;{!$price}";
selectInstructionType.custom = false;

function selectInstructionTypeRadio(el_it, el_minprice, el_maxprice, cb) {
	el_minprice = $(el_minprice);
	el_maxprice = $(el_maxprice);
	var inputs = $$("input[name="+el_it+"]");
	var v = "";
	inputs.each(function(el) {
			if (el.name != el_it) return;
			if (el.type != "radio") return;
			if (!el.checked)      return;
			var opts = {}
			if (el.getAttribute("rev"))
				opts = eval('('+el.getAttribute("rev")+')');
			var prices = format = null;
			switch (el.value) {
				case "Sale":
					prices = typeof(opts.prices) != "undefined" ? opts.prices : salePrices;
					format = typeof(opts.format) != "undefined" ? opts.format : selectInstructionType.format.sale;
					break;
				case "Letting":
					prices = typeof(opts.prices) != "undefined" ? opts.prices : letPrices;
					format = typeof(opts.format) != "undefined" ? opts.format : selectInstructionType.format.let;
					break;
			}
			if (prices && format) {
				if (el_minprice && el_minprice.nodeName == "SELECT") populatePrices(el_minprice, prices, "min", format);
				if (el_maxprice && el_maxprice.nodeName == "SELECT") populatePrices(el_maxprice, prices, "max", format);
			}
			v = el.value;
			if (typeof(cb) == "function")
				cb(el.value.toLowerCase(), el_minprice, el_maxprice, el);
			Plugin.hook("select_instruction_type_radio", {
				instruction_type: el.value.toLowerCase(),
				minprice: el_minprice,
				maxprice: el_maxprice,
				el: el
			});
	});
	return v;
}

function addSelectOption(el, value, text) {
	o = new Option();
	o.text = text;
	o.value = value.toString();
	el.options[el.options.length] = o;
}

function populatePrices(el, prices, type, format) {
	var value = $F(el);
	while (el.options.length > 0)
		el.remove(0);
	prices = $A(prices);
	
	if (typeof(prices[0]) == "string") {
		var mintext = html_entity_decode(prices[0]);
		prices.shift();
	} else var mintext = "No Minimum";

	if (typeof(prices[prices.length-1]) == "string") {
		var maxtext = html_entity_decode(prices[prices.length-1]);
		prices.pop();
	} else var maxtext = "No Maximum";

	if (populatePrices.initialOption)
		addSelectOption(el, "", populatePrices.initialOption);

	if (type == "min")
		addSelectOption(el, "", mintext);

	format = html_entity_decode(format);

	prices.each(function(price) {
			var text = format.replace("%%price%%", number_format(price)).replace("{!$price}", number_format(price));
			addSelectOption(el, price, text);
			if (price == value)
				el.selectedIndex = el.options.length-1;
	});
	if (type == "max") {
		addSelectOption(el, "", maxtext);
		el.selectedIndex = (populatePrices.selectedIndex && typeof(populatePrices.selectedIndex.max) == "number") ? populatePrices.selectedIndex.max : el.options.length-1;
	}
}

function number_format(a, b, c, d) {
	// number_format(number, decimals, comma, formatSeparator)
	//
	if (!b) b = 0;
	if (!c) c = ".";
	if (!d) d = ",";

	a = Math.round(a * Math.pow(10, b)) / Math.pow(10, b);
	e = a.toString()
	f = e.split('.');
	if(!f[0]) f[0] = '0';
	if(!f[1]) f[1] = '';
	if(f[1].length < b){
		g = f[1];
		for(i = f[1].length + 1; i <= b; i++) {
			g += '0';
		}
		f[1] = g;
	}
	if(d != '' && f[0].length > 3) {
		h = f[0];
		f[0] = '';
		for(j = 3; j < h.length; j += 3) {
			i = h.slice(h.length - j, h.length - j + 3);
			f[0] = d + i +  f[0] + '';
		}
		j = h.substr(0, (h.length % 3 == 0) ? 3 : (h.length % 3));
		f[0] = j + f[0];
	}
	c = (b <= 0) ? '': c;
	return f[0] + c + f[1];
}

function html_entity_decode(str) {
	var ta = document.createElement("textarea");
	ta.innerHTML=str.replace(/</g,"<").replace(/>/g,">");
	toReturn = ta.value;
	ta = null;
	return toReturn
}

function sortableVisuals(div) {
	div = $(div);
	Sortable.create(div, {
		handle: "handle",
		onUpdate: function(el) {
			data = Sortable.serialize(el);
			new Ajax.Request("/xml/fsbo/sf/web/fsbo.php/propertyEditor/updateImagesOrder", {
				postBody: data
			});
		}
	});
}

function populateAddress(el) {
	value = $F(el);
	if (!value)
		return;
	new Ajax.Request("/xml/ajax/get-property-address.php", { // FIXME: Better URL required
			parameters: {
				id: value
			},
			evalJSON: true,
			onSuccess: function(t) {
				data = $H(eval('('+t.responseText+')'));
				data.each(function(v) {
					$("el_"+v[0]).value = v[1];
				});
			}
	});
}

if (typeof(Class) != "undefined") {
	var MultiLineInput = Class.create({
			initialize: function (el) {
				this.container = $(el);
				this.template = this.container.getElementsByTagName("li")[0].cloneNode(true);
				$A(this.container.getElementsByTagName("li")).each(function(line) { this.addHandlers(line) }, this);
				this.num_inputs = this.template.getElementsByTagName("input").length;
				this.blank_at_end = 1;
				if (this.num_inputs = 1)
					this.blank_at_end = 2;
				this.rescan();
			},
			rescan: function() {
				var lines = $A(this.container.getElementsByTagName("li"));
				var nlines = lines.length;
				var remove = [];
				var blank_at_end = 0;
				lines.each(function(line, n) {
					var inputs = $A(line.getElementsByTagName("input"));
					blank = true;
					inputs.each(function(input) {
						if($F(input)!==null) { // cope with things like checkboxes
							if ($F(input).strip()) {
								blank = false;
								throw $break;
							} else {
								return;
							}
						}
					});
					if (blank) {
						blank_at_end++;
						if (n < nlines-this.blank_at_end)
							remove.push(n);
					} else blank_at_end = 0;
				}, this);
				remove.each(function(n) {
						Effect.Fade(lines[n], {
								duration: 0.5,
								afterFinish: function() {
									Element.remove(lines[n]);
								}
						});
				});
				if (blank_at_end < this.blank_at_end) {
					for (i = 0; i < this.blank_at_end-blank_at_end; i++) {
						var line = this.container.appendChild(this.template.cloneNode(true));
						Element.hide(line);
						Effect.Appear(line, {
								duration: 0.5
						});
						$A(line.getElementsByTagName("input")).each(function(input) {
								input.value = "";
						});
						this.addHandlers(line);
					}
				}
			},
			addHandlers: function(line) {
				$A(line.getElementsByTagName("input")).each(function(input) {
					Event.observe(input, "change", this.rescan.bind(this));
				}, this);
				$A(line.getElementsByTagName("span")).each(function(span) {
					if (Element.hasClassName(span, "eval-js"))
						eval(span.innerHTML);
				});
				$A(line.getElementsByTagName("img")).each(function(img) {
					if (!Element.hasClassName(img, "delete"))
						return;
					Event.observe(img, "click", function() {
						$A(line.getElementsByTagName("input")).each(function(input) {
							input.value = "";
						}, this);
						this.rescan();
					}.bind(this));
				}, this);
			}
	});

	Event.observe(window, "load", initMultiline);

	var Scroller = Class.create({
		initialize: function(el, prev, next) {
			this.el = $(el);
			this.prev = $(prev);
			this.next = $(next);
			this.width = 0;
			$A(this.el.down("div").childNodes).each(function(c) {
				c = $(c);
				if (c.getWidth && c.getStyle)
					this.width += c.getWidth() + parseInt(c.getStyle("margin-left")) + parseInt(c.getStyle("margin-right"));
			}.bind(this));
			this.el.down("div").style.width = this.width + "px";

			this.next.observe("mousedown", function() { this.scroll(1); }.bindAsEventListener(this));
			this.next.observe("mouseup", this.stopScroll.bindAsEventListener(this));
			this.prev.observe("mousedown", function() { this.scroll(-1); }.bindAsEventListener(this));
			this.prev.observe("mouseup", this.stopScroll.bindAsEventListener(this));
		},
		scrolling: false,
		scroll: function(inc) {
			this.scrolling = true;
			this._scroll.bind(this).delay(0.01, inc);
		},
		_scroll: function(inc) {
			this.el.scrollLeft += inc;
			if (this.scrolling)
				this._scroll.bind(this).delay(0.01, inc);
		},
		stopScroll: function() {
			this.scrolling = false;
		}
	});
}

function initMultiline() {
	MultiLineInput.inputs = [];
	$$("ul.multiline-input, ol.multiline-input").each(function(el) {
		MultiLineInput.inputs.push(new MultiLineInput(el));
	});
}

function showCurrency(currency) {
	var els = $$("div.currency");
	els.each(function(el) {
			if (el.hasClassName(currency))
				el.show();
			else
				el.hide();
	});
	new Ajax.Request("/setcurrency/"+currency);
}
function setCurrency(currency, action) {
	new Ajax.Request("/setcurrency/"+currency, {
		onSuccess: function() {
			if (typeof action == "object" && action.nodeName == "FORM")
				action.submit();
			else if (typeof action == "function")
				action();
			else
				location.reload();
		}
	});
}

function getCurrentImage() {
	var n = 0;
	$$("img.imagechangermain").each(function(img) {
		if (!Element.visible(img))
			return;
		n = img.id.split("imagechanger")[1];
		throw $break;
	});
	return Number(n);
}

function getTotalImages() {
	var images = $$("img.imagechangermain");
	var last = images[images.length-1];
	return Number(last.id.split("imagechanger")[1])+1;
}

var icOnImageChange = function(n) {};

function prevImage() {
	var cur = getCurrentImage();
	if (cur == 0)
		return $("imagechanger"+String(cur));
	var img = $("imagechanger"+(cur-1));
	if (img) {
		ic_switch(img.id);
		return img;
	}
	return $("imagechanger"+String(cur));
}
function nextImage() {
	var cur = getCurrentImage();
	var total = getTotalImages();
	if (cur == total-1)
		cur = -1;
	var img = $("imagechanger"+(cur+1));
	if (img) {
		ic_switch(img.id);
		return img;
	}
	return $("imagechanger"+String(cur));
}


function bookmark(){
	var title = document.title;
	var url = document.location;
	if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)) {
		window.external.AddFavorite(url,title);
	} else if (navigator.appName == "Netscape") {
		window.sidebar.addPanel(title,url,"");
	} else {
		alert("Press CTRL-D (Netscape) or CTRL-T (Opera) to bookmark");
	}
}

function addToShortlist(id, skipreclass) {
	new Ajax.Request("/ajax/add_to_shortlist", {
		parameters: {
			id: id
		},
		onSuccess: updateShortlistCallback
	});
	if (!skipreclass) $$(".shortlist-property-"+id).invoke("addClassName", "remove-from-shortlist");
}

function deleteFromShortlist(id, skipreclass) {
	new Ajax.Request("/ajax/delete_from_shortlist", {
		parameters: {
			id: id
		},
		onSuccess: updateShortlistCallback
	});
	if (!skipreclass) $$(".shortlist-property-"+id).invoke("removeClassName", "remove-from-shortlist");
}

function refreshShortlist() {
	new Ajax.Request("/ajax/get_shortlist", {
		onSuccess: updateShortlistCallback
	});
}

function toggleInShortlist(id) {
	var actioned = false;
	$$(".shortlist-property-"+id).each(function(el) {
		if (el.hasClassName("remove-from-shortlist")) {
			if (!actioned) {
				deleteFromShortlist(id, true);
				actioned = true;
			}
			el.removeClassName("remove-from-shortlist");
			el.addClassName("add-to-shortlist");
		} else {
			if (!actioned) {
				addToShortlist(id, true);
				actioned = true;
			}
			el.removeClassName("add-to-shortlist");
			el.addClassName("remove-from-shortlist");
		}
	});
}

function updateShortlistCallback(t) {
	data = eval('('+t.responseText+')');
	if ($("shortlist")) $("shortlist").update(data);
}

var asEnableRadius = function (radius) {
	if (!radius) return;
	//radius.enable();
	radius.options[0].value = "";
	radius.options[0].text = radius.originalText;
};
var asDisableRadius = function (radius) {
	if (!radius) return;
	//radius.disable();
	radius.options[0].value = "";
	radius.options[0].text = "this area only";
	radius.options.selectedIndex = 0;
};

function applyAjaxSearch() {
	$$("input[name=ajax_location], input.ajax-complete-simple").each(function(el) {
		if (el.ajaxSearchApplied)
			return;
		el.ajaxSearchApplied = true;

		/* Why are these lines here?
		var oDiv = document.createElement("DIV");
		document.body.appendChild(oDiv);
		*/

		div = Builder.node("div", {"class":"ajax-search-results", "style":"z-index: 100"});
		/* XXX this was at the top. changed to bottom for prestonbarker.co.uk/buy.html */
		$(document.body).insert({bottom: Builder.node("div", {"style":"position: relative"}, [div])});
		var parameters = "field="+escape(el.getAttribute("rel"))
			+"&show_type="+Number(Boolean(el.hasClassName("ac-show-type")))
			+"&only_predefined="+Number(Boolean(el.hasClassName("ac-only-predefined")));
		if (el.getAttribute("rev"))
			parameters += "&parameters="+el.getAttribute("rev");
		new Ajax.Autocompleter(el, div, "/ajax/viewport-search", {
			paramName: "value",
			parameters: parameters,
			updateElement: function(li) {
				if (li.hasClassName("result"))
					el.value = li.firstChild.nodeValue;

				Plugin.hook("ajax_location_after_select", {
					li: li
				});
			},
			minChars: 1,
			frequency: 0.2
		});
	});
	$$("input.ajax-complete").each(function(el, n) {
		if (el.ajaxSearchApplied)
			return;
		el.ajaxSearchApplied = true;
		el.originalName = el.getAttribute("name");
		try {
			var radius = $$("select.ajax-radius")[n];
			radius.originalText = radius.options[0].text;
		} catch (err) {
			var radius = false;
		}

		div = Builder.node("div", {"class":"ajax-search-results", "style":""});
		if (el.id)
			div.id = "as-"+el.id;
		$(document.body).insert({bottom: Builder.node("div", {"style":"position: relative"}, [div])});

		var parameters = "field="+escape(el.getAttribute("rel"))
			+"&show_type="+Number(Boolean(el.hasClassName("ac-show-type")));
			+"&only_predefined="+Number(Boolean(el.hasClassName("ac-only-predefined")));

		if (el.getAttribute("rev"))
			parameters += "&parameters="+el.getAttribute("rev");
		new Ajax.Autocompleter(el, div, "/ajax/search-autocomplete", {
			paramName: "value",
			parameters: parameters,
			callback: function(inp, str) {
				el.name = el.originalName;
				if (el.hasClassName("ac-set-name")) asEnableRadius(radius);
				return str;
			},
			updateElement: function(li) {
				el.value = li.down("span.data").firstChild.nodeValue;
				if (el.hasClassName("ac-set-name")) {
					el.name = li.getAttribute("rel");
					asDisableRadius(radius);
				} else {
					//asEnableRadius(radius);
				}
			},
			select: "result",
			minChars: 1
		});
		el.observe("change", function() {
		});
	});

	$$("input.ajax-complete-detailed").each(function(el, n) {
		if (el.ajaxSearchApplied)
			return;
		el.ajaxSearchApplied = true;
		div = Builder.node("div", {"class":"ajax-search-results", "style":"z-index: 100"});
		$(document.body).insert({top: div});
		new Ajax.Autocompleter(el, div, "/ajax/search-autocomplete-detailed", {
			paramName: "value",
			updateElement: function(li) {
				el.value = li.down("span.data").firstChild.nodeValue;
				var radius = $$("select.ajax-radius")[n];
				var type = li.getAttribute("rel");
				el.name = type == "postcode" ? "part_postcode" : "radius_location";
				ajaxSearchOnchange(el, radius);
			},
			select: "result",
			minChars: 1
		});
	});
	if (window.loading)
		applyAjaxSearch.delay(0.1);
}
if(typeof Prototype != 'undefined')
	applyAjaxSearch();

ajaxSearchOnchange = function (el, radius) {
	switch (el.name) {
		case "part_postcode":
			radius.options[0].text = "this postcode";
			radius.options[0].value = "-";
			radius.selectedIndex = 0;
			break;
		case "radius_location":
			radius.options[0].text = "select distance:";
			radius.options[0].value = "";
			break;
	}
}

var ListSearch = function(form_id) {
	var el = document.getElementById(form_id);
	el.setAttribute("action", "/search/");
}
var MapSearch = function(form_id) {
	if (typeof form_id == "object") {
		$(form_id).up("form").setAttribute("action", "/search2/");
	} else {
		document.getElementById(form_id).setAttribute("action", "/search2/");
	}
}

var setFormAction = function(self, action) {
	$(self).up("form").setAttribute("action", action);
}

var touchHandler = function(event) {
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
    
    switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type="mousemove"; break;        
        case "touchend":   type="mouseup"; break;
        default: return;
    }
        
    //initMouseEvent(type, canBubble, cancelable, view, clickCount,
    //           screenX, screenY, clientX, clientY, ctrlKey,
    //           altKey, shiftKey, metaKey, button, relatedTarget);
    
    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1,
                              first.screenX, first.screenY,
                              first.clientX, first.clientY, false,
                              false, false, false, 0/*left*/, null);
                                                                            
    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

var getCurrentLocation = function() {
	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(function(position) {
			$("latitude").value = position.coords.latitude;
			$("longitude").value = position.coords.longitude;

			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({ latLng: new google.maps.LatLng(position.coords.latitude, position.coords.longitude) }, function(results, status) {
				var address = results[0].formatted_address;
				$("address_keyword").value = address;
				$("address_keyword").name = "";
				new Ajax.Request("/recent_locations.html", {
					parameters: {
						action: 'add',
						address: address,
						latitude: position.coords.latitude,
						longitude: position.coords.longitude
					}
				});
			})
		});
	}
};

var setManualLocation = function() {
	$("address_keyword").name = "address_keyword";
	$("latitude").value = "";
	$("longitude").value = "";
};

var showRecentLocations = function() {
	var div = Builder.node("div", { id: 'recent-locations' }, [ Builder.node("div", { id: 'recent-locations-inner'}) ]);
	new Ajax.Updater(div.firstChild, "/recent_locations.html", {
		onSuccess: function() {
			//$("recent-locations").remove();
			document.body.appendChild(div);
		}
	});
}

var closeRecentLocations = function() {
	$("recent-locations").remove();
	return false;
}

var setCurrentLocation = function(latitude, longitude, address) {
	$("address_keyword").value = address;
	if (latitude || longitude) {
		$("latitude").value = latitude;
		$("longitude").value = longitude;
		$("address_keyword").name = "";
	} else {
		$("latitude").value = "";
		$("longitude").value = "";
		$("address_keyword").name = "address_keyword";
	}
	closeRecentLocations();
};

