﻿var Sawbuck = window.Sawbuck || {}; Sawbuck.SearchManager = (function() {
	var filters = {}; var _saveDefintion = true; var eventHandlers = []; var propertyList = {}; var defaultSearch = { areaURL: { hash: true, value: [], symbol: "a", travels: false }, areaID: { hash: true, value: [], symbol: "i", travels: false }, status: { hash: false, value: [1] }, view: { hash: true, value: ["list"], symbol: "v" }, feeds: { hash: true, value: [0], symbol: "fd" }, page: { hash: true, value: [1], symbol: "p", travels: false }, zoom: { hash: true, value: [], symbol: "zl", travels: false, location: true }, map_center: { hash: true, value: [], symbol: "c", travels: false, location: true }, specialFeatures: { hash: true, value: [0], symbol: "f" }, beds: { hash: true, value: [0, 100], symbol: "br" }, price: { hash: true, value: [0, 100000000], symbol: "pr" }, baths: { hash: true, value: [0, 50], symbol: "ba" }, propertyTypes: { hash: true, value: [7], symbol: "ty" }, listDate: { hash: true, value: [-3650, 0], symbol: "li" }, closeDate: { hash: true, value: [-365, 1], symbol: "cl" }, rating: { hash: true, value: [1, 0], symbol: "ra" }, sort: { hash: true, value: ["sdate-"], symbol: "s" }, updateTypeID: { hash: true, value: [15], symbol: "uty" }, searchIDs: { hash: true, value: [], symbol: "sid"} }
	var currentSearch = null; var preloadedContent = false; var preloadedSearch = null; var doHashLinks = false; function onHashChange(args) {
		if (!args.app) {
			var newSearch = decodeHash(args.hash); var compare = compareProperties(newSearch, currentSearch); if (!compare.same) {
				currentSearch = newSearch; if (_saveDefintion)
					Sawbuck.Utilities.writeCookie("SearchDef", encodeHash(currentSearch, false)); raise({ search: currentSearch, properties: compare.properties, source: "hash" });
			}
			else if (preloadedContent)
				changeHashLinks();
		} 
	}
	function onFilterChange(args) {
		var newSearch = Sawbuck.Utilities.cloneObject(currentSearch); var property = args.property; var value = args.value; if (property) { if (newSearch[property]) { newSearch[property].value = value; } }
		if (args.resetFields) { for (var i = 0; i < args.resetFields.length; i++) { var property = args.resetFields[i]; Sawbuck.Debugger.report("Resetting " + property); newSearch[property].value = defaultSearch[property].value } }
		var compare = compareProperties(newSearch, currentSearch); if (!compare.same) {
			currentSearch = newSearch; var hash = encodeHash(currentSearch); if (_saveDefintion)
				Sawbuck.Utilities.writeCookie("SearchDef", encodeHash(currentSearch, false)); updateHashManager(hash); raise({ search: currentSearch, properties: compare.properties, source: "filter" });
		} 
	}
	function decodeHash(hash) {
		var newSearch = Sawbuck.Utilities.cloneObject(defaultSearch), v, i; if (hash.length > 0) { var items = hash.split("/"); var item = [], key, value, property, range = []; for (var i = 0; i < items.length; i++) { item = items[i].split("_"); key = item[0]; value = item[1]; if (key && value) { property = findProperty(key); if (property) { if (newSearch[property].hash) { if (typeof defaultSearch[property].value[0] == "number") { newSearch[property].value = []; v = value.split(","); for (var j = 0; j < v.length; j++) { newSearch[property].value[j] = parseFloat(v[j]); } } else { var values = value.split(","); newSearch[property].value = []; for (var v = 0; v < values.length; v++) { newSearch[property].value.push(values[v].replace(/\|/g, "/").replace(/\*/g, "_").replace(/\+/g, ",")); } } } } } } }
		return newSearch;
	}
	function findProperty(key) {
		var propertyName; for (i in defaultSearch) { if (defaultSearch[i].symbol) { if (key == defaultSearch[i].symbol.toString()) { propertyName = i; break; } } }
		return propertyName;
	}
	function encodeHash(search, includeTravelers, includeLocation) {
		includeTravelers = (includeTravelers === undefined) ? true : includeTravelers; includeLocation = (includeLocation === undefined) ? false : includeLocation; var hash = ""; for (i in search) { if (!Sawbuck.Utilities.isSame(search[i], defaultSearch[i]) && defaultSearch[i].hash && (defaultSearch[i].travels !== includeTravelers || defaultSearch[i].location === includeLocation)) { hash += "/" + search[i].symbol + "_" + search[i].value.join("!").replace(/\//g, "|").replace(/_/g, "*").replace(/,/, "+").replace(/!/, ","); } }
		return (hash.length > 0) ? hash.substr(1) : hash;
	}
	function updateHashManager(hash) { Sawbuck.Debugger.report("Changing hash"); Sawbuck.HashManager.newHash(hash); }
	function raise(args, silent) {
		if (!silent) { for (var i = 0; i < eventHandlers.length; i++) { eventHandlers[i](args); } }
		if (args.source != "filter") { var filter, j, property; for (property in filters) { if (!args.properties[property]) { for (j = 0; j < filters[property].length; j++) { filter = filters[property][j]; filter.load({ value: currentSearch[property].value }); } } } }
		changeHashLinks();
	}
	function registerFilter(property, filter) { var del = Sawbuck.Utilities.createDelegate(this, onFilterChange); filter.addHandler(del); filters[property] = filters[property] || []; filters[property].push(filter); }
	function compareProperties(search1, search2) {
		var objSame = true; var propSame; var properties = {}; if (search1) { for (property in search1) { propSame = Sawbuck.Utilities.isSame(search1[property], search2[property]); objSame = (objSame && propSame); properties[property] = propSame; } }
		else { for (property in search2) { properties[property] = false; } }
		return { same: objSame, properties: properties}
	}
	function changeHashLinks() { if (doHashLinks && jQuery) { var hash = encodeHash(currentSearch, false); h = (hash.length > 0) ? "#" + hash : ""; jQuery("a.hash").each(function() { this.href = this.getAttribute("href").split("#")[0] + h; }); var q = (hash.length > 0) ? "?" + hash.replace(/\//g, "&").replace(/_/g, "=") : ""; jQuery("a.querystring").each(function() { this.href = this.getAttribute("href").split("?")[0] + q; }); var locationHash = encodeHash(currentSearch, false, true); var l = (locationHash.length > 0) ? "#" + locationHash : ""; jQuery("a.hash.location").each(function() { this.href = this.getAttribute("href").split("#")[0] + l; }); } }
	function saveSearch() { return true; }
	function updateHash() {
		var hash = encodeHash(currentSearch, true); if (hash.length > 0)
			return updateHashManager(hash); else
			return updateHashManager("");
	}
	$j(window).unload(function() { saveSearch() }); return { addHandler: function(eventHandler) { eventHandlers.push(eventHandler); }, init: function(opt) {
		var options = opt || {}; if (options.filters) { for (var i = 0; i < options.filters.length; i++) { registerFilter(options.filters[i].property, options.filters[i].filter); } }
		if (options.dontSave) _saveDefintion = false; var del = Sawbuck.Utilities.createDelegate(this, onHashChange); Sawbuck.HashManager.addHandler(del); defaultSearch = options.defaultSearch || defaultSearch; currentSearch = Sawbuck.Utilities.cloneObject(defaultSearch); var hash = options.hash || Sawbuck.HashManager.getCurrentHash(); if (opt.preloadedHash) {
			preloadedContent = true; var preloadedSearch = decodeHash(opt.preloadedHash)
			if (preloadedSearch.view.value[0] == "map")
				preloadedSearch.view.value[0] = ""; $j.extend(currentSearch, preloadedSearch);
		}
		doHashLinks = options.doHashLinks || doHashLinks; onHashChange({ hash: hash, app: false }); var filter, j, property; for (property in filters) { for (j = 0; j < filters[property].length; j++) { filter = filters[property][j]; filter.load({ value: currentSearch[property].value }); } } 
	}, getSearch: function() { return currentSearch; }, getHash: function(includeTravelers) {
		var hash = encodeHash(currentSearch, includeTravelers); if (hash.length > 0)
			return "#" + hash; else
			return "";
	}, updateHash: function() { var val = updateHash(); changeHashLinks(); return val; }, getValue: function(key) {
		if (currentSearch && currentSearch[key])
			return currentSearch[key].value
		else if (defaultSearch && defaultSearch[key])
			return defaultSearch[key].value
	}, setValues: function(valueHash, doUpdateHash) {
		for (var key in valueHash) {
			if (!valueHash[key]) continue; if (currentSearch && currentSearch[key])
				currentSearch[key].value = valueHash[key]; else if (defaultSearch && defaultSearch[key])
				defaultSearch[key].value = valueHash[key];
		}
		if (doUpdateHash) { updateHash(); changeHashLinks(); } 
	}, setValue: function(key, value, doUpdateHash) {
		if (currentSearch && currentSearch[key])
			currentSearch[key].value = value; else if (defaultSearch && defaultSearch[key])
			defaultSearch[key].value = value; if (doUpdateHash) { updateHash(); changeHashLinks(); } 
	}, saveRecentSearch: function() { return saveSearch(); }, goToPage: function(page) { if (filters["page"]) { Sawbuck.Debugger.report("Going to page " + page); onFilterChange({ property: "page", value: [parseInt(page)] }); } }, changeHashLinks: function() { changeHashLinks(); } }
	})(); Sawbuck.Queue = (function() { var _actions = []; return { add: function(action) { _actions.push(action); }, go: function() { if (_actions.length > 0) { var action = _actions.pop(); action.call(); } }, rewind: function() { _actions.pop(); }, clear: function() { _actions = []; }, flush: function() { while (_actions.length > 0) { var action = _actions.pop(); action.call(); } }, debug: function() { console.log(_actions); } }; })();