﻿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 }, xyz: { hash: true, value: [], symbol: "xyz", 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; var updateUrlHash = true; 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(/,/g, "+").replace(/!/g, ","); } }
        return (hash.length > 0) ? hash.substr(1) : hash;
    }
    function updateHashManager(hash) { if (updateUrlHash) { 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 || hash.indexOf("xyz") != -1) {
            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; if (options.updateUrlHash != undefined) { updateUrlHash = options.updateUrlHash; }
        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; }, isDefaultRatings: function () {
        if (currentSearch && currentSearch['rating'] && defaultSearch && defaultSearch['rating']) { return (Sawbuck.Utilities.isSame(currentSearch['rating'].value, defaultSearch['rating'].value)); }
        else return true;
    }, 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); } }; })();
