﻿FilterHelper = function() {
    this.ControlInfo = {};
    this.ExpectedSliders = 0;
    this.InitializedSliders = 0;
    this.Params = {};
    this.LastLocation = null;
    this.ObservationInterval = 500;
    this.UpdateFilterTimer = null;
    this.LastSearchStart = null;
    this.LastSearchEnd = null;
    this.SearchPending = false;
    this.RedoSearch = false;
    this.LastSearchLocation = "";
    this.InitTime = null;
    this.ItemsPerPage = 10;
    this.LastResultList = null;
    this.LastTopResultList = null;
    this.LastPrices = null;
    this.CurrentPagingPage = 1;
    this.PageCount = 0;
    this.IsFirstRequest = false;
    this.SkipNextUpdateBy = []
    this.DetectedSource = null;
    this.SortDropdown = null;
    this.CurrentSearchField = "ChangeDate";
    this.CurrentSearchDirection = "DESC";
    this.FirefoxObjectBackup = [];
    this.FirefoxLastTimeout = null;
    this.DisplayingTopItems = false;
    this.CurrentStartItem = 0;
    this.CurrentEndItem = this.ItemsPerPage;
    this.SearchIsDirty = false;
    this.LastResultCount = 0;
    this.CompleteListRealtyIDs = null;
    this.RealtyDefinitions = {};
    this.TelerikLoadedEvent = false;
    this.ExponentialSliderValues = {};
}

var FILTER_TYPE_SLIDER = "Slider";
var FILTER_TYPE_DROPDOWN = "Dropdown";
var FILTER_TYPE_HIDDEN = "Hidden";
var FILTER_TYPE_TEXTBOX = "Textbox";

FilterHelper.prototype = {
    Init: function () {
        if (window.location.href.search(/%/) > -1) {
            window.location = decodeURI(window.location.href);
        }

        // Only load this on the result page, but precache the file on start page to prevent slider errors.
        // [MB]
        if (window.EnableFilterHelper) {
            filterHelper.LastLocation = window.location.href;
            filterHelper.RegisterControlInfo("HfLocations", "l", FILTER_TYPE_HIDDEN);
            filterHelper.RegisterControlInfo("HfStreets", "str", FILTER_TYPE_HIDDEN);
            filterHelper.RegisterControlInfo("HfObjectIDs", "i", FILTER_TYPE_HIDDEN);
            filterHelper.RegisterControlInfo("HfZips", "z", FILTER_TYPE_HIDDEN);
            filterHelper.RegisterControlInfo("HfSource", "src", FILTER_TYPE_HIDDEN);
            filterHelper.RegisterControlInfo("RsPrice", "p", FILTER_TYPE_SLIDER);
            filterHelper.RegisterControlInfo("RsSurface", "s", FILTER_TYPE_SLIDER);
            filterHelper.RegisterControlInfo("RsRooms", "n", FILTER_TYPE_SLIDER);
            filterHelper.RegisterControlInfo("RsFactor", "f", FILTER_TYPE_SLIDER);
            filterHelper.RegisterControlInfo("RsYield", "y", FILTER_TYPE_SLIDER);
            filterHelper.RegisterControlInfo("DdlRealtySubType", "sty", FILTER_TYPE_DROPDOWN);
            filterHelper.RegisterControlInfo("DdlRealtyType", "rt", FILTER_TYPE_DROPDOWN);
            filterHelper.RegisterControlInfo("DdlObjectAge", "oa", FILTER_TYPE_DROPDOWN);
            filterHelper.RegisterControlInfo("TbBuzzwordSearch", "bw", FILTER_TYPE_TEXTBOX);

            var startPageControl = $j("#SbComingFromStartPage");
            if (startPageControl.length > 0) {
                if (startPageControl.get(0).value == "true") {
                    filterHelper.IsFirstRequest = true;
                }
                startPageControl.get(0).value = "-";
            }

            var locationMatches = window.location.href.match(/src{([^\}]+)}/);
            if (locationMatches && locationMatches.length >= 2) {
                filterHelper.DetectedSource = locationMatches[1];
                filterHelper.SortDropdown = $get("DdlResultListSort");

                filterHelper.RefreshSortDropdown();
            }
        }
    },

    RefreshSortDropdown: function () {
        var realtyTypeNotSet = (filterHelper.GetRealtyTypeKey() == "");
        var isPrivateBuilding = (filterHelper.GetRealtyTypeKey().search(/(Wohnung)|(Einfamilienhaus)/) != -1);
        var showRooms = isPrivateBuilding || realtyTypeNotSet;

        // Update the realty-dropdowns and 
        // [MB]
        ClearDropdownList(filterHelper.SortDropdown, true);
        if (filterHelper.DetectedSource == "kapitalanlage") {
            $get("PnlFactorAndYield").style.display = "block";

            AddDropdownOption(filterHelper.SortDropdown, "Price ASC", "Preis (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Price DESC", "Preis (absteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Factor ASC", "X-fache Miete (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Factor DESC", "X-fache Miete (absteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Yield ASC", "Rendite (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Yield DESC", "Rendite (absteigend)");
            if (showRooms) {
                AddDropdownOption(filterHelper.SortDropdown, "Rooms ASC", "Zimmer (aufsteigend)");
                AddDropdownOption(filterHelper.SortDropdown, "Rooms DESC", "Zimmer (absteigend)");
            }
            AddDropdownOption(filterHelper.SortDropdown, "Surface ASC", "Fläche (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Surface DESC", "Fläche (absteigend)");
        }
        else {
            AddDropdownOption(filterHelper.SortDropdown, "Price ASC", "Preis (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Price DESC", "Preis (absteigend)");
            if (showRooms) {
                AddDropdownOption(filterHelper.SortDropdown, "Rooms ASC", "Zimmer (aufsteigend)");
                AddDropdownOption(filterHelper.SortDropdown, "Rooms DESC", "Zimmer (absteigend)");
            }
            AddDropdownOption(filterHelper.SortDropdown, "Surface ASC", "Fläche (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "Surface DESC", "Fläche (absteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "ObjectAge ASC", "Baujahr/Objektalter (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "ObjectAge DESC", "Baujahr/Objektalter (absteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "ChangeDate ASC", "Datum der letzten Änderung (aufsteigend)");
            AddDropdownOption(filterHelper.SortDropdown, "ChangeDate DESC", "Datum der letzten Änderung (absteigend)", true);
        }

        // Also hide the room-slider itself.
        // [MB]
        if (showRooms) {
            $j("#FbRooms").css("display", "block");
        }
        else {
            var clientIdOfRoomSlider = GetControlId("RsRooms");
            if (clientIdOfRoomSlider) {
                var roomSlider = $find(clientIdOfRoomSlider);

                if (roomSlider) {
                    roomSlider.set_selectionStart(roomSlider.get_minimumValue());
                    roomSlider.set_selectionEnd(roomSlider.get_maximumValue());
                }
            }

            $j("#FbRooms").css("display", "none");
        }
    },

    GetRealtyTypeKey: function () {
        var controlId = GetControlId("DdlRealtyType");

        if (controlId) {
            var realtyTypeDdl = $get(controlId);

            if (realtyTypeDdl) {
                if ((realtyTypeDdl.selectedIndex >= 0) && (realtyTypeDdl.selectedIndex < realtyTypeDdl.options.length))
                    return realtyTypeDdl.options[realtyTypeDdl.selectedIndex].value;
            }
        }

        return "";
    },

    UpdateSearchFromLocationBar: function (caller) {
        if (!filterHelper.TelerikLoadedEvent) {
            filterHelper.TelerikLoadedEvent = true;

            // Load filter values from location bar.
            // [MB]
            filterHelper.Params = filterHelper.GetParameters();
            for (var paramName in filterHelper.Params) {
                var controlInfo = filterHelper.GetControlInfoByShortcut(paramName);

                // HINT: At the first time this will only restore the dropdowns, because the sliders aren't already loaded at this point.
                // TODO: If reactivated - remove IF to reenable buzzwords.
                // [MB]
                if (paramName != "bw")
                    filterHelper.RestoreFilterValue(controlInfo, filterHelper.Params[paramName]);
            }

            filterHelper.UpdateSearch(1, "Init");
        }
    },

    StartLocationObserver: function () {
        filterHelper.LastLocation = window.location.href;

        window.setInterval(filterHelper.CheckLocation, filterHelper.ObservationInterval);
    },

    BackupForFirefoxWorkaround: function (e) {
        filterHelper.FirefoxObjectBackup[filterHelper.FirefoxObjectBackup.length] = e;
    },

    RestoreFirefoxWorkaroundBackup: function () {
        for (var i = 0; i < filterHelper.FirefoxObjectBackup.length; i++) {
            var e = filterHelper.FirefoxObjectBackup[i];

            if (e != null) {
                filterHelper.InformClientLoaded(e, null, true);

                filterHelper.FirefoxObjectBackup[i] = null;
            }
        }

        if (filterHelper.FirefoxLastTimeout)
            window.clearTimeout(filterHelper.FirefoxLastTimeout);
    },

    InformClientLoaded: function (e, sender, skipFirefoxWorkaround) {
        // Firefox workaround which is caused by it's events variing from the order of the IE ones.
        // [MB]
        if (!document.all) {
            if (filterHelper.FirefoxLastTimeout)
                window.clearTimeout(filterHelper.FirefoxLastTimeout);

            if (filterHelper.RestoreFirefoxWorkaroundBackup)
                filterHelper.FirefoxLastTimeout = window.setTimeout("filterHelper.RestoreFirefoxWorkaroundBackup()", 50);
        }

        var controlKey = GetControlKeyByClientId(e._uniqueID);

        if (controlKey) {
            var controlInfo = filterHelper.GetControlInfo(controlKey);

            if (controlInfo) {
                controlInfo.IsLoaded = true;

                // Check if all controls are loaded.
                // [MB]
                for (var controlKey in filterHelper.ControlInfo) {
                    if (!filterHelper.ControlInfo[controlKey].IsLoaded)
                        return false;
                }

                // Fire the update event as soon as all controls are loaded.
                // [MB]
                filterHelper.UpdateSearchFromLocationBar("TeleriksLoaded");
            }
            else {
                if (!document.all)
                    filterHelper.BackupForFirefoxWorkaround(e);
            }
        }

        return false;
    },

    CheckLocation: function () {
        if (filterHelper.LastLocation != window.location.href) {
            filterHelper.LastLocation = window.location.href;

            // Inform the modal handler about the change.
            // [MB]
            if (detailsViewHelper && detailsViewHelper.Init) {
                detailsViewHelper.Init();
            }

            filterHelper.UpdateSearchFromLocationBar("Interval");
        }
    },

    RestoreFilterValue: function (controlInfo, params) {
        if (controlInfo) {
            clientId = GetControlId(controlInfo.Key);
            var fieldUpdated = false;

            switch (controlInfo.Type) {
                case FILTER_TYPE_SLIDER:
                    var slider = $find(clientId);
                    if (slider) {
                        filterHelper.InitializedSliders++;
                        var startVal = params[0];
                        var endVal = params[1];
                        var minVal = slider.get_minimumValue();
                        var maxVal = slider.get_maximumValue();

                        if (startVal == "MIN") {
                            startVal = minVal;
                        }
                        else {
                            startVal = filterHelper.GetUnwrappedSliderValue(startVal, minVal, maxVal, clientId);
                        }
                        if (endVal == "MAX") {
                            endVal = maxVal;
                        }
                        else {
                            endVal = filterHelper.GetUnwrappedSliderValue(endVal, minVal, maxVal, clientId);
                        }

                        slider.set_selectionStart(startVal);
                        slider.set_selectionEnd(endVal);
                        fieldUpdated = true;
                    }

                    break;
                case FILTER_TYPE_DROPDOWN:
                    var selectBox = $get(clientId);

                    for (var optionNum = 0; optionNum < selectBox.options.length; optionNum++) {
                        if (selectBox[optionNum].value == params[0]) {
                            selectBox.selectedIndex = optionNum;
                            fieldUpdated = true;
                            break;
                        }
                    }

                    break;
                case FILTER_TYPE_TEXTBOX:
                case FILTER_TYPE_HIDDEN:
                    var hidden = $get(GetControlId(controlInfo.Key));
                    hidden.value = params.join();
                    fieldUpdated = true;

                    break;
            }

            if (filterHelper.InitializedSliders > filterHelper.ExpectedSliders) {
                var extension = filterHelper.BuildLocationExtension();
                filterHelper.UpdateLocationBar(extension);
            }
        }
    },

    GetParameters: function () {
        var mainSplit = window.location.href.split(/#/);

        var parameterValues = {};
        if (mainSplit.length == 2) {
            var parameters = mainSplit[1].split(/\}/);

            for (var parameterNumber = 0; parameterNumber < parameters.length; parameterNumber++) {
                var parameterParts = parameters[parameterNumber].split(/\{/);

                if (parameterParts.length == 2) {
                    var parameterName = parameterParts[0];
                    parameterValues[parameterName] = parameterParts[1].split(/,/);
                }
            }
        }

        return parameterValues;
    },

    RegisterControlInfo: function (key, shortcut, type) {
        var controlAvailable = true;

        if ((type == FILTER_TYPE_SLIDER) || (type == FILTER_TYPE_DROPDOWN)) {
            var controlId = GetControlId(key);

            if (!controlId)
                controlAvailable = false;
        }

        if (controlAvailable) {
            if (type == FILTER_TYPE_SLIDER)
                filterHelper.ExpectedSliders++;

            filterHelper.ControlInfo[key] = {}
            filterHelper.ControlInfo[key].Shortcut = shortcut;
            filterHelper.ControlInfo[key].Type = type;
            filterHelper.ControlInfo[key].Key = key;
            filterHelper.ControlInfo[key].IsLoaded = (type == FILTER_TYPE_SLIDER) ? false : true;
        }
    },

    GetControlInfo: function (key) {
        return filterHelper.ControlInfo[key];
    },

    GetControlInfoByShortcut: function (shortcut) {
        for (var controlKey in filterHelper.ControlInfo) {
            if (filterHelper.ControlInfo[controlKey].Shortcut == shortcut)
                return filterHelper.ControlInfo[controlKey];
        }
    },

    ShowLoadingAnimation: function () {
        var resultList = $get("SearchResultList");
        var loadingAnimation = $get("LoadingDummy");
        filterHelper.ClearResultList();

        resultList.innerHTML = loadingAnimation.innerHTML;
    },

    UpdateSearch: function (overrideDelay, source) {
        if (window.location.href.search(/ResultPage/) != -1) {
            for (var i = 0; i < filterHelper.SkipNextUpdateBy.length; i++) {
                if (filterHelper.SkipNextUpdateBy[i] == source) {
                    delete (filterHelper.SkipNextUpdateBy[i]);
                    return;
                }
            }

            if (filterHelper.UpdateFilterTimer)
                window.clearTimeout(filterHelper.UpdateFilterTimer);

            if (!overrideDelay) {
                overrideDelay = 1000;
            }

            filterHelper.UpdateFilterTimer = window.setTimeout("filterHelper._UpdateSearchWrapped('" + source + "')", overrideDelay);
        }
    },

    _UpdateSearchWrapped: function (source) {
        if (!filterHelper.SearchPending && (filterHelper.LastSearchLocation != filterHelper.LastLocation)) {
            if ((filterHelper.CurrentPagingPage != 1) && (source != "SwitchToPagingPage")) {
                filterHelper.SwitchToPagingPage(1);
                return;
            }

            filterHelper.SearchIsDirty = false;

            // Close all open modal-popups when changing filter.
            // [MB]
            if (source != "Init") {
                if (modalHelper && modalHelper.HideModal)
                    modalHelper.HideModal();
                if (detailsViewHelper && detailsViewHelper.HideDetails)
                    detailsViewHelper.HideDetails();
            }

            // Start the new search.
            // [MB]
            filterHelper.SearchPending = true;
            filterHelper.RedoSearch = false;
            filterHelper.ShowLoadingAnimation();
            var extension = filterHelper.BuildLocationExtension();

            filterHelper.UpdateLocationBar(extension);
            filterHelper.LastSearchLocation = extension;

            filterHelper.LastSearchStart = new Date();
            var request = requestHelper.BuildSearchRequest(extension, filterHelper.CurrentSearchField, filterHelper.CurrentSearchDirection, filterHelper.CurrentStartItem, filterHelper.CurrentEndItem);
            services.corpussireomakler.de.SearchService.v1.ISearchService._staticInstance.Search(request, filterHelper.SearchSuccess, filterHelper.SearchFailure);
        }
        else if (filterHelper.LastSearchLocation != filterHelper.LastLocation) {
            filterHelper.RedoSearch = true;
        }
    },

    BuildLocationExtension: function () {
        var extension = "";

        for (var key in filterHelper.ControlInfo) {
            var controlInfo = filterHelper.ControlInfo[key];

            // TODO: Remove everything but the else-clause, if the buzzwords get reenabled.
            // [MB]
            if (key == "TbBuzzwordSearch") {
                extension += "bw{}";
            }
            else {
                extension += filterHelper.GetFilterValueString(controlInfo.Type, controlInfo.Key);
            }
        }

        return extension;
    },

    StoreFragments: function (fragments) {
        $get("SbFragments").value = fragments;
    },

    UpdateLocationBar: function (extension) {
        if (!extension)
            extension = filterHelper.BuildLocationExtension();

        var address = GetCurrentURL() + "/Search/ResultPage.aspx#";

        $get(GetControlId("HfFragments")).value = extension;
        filterHelper.LastLocation = address + extension;

        filterHelper.StoreFragments(extension);

        // VERY VERY IMPORTANT for the telerik sliders... if this is reloaded here, the sliders think they should update themselves and fire the init events again!
        // [MB]
        var extensionWithHash = "#" + extension;
        if (window.location.hash != extensionWithHash) {
            window.location.hash = extensionWithHash;
        }
    },

    ClearResultList: function () {
        var resultList = $get("SearchResultList");
        resultList.innerHTML = "";
    },

    SearchSuccess: function (serviceResponse) {
        filterHelper.SearchPending = false;
        filterHelper.LastSearchEnd = new Date();
        var resultList = $get("SearchResultList");
        filterHelper.ClearResultList();

        if (serviceResponse.HasResult && serviceResponse.Success && (serviceResponse.Result.SearchResults || serviceResponse.Result.TopSearchResults)) {
            filterHelper.LastResultList = serviceResponse.Result.SearchResults;
            filterHelper.LastTopResultList = serviceResponse.Result.TopSearchResults;
            filterHelper.LastResultCount = serviceResponse.Result.AbsoluteRows;
            filterHelper.LastPrices = serviceResponse.Result.Prices;
            filterHelper.CompleteListRealtyIDs = serviceResponse.Result.RealtyDSNs;

            if (filterHelper.IsFirstRequest) {
                filterHelper.IsFirstRequest = false;

                filterHelper.UpdateSliderMaxValues(
                {
                    MaxNumberOfRooms: serviceResponse.Result.MaxNumberOfRooms,
                    MaxSurface: serviceResponse.Result.MaxSurface
                });

                filterHelper.UpdateRealtyTypeDropdowns(serviceResponse.Result.RealtyDefinitions);
            }

            filterHelper.UpdatePriceSlider();
            filterHelper.RenderResultList(filterHelper.CurrentPagingPage);

            filterHelper.EvaluateSubsidiaries((filterHelper.LastResultList) ? filterHelper.LastResultList : filterHelper.LastTopResultList);

            // Appending link tag.
            // [MB]
            if (Sys.Browser.agent == Sys.Browser.Firefox)
                filterHelper.AddRssHeader();
        }
        else {
            resultList.innerHTML = "<div class=\"EmptyPage\" style=\"padding:15px 0px 0px 20px; width:480px; text-align:left; font-family:Times New Roman; font-size:13px;\" class=\"Text\"><div class=\"Headline\">Leider ergab Ihre Suche keine Ergebnisse.</div>Geben Sie bitte nicht auf: Sie können Ihre Suchkriterien ändern, indem Sie die Regler auf der linken Seite bewegen.<br /><br />Sollten Sie nach längerer Suche kein passendes Angebot finden, schicken Sie uns bitte Ihren <span style=\"font-weight:bolder; cursor:pointer; font-family:arial;\" class=\"TextWithGrayArrow\" onclick=\"modalHelper.ShowModal('Wishlist'); return false;\">WUNSCHZETTEL</span>. Wir kümmern uns um passende Angebote für Sie.<br /><br />Die CORPUS SIREO Makler konzentrieren sich auf die Standorte Düsseldorf, Köln / Bonn sowie Raum Frankfurt am Main. Dort stehen unseren Kunden über 100 Mitarbeiter mit Immobilienwissen und lokalem Know How zur Verfügung. Im nationalen Vergleich sind wir unter den Top Ten der deutschen Immobilienvermittler.<br /><br /><br />Ihr CORPUS SIREO Makler-Team<br /><br /><b>Sie erreichen uns unter:<br /><br /><span style=\"font-family:arial; font-size:12px;\">0221 4737-700 für Köln<br />0228 606-2406 für Bonn<br />0211 878-3377 für Düsseldorf<br />069 97 908-0  für Rhein-Main</span></b></div>";
            RebindLinkHovers();
        }

        filterHelper.CheckForRedoSearch();
    },

    EvaluateSubsidiaries: function (resultList) {
        var phoneOfCologne = "0221 4737-700"
        var subsidiaryPhones = {
            "Frankfurt": "069 97908-0",
            "Duesseldorf": "0211 878-3377",
            "Bonn": "0228 606-2406",
            "Koeln": "0221 4737-700"
        }

        var ddorfMixedPhone = "0211 15978-444";
        var ddorfPhones = {
            "Bestand": "0211 878-3388",
            "Altbau": "0211 878-3388",
            "Neubau": "0211 15978-110"
        }

        var foundSubsidiaries = {};
        var foundSubCount = 0;
        var foundObjectAges = {};
        var foundObjectAgesCount = 0;
        if (resultList) {
            for (var resultNum = 0; resultNum < resultList.length; resultNum++) {
                var resultItem = resultList[resultNum];

                var sub = resultItem.Subsidiary;
                if (sub && subsidiaryPhones[sub] && !foundSubsidiaries[sub]) {
                    foundSubsidiaries[sub] = 1;
                    foundSubCount++;
                }

                var objectAge = resultItem.ObjectAge;
                if (objectAge && !foundObjectAges[objectAge]) {
                    foundObjectAges[objectAge] = 1;
                    foundObjectAgesCount++;
                }
            }
        }

        // If we were able to identify a specific subsidiary, use its number - otherwise cologne as fallback.
        // [MB]
        var subsidiaryToUse = "";
        var numberToUse = "";

        if (foundSubCount == 1) {
            for (var sub in foundSubsidiaries) {
                subsidiaryToUse = sub;

                if (sub == "Duesseldorf") {
                    if (foundObjectAgesCount == 1) {
                        for (var singleObjectAge in foundObjectAges) {
                            numberToUse = ddorfPhones[singleObjectAge];
                            break;
                        }
                    }
                    else {
                        numberToUse = ddorfMixedPhone;
                    }
                }
                else {
                    numberToUse = subsidiaryPhones[sub];
                }

                break;
            }
        }
        else {
            numberToUse = phoneOfCologne;
        }

        pagePartHelper.UpdateInternetContactPhone(numberToUse);
        pagePartHelper.UpdateSubsidiaryRelatedBanner(subsidiaryToUse);
    },

    BuildRssLink: function (rssAddress) {
        return "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"CORPUS SIREO Search Feed\" href=\"" + rssAddress + "\">"
    },

    AddRssHeader: function () {
        var rssAddress = GetCurrentRssFeed();
        var headElements = document.getElementsByTagName("head");
        if (headElements.length > 0) {
            filterHelper.RemoveRssHeaders();
            headElements[0].innerHTML += filterHelper.BuildRssLink(rssAddress);
        }
    },

    RemoveRssHeaders: function () {
        var linkElements = document.getElementsByTagName("link");
        var headElements = document.getElementsByTagName("head");

        if (headElements.length > 0) {
            for (var i = 0; i < linkElements.length; i++) {
                if (linkElements[i].type == "application/rss+xml") {
                    headElements[0].removeChild(linkElements[i]);
                }
            }
        }
    },

    UpdateRealtyTypeDropdowns: function (realtyDefinitions) {
        if (realtyDefinitions) {
            filterHelper.RealtyDefinitions = {};
            for (var i = 0; i < realtyDefinitions.length; i++) {
                var rd = realtyDefinitions[i];

                if (!filterHelper.RealtyDefinitions[rd.RealtyType])
                    filterHelper.RealtyDefinitions[rd.RealtyType] = [];

                filterHelper.RealtyDefinitions[rd.RealtyType][filterHelper.RealtyDefinitions[rd.RealtyType].length] = rd.RealtyStyle;
            }


            var realtyTypeList = $j("#" + GetControlId("DdlRealtyType"));
            if (realtyTypeList && (realtyTypeList.length > 0)) {
                var realtyTypes = realtyTypeList.get(0);

                if (realtyTypes) {
                    var itemsToDelete = [];
                    for (var realtyOptNum = 0; realtyOptNum < realtyTypes.options.length; realtyOptNum++) {
                        var optVal = realtyTypes.options[realtyOptNum].value;

                        if (optVal && (!filterHelper.RealtyDefinitions[optVal]))
                            itemsToDelete[itemsToDelete.length] = realtyOptNum;
                    }

                    for (var itemToDelIdx = (itemsToDelete.length - 1); itemToDelIdx >= 0; itemToDelIdx--) {
                        realtyTypes.options[itemsToDelete[itemToDelIdx]] = null;
                    }
                }
            }
        }
    },

    UpdateCascading: function (item) {
        var cascadingControlId = GetControlId("DdlRealtySubType");

        if (cascadingControlId) {
            var cascadingList = $get(cascadingControlId);
            cascadingList.style.display = "block";

            if (cascadingList) {
                ClearDropdownList(cascadingList);

                if (item && (item.selectedIndex >= 0)) {
                    var selectedOption = item.options[item.selectedIndex];

                    if (selectedOption) {
                        var realtySubTypes = filterHelper.RealtyDefinitions[selectedOption.value];

                        if (realtySubTypes) {
                            for (var subTypeNum = 0; subTypeNum < realtySubTypes.length; subTypeNum++) {
                                var subTypeVal = realtySubTypes[subTypeNum];
                                AddDropdownOption(cascadingList, subTypeVal, subTypeVal);
                            }
                        }
                        else {
                            cascadingList.style.display = "none";
                        }
                    }
                }
            }
        }
    },

    SortResultList: function () {
        if (filterHelper.SortDropdown) {
            var sortProperties = filterHelper.SortDropdown.options[filterHelper.SortDropdown.selectedIndex].value.split(/ /);
            if (sortProperties.length == 2) {
                filterHelper.CurrentSearchField = sortProperties[0];
                filterHelper.CurrentSearchDirection = sortProperties[1];

                filterHelper.SearchIsDirty = true;
                filterHelper.SwitchToPagingPage(1);
            }
        }
    },

    UpdatePriceSlider: function () {
        var sectionResults = [];
        var biggestSectionValue = 0;
        var allValue = 0;
        if (filterHelper.LastPrices) {
            for (var resultNum = 0; resultNum < filterHelper.LastPrices.length; resultNum++) {
                var price = parseInt(filterHelper.LastPrices[resultNum]);

                if (price == 0)
                    continue;

                var sectionIdx = priceSlider.GetSectionIndexByValue(price);

                if (!sectionResults[sectionIdx]) {
                    sectionResults[sectionIdx] = 1;
                }
                else {
                    sectionResults[sectionIdx]++;

                    if (biggestSectionValue < sectionResults[sectionIdx])
                        biggestSectionValue = sectionResults[sectionIdx];
                }

                allValue += price;
            }

            var medianPrice = Math.round(allValue / filterHelper.LastPrices.length);
            var medianPosition = priceSlider.GetPixelByValue(medianPrice) - 3; // 3: Half median width. [MB]

            // Prevent errors.
            // [MB]
            if (medianPosition < 0)
                medianPosition = 0;

            if (medianPosition > 0) {
                $j("#Median").css("display", "block").css("left", medianPosition);
            }
            else {
                $j("#Median").css("display", "none");
            }

            for (var sectionNum = 0; sectionNum < priceSlider.Sections.length; sectionNum++) {
                if (sectionResults[sectionNum]) {
                    var percentage = (sectionResults[sectionNum] / biggestSectionValue) * 100;
                    priceSlider.SetPercentageOfSection(priceSlider.GetSectionByIdx(sectionNum), percentage);
                }
                else {
                    priceSlider.SetPercentageOfSection(priceSlider.GetSectionByIdx(sectionNum), 0);
                }
            }
        }
    },

    GetMaxSurfaceFromResultItem: function (singleResult) {
        var maxSurfaceArea = 0;

        var sa = parseInt(singleResult.BusinessAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.LaboratoryAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.LandAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.LivingAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.OfficeSpaceInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.ProductionAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.TotalBusinessAreaInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;
        var sa = parseInt(singleResult.UseableSurfaceInSquareMeters)
        if (sa > maxSurfaceArea)
            maxSurfaceArea = sa;

        return maxSurfaceArea;
    },

    UpdateSliderMaxValues: function (maxValues) {
        if (maxValues) {
            // Because there's no update here (we only set the maxValues of the current search) we do not want to redo the search.
            // [MB]
            filterHelper.SkipNextUpdateBy[filterHelper.SkipNextUpdateBy.length] = "RsRooms";
            filterHelper.SkipNextUpdateBy[filterHelper.SkipNextUpdateBy.length] = "RsSurface";

            // Update room slider.
            // [MB]
            var clientIdOfRoomSlider = GetControlId("RsRooms");
            if (clientIdOfRoomSlider) {
                var roomSlider = $find(clientIdOfRoomSlider);

                if (roomSlider) {
                    roomSlider.set_maximumValue(maxValues.MaxNumberOfRooms);
                    roomSlider.set_selectionEnd(maxValues.MaxNumberOfRooms);
                }
            }

            // Update room slider.
            // [MB]
            var clientIdOfSurfaceSlider = GetControlId("RsSurface");
            if (clientIdOfSurfaceSlider) {
                var surfaceSlider = $find(clientIdOfSurfaceSlider);

                if (surfaceSlider) {
                    surfaceSlider.set_maximumValue(maxValues.MaxSurface);
                    surfaceSlider.set_selectionEnd(maxValues.MaxSurface);
                }
            }
        }
    },

    _GeneratePagingMenu: function (currentPagingPage) {
        filterHelper.PageCount = Math.ceil(filterHelper.LastResultCount / filterHelper.ItemsPerPage);

        var newPagingMenu = "";
        var insertPlaceholders = (filterHelper.PageCount > 7);

        if (insertPlaceholders) {
            if (currentPagingPage <= 4) {
                newPagingMenu += filterHelper.GetPagingMenuEntry(1, 1) + " | ";
                for (var pagingNum = 2; pagingNum <= 5; pagingNum++) {
                    if (pagingNum != filterHelper.PageCount) {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum) + " | ";
                    }
                    else {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum);
                    }
                }
                newPagingMenu += filterHelper.GetPagingMenuEntry("...", 0) + " | ";
                newPagingMenu += filterHelper.GetPagingMenuEntry(filterHelper.PageCount, filterHelper.PageCount);
            }
            else if (currentPagingPage > filterHelper.PageCount - 4) {
                newPagingMenu += filterHelper.GetPagingMenuEntry(1, 1) + " | ";
                newPagingMenu += filterHelper.GetPagingMenuEntry("...", 0) + " | ";
                for (var pagingNum = filterHelper.PageCount - 4; pagingNum < filterHelper.PageCount; pagingNum++) {
                    if (pagingNum != filterHelper.PageCount) {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum) + " | ";
                    }
                    else {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum);
                    }
                }
                newPagingMenu += filterHelper.GetPagingMenuEntry(filterHelper.PageCount, filterHelper.PageCount);
            }
            else {
                newPagingMenu += filterHelper.GetPagingMenuEntry(1, 1) + " | ";
                newPagingMenu += filterHelper.GetPagingMenuEntry("...", 0) + " | ";
                for (var pagingNum = currentPagingPage - 1; pagingNum <= currentPagingPage + 1; pagingNum++) {
                    if (pagingNum != filterHelper.PageCount) {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum) + " | ";
                    }
                    else {
                        newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum);
                    }
                }
                newPagingMenu += filterHelper.GetPagingMenuEntry("...", 0) + " | ";
                newPagingMenu += filterHelper.GetPagingMenuEntry(filterHelper.PageCount, filterHelper.PageCount);
            }
        }
        else {
            for (var pagingNum = 1; pagingNum <= filterHelper.PageCount; pagingNum++) {
                if (pagingNum != filterHelper.PageCount) {
                    newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum) + " | ";
                }
                else {
                    newPagingMenu += filterHelper.GetPagingMenuEntry(pagingNum, pagingNum);
                }
            }
        }

        $get("PagingMenu").innerHTML = newPagingMenu;
    },

    IncreaseCurrentPagingPage: function () {
        if (filterHelper.CurrentPagingPage < filterHelper.PageCount) {
            filterHelper.SearchIsDirty = true;
            filterHelper.CurrentPagingPage++;
            filterHelper.SwitchToPagingPage(filterHelper.CurrentPagingPage);
        }
    },

    DecreaseCurrentPagingPage: function () {
        if (filterHelper.CurrentPagingPage > 1) {
            filterHelper.SearchIsDirty = true;
            filterHelper.CurrentPagingPage--;
            filterHelper.SwitchToPagingPage(filterHelper.CurrentPagingPage);
        }
    },

    GetPagingMenuEntry: function (text, targetPage, selected) {
        var sel = (filterHelper.CurrentPagingPage == targetPage) ? "color:#559CB3;" : "";

        if (targetPage == 0) {
            return "<span>" + text + "</span>";
        }

        return "<span style=\"cursor:pointer; " + sel + "\" onclick=\"filterHelper.SwitchToPagingPage(" + targetPage + ")\">" + text + "</span>";
    },

    SetItemsPerPage: function (newValue) {
        var parsedValue = parseInt(newValue);

        if (parsedValue) {
            filterHelper.ItemsPerPage = parsedValue;

            filterHelper.SearchIsDirty = true;
            filterHelper.SwitchToPagingPage(1);
        }
    },

    SwitchToPagingPage: function (targetPage) {
        if (filterHelper.CurrentPagingPage != targetPage)
            filterHelper.SearchIsDirty = true;

        if (filterHelper.SearchIsDirty) {
            filterHelper.CurrentPagingPage = targetPage;

            var startItem = (targetPage - 1) * filterHelper.ItemsPerPage;
            var endItem = startItem + filterHelper.ItemsPerPage;

            if (startItem >= filterHelper.LastResultCount)
                return;

            if (endItem > filterHelper.LastResultCount)
                endItem = filterHelper.LastResultCount;


            filterHelper.CurrentStartItem = startItem;
            filterHelper.CurrentEndItem = endItem;

            filterHelper.UpdateSearch(1, 'SwitchToPagingPage');
        }
    },

    RenderResultList: function (targetPage) {
        var newListHTML = "";

        if (filterHelper.LastTopResultList) {
            if ((targetPage == 1) && filterHelper.LastTopResultList) {
                filterHelper.DisplayingTopItems = true;
                for (var topResultNum = 0; topResultNum < filterHelper.LastTopResultList.length; topResultNum++) {
                    newListHTML += filterHelper.GenerateResultItemHTML(filterHelper.LastTopResultList[topResultNum], true);
                }
            }
            else {
                filterHelper.DisplayingTopItems = false;
            }
        }

        if (filterHelper.LastResultList) {
            for (var resultNum = 0; resultNum < filterHelper.LastResultList.length; resultNum++) {
                newListHTML += filterHelper.GenerateResultItemHTML(filterHelper.LastResultList[resultNum]);
            }
        }

        filterHelper._GeneratePagingMenu(targetPage);
        $get("SearchResultList").innerHTML = newListHTML;
    },

    SearchFailure: function (serviceResponse) {
        filterHelper.SearchPending = false;
        alert("failed");

        filterHelper.CheckForRedoSearch();
    },

    CheckForRedoSearch: function () {
        if (filterHelper.RedoSearch) {
            filterHelper.UpdateSearch(1, 'Redo');
        }
    },

    GenerateResultItemHTML: function (result, isTopElement) {
        if (result) {
            var newHTML = $get("SearchResultDummy").innerHTML;

            if (result.Pictures && (result.Pictures.length > 0)) {
                newHTML = newHTML.replace(/\{Image\}/, result.Pictures[0].replace(/\[PLACEHOLDER\]/, "normal"));
                newHTML = newHTML.replace(/%7BImage%7D/, result.Pictures[0].replace(/\[PLACEHOLDER\]/, "normal"));
            }
            else {
                newHTML = newHTML.replace(/\{Image\}/, "/Images/Spacer.gif");
                newHTML = newHTML.replace(/%7BImage%7D/, "/Images/Spacer.gif");
            }

            newHTML = newHTML.replace(/\[\[\[/, "<");
            newHTML = newHTML.replace(/\]\]\]/, ">");

            newHTML = newHTML.replace(/\{TopMarker\}/, (!isTopElement) ? "" : "<div class=\"TopMarkerElement\">TOP</div>");
            newHTML = newHTML.replace(/\{OnClickHandler\}/, "detailsViewHelper.ShowDetails(" + result["ID"] + ")");
            newHTML = newHTML.replace(/\{Headline\}/, result["Headline"].toUpperCase() + " (" + result["ID"] + ")");
            newHTML = newHTML.replace(/\{Location\}/, result["Location"]);
            newHTML = newHTML.replace(/\{Surface\}/, result.LivingAreaInSquareMeters + " m<sup>2</sup>"); //filterHelper.GetMaxSurfaceFromResultItem(result) + " m<sup>2</sup>");
            newHTML = newHTML.replace(/\{BusinessArea\}/, (result.BusinessAreaInSquareMeters) ? "<tr><td class=\"Key\">Gewerbefläche:</td><td class=\"Value\">" + result.BusinessAreaInSquareMeters + " m<sup>2</sup></td></tr>" : "");

            if (result["NumberOfRooms"] && (result["NumberOfRooms"] != 0)) {
                newHTML = newHTML.replace(/\{NumberOfRooms\}/, result["NumberOfRooms"]);
            }
            else {
                if (document.all) {
                    newHTML = newHTML.replace("NumberOfRoomsRow", "NumberOfRoomsRow style=\"display:none;\"");
                }
                else {
                    newHTML = newHTML.replace("\"NumberOfRoomsRow\"", "\"NumberOfRoomsRow\" style=\"display:none;\"");
                }
            }

            if (result["PurchasePriceInEuro"] && (result["PurchasePriceInEuro"] != 0)) {
                newHTML = newHTML.replace(/\{Price\}/, CreateGermanPrice(result["PurchasePriceInEuro"]));
            }
            else {
                if (document.all) {
                    newHTML = newHTML.replace("PriceRow", "PriceRow style=\"display:none;\"");
                }
                else {
                    newHTML = newHTML.replace("\"PriceRow\"", "\"PriceRow\" style=\"display:none;\"");
                }
            }

            return newHTML;
        }

        return "";
    },

    RegisterWrappedSlider: function (controlKey, sliderMiddleAt, valueMiddleAt) {
        var clientId = GetControlId(controlKey);

        if (clientId) {
            filterHelper.ExponentialSliderValues[clientId] = {
                SliderMiddleAt: sliderMiddleAt,
                ValueMiddleAt: valueMiddleAt
            };
        }
    },

    GetUnwrappedSliderValue: function (valueToUnwrap, minVal, maxVal, clientId) {
        if (filterHelper.ExponentialSliderValues[clientId]) {
            var sliderConfig = filterHelper.ExponentialSliderValues[clientId];

            var leftPartMaxValue = maxVal * (sliderConfig.ValueMiddleAt / 100);

            // Check if we are on the left or right side of the slider.
            // [MB]
            if (leftPartMaxValue > valueToUnwrap) {
                // Check where we are at the wrapped slider.
                // [MB]
                var percentageOnLeftSide = (100 / leftPartMaxValue) * valueToUnwrap;

                // Check where we are at the unwrapped slider.
                // [MB]
                var unwrappedPercentage = sliderConfig.SliderMiddleAt * (percentageOnLeftSide / 100);

                // Get the value of the unwrapped slider.
                // [MB]
                valueToUnwrap = maxVal * (unwrappedPercentage / 100);
            }
            else {
                // Check where we are at the wrapped slider.
                // [MB]
                var valuesOnRightSide = valueToUnwrap - leftPartMaxValue;

                // Get unwrapped percentage of slider.
                // [MB]
                var wrappedPercentageOnRightSide = valuesOnRightSide / (maxVal - leftPartMaxValue);
                var unwrappedPercentageOnRightSide = ((100 - sliderConfig.SliderMiddleAt) * wrappedPercentageOnRightSide)
                var fullPercentage = unwrappedPercentageOnRightSide + sliderConfig.SliderMiddleAt;

                // Get unwrapped value.
                // [MB]
                valueToUnwrap = maxVal * (fullPercentage / 100);
            }
        }

        return Math.floor(valueToUnwrap);
    },

    GetWrappedSliderValue: function (valueToWrap, minVal, maxVal, clientId) {
        if (filterHelper.ExponentialSliderValues[clientId]) {
            var sliderConfig = filterHelper.ExponentialSliderValues[clientId];
            var percentageOnSlider = (valueToWrap / maxVal) * 100;

            if (sliderConfig.SliderMiddleAt > percentageOnSlider) {
                // How many percents are we into the left side?
                // [MB]
                var percentageOfLeftPart = (percentageOnSlider / sliderConfig.SliderMiddleAt) * 100;
                // How many values are assigned to the left side of the slider?
                // [MB]
                var leftSideValues = maxVal * (sliderConfig.ValueMiddleAt / 100);
                // At which value are we on the left side?
                // [MB]
                valueToWrap = leftSideValues * (percentageOfLeftPart / 100);
            }
            else {
                // How many percents are we into the right side?
                // [MB]
                var percentageOfSliderOnRightSide = percentageOnSlider - sliderConfig.SliderMiddleAt;
                var percentageOfRightPart = (percentageOfSliderOnRightSide / (100 - sliderConfig.SliderMiddleAt)) * 100;
                // How many values are assigned to the right side of the slider?
                // [MB]
                var rightPartValuePercentage = 100 - sliderConfig.ValueMiddleAt;
                var rightSideValues = maxVal * (rightPartValuePercentage / 100);
                // At which value are we on the right side?
                // [MB]
                var rightSideCurrentValue = rightSideValues * (percentageOfRightPart / 100);
                // At which value are we overall?
                // [MB]
                var leftPartMaxValue = maxVal * (sliderConfig.ValueMiddleAt / 100);
                valueToWrap = leftPartMaxValue + rightSideCurrentValue;
            }
        }

        return Math.floor(valueToWrap);
    },

    GetFilterValueString: function (type, controlId, groupShortcut) {
        clientId = GetControlId(controlId);
        groupShortcut = filterHelper.GetControlInfo(controlId).Shortcut;

        switch (type) {
            case FILTER_TYPE_SLIDER:
                if (clientId) {
                    var slider = $find(clientId);

                    if (slider) {
                        var minVal = slider.get_minimumValue();
                        var maxVal = slider.get_maximumValue();
                        var startVal = slider.get_selectionStart();
                        var endVal = slider.get_selectionEnd();

                        if (minVal == startVal)
                            startVal = "MIN";
                        if (maxVal == endVal)
                            endVal = "MAX";

                        // If we haven't reached the outer borders of the slider, recalculate the values to allow exponential values.
                        // Round specific values before updating location.
                        // [MB]
                        if (startVal != "MIN") {
                            startVal = filterHelper.GetWrappedSliderValue(startVal, minVal, maxVal, clientId);

                            if (controlId == "RsPrice") {
                                startVal = RoundValue(startVal, 1000);
                            }
                            else if (controlId == "RsSurface") {
                                startVal = RoundValue(startVal, 10);
                            }
                        }
                        if (endVal != "MAX") {
                            endVal = filterHelper.GetWrappedSliderValue(endVal, minVal, maxVal, clientId);

                            if (controlId == "RsPrice") {
                                endVal = RoundValue(endVal, 1000);
                            }
                            else if (controlId == "RsSurface") {
                                endVal = RoundValue(endVal, 10);
                            }
                        }

                        return groupShortcut + "{" + startVal + "," + endVal + "}";
                    }
                }

                break;
            case FILTER_TYPE_DROPDOWN:
                if (clientId) {
                    var dropDown = $get(clientId);

                    if (dropDown)
                        return groupShortcut + "{" + dropDown.options[dropDown.selectedIndex].value + "}";
                }

                break;
            case FILTER_TYPE_TEXTBOX:
            case FILTER_TYPE_HIDDEN:
                if (clientId) {
                    var hidden = $get(clientId);

                    if (hidden)
                        return groupShortcut + "{" + hidden.value + "}";
                }

                break;
        }

        return "";
    },

    UpdateTextboxesBySlider: function (slider, type, tbStartId, tbEndId) {
        if (slider) {
            var minVal = slider.get_minimumValue();
            var maxVal = slider.get_maximumValue();
            var startVal = slider.get_selectionStart();
            var endVal = slider.get_selectionEnd();

            var sliderId = slider._uniqueID;
            while (sliderId.search(/\$/) > -1) {
                sliderId = sliderId.replace(/\$/, "_");
            }

            var tbStart = $j("#" + tbStartId).get(0);
            var tbEnd = $j("#" + tbEndId).get(0);

            startVal = filterHelper.GetWrappedSliderValue(startVal, minVal, maxVal, sliderId);
            endVal = filterHelper.GetWrappedSliderValue(endVal, minVal, maxVal, sliderId);



            if (type == "Price") {

                if (endVal == 1000001)
                    endVal = "";

                startVal = RoundValue(startVal, 1000);
                if (endVal != "")
                    endVal = RoundValue(endVal, 1000);
                minVal = RoundValue(minVal, 1000);
                maxVal = RoundValue(maxVal, 1000);

                minVal = priceSlider.GetValueToDisplay(minVal).ValueToReturn;
                maxVal = priceSlider.GetValueToDisplay(maxVal).ValueToReturn;
            }
            else if (type == "Surface") {
                startVal = RoundValue(startVal, 10);
                endVal = RoundValue(endVal, 10);
                minVal = RoundValue(minVal, 10);
                maxVal = RoundValue(maxVal, 10);
            }

            if (startVal == 0)
                startVal = 1;
            if (endVal === 0)
                endVal = 1;

            var newValue = "";
            if ((minVal == startVal) && (maxVal == endVal)) {
                tbStart.value = "1";
                tbEnd.value = "";
            }
            else if (minVal == startVal) {
                tbStart.value = "1";
                tbEnd.value = endVal;
            }
            else if (maxVal == endVal) {
                tbStart.value = startVal;
                tbEnd.value = "";
            }
            else {
                if (startVal == endVal) {
                    tbStart.value = startVal;
                    tbEnd.value = startVal;
                }
                else {
                    tbStart.value = startVal;
                    tbEnd.value = endVal;
                }
            }
        }
    },

    UpdateStartValue: function (sender, sliderKey) {
        filterHelper.UpdateSliderValue(sliderKey, sender.value, "Start", sender);
    },

    UpdateEndValue: function (sender, sliderKey) {
        filterHelper.UpdateSliderValue(sliderKey, sender.value, "End", sender);
    },

    UpdateSliderValue: function (sliderKey, newValue, endType, sender) {
        var sliderClientId = GetControlId(sliderKey);

        if (sliderClientId) {
            var sliderToChange = $find(sliderClientId);
            var minVal = sliderToChange.get_minimumValue();
            var maxVal = sliderToChange.get_maximumValue();

            while (newValue.match(/[^0-9]/))
                newValue = newValue.replace(/[^0-9]/, "");

            if (newValue == "")
                newValue = 0;

            var newValInt = parseInt(newValue);
            if (newValInt != sender.value)
                sender.value = (newValInt == 0) ? "" : newValInt;

            if (sliderToChange) {
                var unwrappedValue = filterHelper.GetUnwrappedSliderValue(newValInt, minVal, maxVal, sliderClientId);

                switch (endType) {
                    case "Start":
                        if (unwrappedValue < minVal)
                            unwrappedValue = 1;

                        sliderToChange.set_selectionStart(unwrappedValue);
                        break;
                    case "End":
                        if ((unwrappedValue > maxVal) || (unwrappedValue == 0))
                            unwrappedValue = maxVal;

                        sliderToChange.set_selectionEnd(unwrappedValue);
                        break;
                }
            }
        }
    }
}

var filterHelper = new FilterHelper();

$j(document).ready(function() {
    filterHelper.Init();
    filterHelper.StartLocationObserver();
});