/**
 * The suggestions context menu component of the search box for listings control.
 *
 * @requires
 *     jquery
 *     knockout
 */

var searchBoxSuggestions = (function () {

    var pub = {};
    var queryCache = {};

    pub.setCache = function (newCache) {
        ////newCache.suggestions = _.orderBy(newCache.suggestions, function (obj) {
        ////    return obj.areaName.toLowerCase();
        ////}, ['asc']);
        newCache.suggestions = _.orderBy(newCache.suggestions, ['isExactMatch', 'isCommunity', 'isUserLocationMatch', 'matchCount', 'isComByLocation', 'isCommunityCityMatched', function (obj) {
            return obj.areaName.toLowerCase();
        }, 'unit'], ['desc', 'asc', 'desc', 'desc', 'desc', 'desc', 'asc', 'asc']);
        queryCache = newCache;
    }

    pub.getSuggestions = function () {
        return queryCache.suggestions;
    }

    pub.cacheAvailable = function (searchText) {
        return queryCache.resultsComplete
            && (locationHelper.convertFromAbbreviationAreaName(searchText).toLowerCase().startsWith(locationHelper.convertFromAbbreviationAreaName(queryCache.searchText).toLowerCase())
            || locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(searchText)).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(queryCache.searchText)).toLowerCase()));
    }

    pub.filterCachedSuggestions = function (filter, userCounty) {
        var filteredSuggestions = [];

        queryCache.suggestions.forEach(function (item, index, array) {
            if (locationHelper.convertFromAbbreviationAreaName(item.areaName).toLowerCase().startsWith(locationHelper.convertFromAbbreviationAreaName(filter).toLowerCase())) {
                item.isExactMatch = true;
                filteredSuggestions.push(item);
            }
            // Check matchWithFreeFormText with AreaName(City/County Name + State Code)
            else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.areaName)).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            // Check matchWithFreeFormText with BaseAreaName(City/County Name + State Name)
            else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.baseAreaName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            else if (item.areaType.toLowerCase() == 'county' && locationHelper.matchWithFreeFormText(locationHelper.addCountyText(locationHelper.convertFromAbbreviationAreaName(item.baseAreaName), item.stateName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            // Check matchWithFreeFormText with Address + State Name
            else if (item.areaType.toLowerCase() == 'address' && locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(locationHelper.replaceStateCodeWithStateNameForAddress(item.areaName, item.stateCode, item.stateName))).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            else if (item.areaType.toLowerCase() == 'address') {
                var addressItem = locationHelper.getDetailedAddressItem(item);
                // Check matchWithFreeFormText with Address with State Code for St. Address
                if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(addressItem.addressLine + '.') + locationHelper.convertFromAbbreviationAreaName(addressItem.cityName) + addressItem.stateCode + addressItem.zipCode).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                    item.isExactMatch = false;
                    filteredSuggestions.push(item);
                }
                // Check matchWithFreeFormText with Address witj     State Name for St. Address
                else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(addressItem.addressLine + '.') + locationHelper.convertFromAbbreviationAreaName(addressItem.cityName) + addressItem.stateName + addressItem.zipCode).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                    item.isExactMatch = false;
                    filteredSuggestions.push(item);
                }
            }
            // Check Anywhere with community name OR community location
            else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.convertFromAbbreviationAreaName(item.areaName), locationHelper.convertFromAbbreviationAreaName(filter))) {
                item.isExactMatch = true;
                filteredSuggestions.push(item);
            }
            // Check matchWithFreeFormText Anywhere with community name OR community location + State Code
            else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.areaName)), locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)))) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            // Check matchWithFreeFormText Anywhere with community name OR community location + State Name
            else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(locationHelper.replaceStateCodeWithStateNameForCommunity(item.areaName, item.stateCode, item.stateName))), locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)))) {
                item.isExactMatch = false;
                filteredSuggestions.push(item);
            }
            // Check community with county location
            else if (item.areaType.toLowerCase() == 'neighborhood' && !helper.isUndefinedOrNullOrEmpty(item.countyName) && locationHelper.matchWithFreeFormText(locationHelper.addCountyText(locationHelper.convertFromAbbreviationAreaName(item.countyName), item.stateName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                item.isExactMatch = false;
                item.isComByLocation = 2;
                filteredSuggestions.push(item);
            }

            if (item.areaType.toLowerCase() == 'neighborhood' && !helper.isUndefinedOrNullOrEmpty(item.countyName) && !locationHelper.matchWithFreeFormText(locationHelper.addCountyText(locationHelper.convertFromAbbreviationAreaName(item.countyName), item.stateName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                // Check community county matching with searched location.
                if (locationHelper.matchWithFreeFormText(locationHelper.addCountyText(locationHelper.convertFromAbbreviationAreaName(item.countyName), item.stateName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(filter)).toLowerCase())) {
                    item.isComByLocation = 2;
                }
                // Check community county matching with user location's county
                else if (locationHelper.matchWithFreeFormText(locationHelper.addCountyText(locationHelper.convertFromAbbreviationAreaName(item.countyName), item.stateName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(userCounty)).toLowerCase())) {
                    item.isComByLocation = 1;
                }
                else {
                    item.isComByLocation = 0;
                }
            }
            // Zipcode has more priority over address.
            else if (item.areaType.toLowerCase() == 'zip') {
                item.isComByLocation = 2;
            }
            // Changing priority of addresses without unit.
            else if (item.areaType.toLowerCase() == 'address' && (helper.isUndefinedOrNullOrEmpty(item.unit) || item.unit === '0')) {
                item.isComByLocation = 1;
            }
            else {
                item.isComByLocation = 0;
            }
        });

        if (filteredSuggestions && filteredSuggestions.length > 0) {
            var filteredCommunitySuggestions = [];

            filteredSuggestions.forEach(function (item, index, array) {
                if (item.areaType.toLowerCase() == 'address' && item.isCommunity === true && item.communityId > 0 && !helper.isUndefinedOrNullOrEmpty(item.unit)) {
                    if (!pub.findParentAddressExistsInArray(item.communityId, filteredSuggestions)) {
                        filteredCommunitySuggestions.push(item);
                    }
                }
                else {
                    filteredCommunitySuggestions.push(item);
                }
            });

            filteredCommunitySuggestions = _.orderBy(filteredCommunitySuggestions, ['isExactMatch', 'isCommunity', 'isUserLocationMatch', 'matchCount', 'isComByLocation', 'isCommunityCityMatched', function (obj) {
                return obj.areaName.toLowerCase();
            }, 'unit'], ['desc', 'asc', 'desc', 'desc', 'desc', 'desc', 'asc', 'asc']);

            let uniqueObjArray = [
                ...new Map(filteredCommunitySuggestions.map((item) => [item["areaName"], item])).values(),
            ];

            return uniqueObjArray;
        }
        else {
            return filteredSuggestions;
        }
    }

    /**
        * finds parent community address in the array (value, array name) by value and returns is exists or not
    */
    pub.findParentAddressExistsInArray = function (communityId, arrayToSearch) {
        var item = ko.utils.arrayFirst(arrayToSearch, function (item) {
            return (item.communityId == communityId && helper.isUndefinedOrNullOrEmpty(item.unit))
        });

        return item != null;
    }

    return pub;
}());

/**
 * A control for searching for listings.
 *
 * @requires
 *     jquery
 *     knockout
 */

var go8SearchBoxForListings = (function () {
    try {
        var pub = {};
        pub.PageType = '';
        pub.isAvoidBlurSelection = false;
 
        var displayTextSubscription = null;
        var xhr = null;
        var isRunning = false;
        var maxRecentMatchToShow = 3;
        var maxSuggestionToShow = 10;
        var maxSuggestionsToSave = 10;
        var isTenantLogged = false;
        var isIE = /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);
        var tabSelectedIndex = 0;
        var isTabbed = false;
        var currentLocation = {};
        var currentLocationStorageName = "currentlocationdata";
        var queryTimer = null;
        var querySize = 1000;
        var isAbbreviationSearched = false;
        var isAbbreviationWithSpaceSearched = false;
        var isNonExactMatchItemSelected = false;
        var suggestions = searchBoxSuggestions;
        var isEdge = (window.navigator.userAgent.indexOf('Edge/') > 0);
        var userLocationByIP = {
            userCity: '',
            userCounty: '',
            userState: ''
        };
        var txtCurrentMapArea = 'Current Map Area';
        
        function init() {

            pub.previewText = ko.observable("");
            pub.displayText = ko.observable("");
            // Internal State
            lastSearch = $.cookie(lastsearchqueryCookieName);
            
            if (lastSearch != null && lastSearch != "") {
                pub.displayText = ko.observable(locationHelper.applyLocationCapitalization(lastSearch));
                pub.previewText = ko.observable(locationHelper.applyLocationCapitalization(lastSearch));
            }
            else if (document.createElement("input").placeholder == undefined) {
                pub.displayText = ko.observable(searchplaceholder);
            }
            else {
                pub.displayText = ko.observable("");
            }

            pub.showSuggestions = ko.observable(false);
            pub.showNoMatching = ko.observable(false);
            pub.selectedIndex = ko.observable(-1);
            pub.suggestionsBest = ko.observableArray();
            pub.ShowCurrentLocation = ko.observable(false);
            pub.showRecentMatching = ko.observable(false);
            pub.suggestionsRecent = ko.observableArray();
            pub.recentMatchCount = ko.observable(0);

            // Behaviors
            displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);

            pub.getUserCurrentLocation()
        }

        pub.initTenant = function () {
            if (isTenantLoggedIn()) {
                pub.isTenantLogged = true;
                pub.clearVisitorSearch();
                pub.ShowCurrentLocation(false);
                pub.showRecentMatching(false);
                pub.showSuggestions(false);
            }
            else if (headerModel.domain.user() && headerModel.domain.user().UserType().toLowerCase() === "landlord")
            {
                pub.clearVisitorSearch();
                pub.ShowCurrentLocation(false);
                pub.showRecentMatching(false);
                pub.showSuggestions(false);
            }
        };

        pub.onChangeSearchText = function (newValue) {
            if (queryTimer) {
                clearTimeout(queryTimer);
                queryTimer = null;
            }

            if (pub.isAvoidBlurSelection) {
                pub.isAvoidBlurSelection = false;
            }

            isNonExactMatchItemSelected = false;
            displayTextSubscription.dispose();
            pub.displayText(locationHelper.applyLocationCapitalization(helper.limitCharacters(pub.displayText())));

            displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);

            var text = pub.displayText();

            pub.ShowCurrentLocation(text.length == 0);

            if (text.length >= 3) {

                if (!pub.previewText().toLowerCase().startsWith(pub.displayText().toLowerCase())) {
                    pub.previewText("");
                }
                isAbbreviationSearched = /\b[smf]t[.]/i.test(text);
                isAbbreviationWithSpaceSearched = /\b[smf]t\s/i.test(text);

                var message =
                {
                    text: locationHelper.convertFromAbbreviationAreaName(locationHelper.removeCountyText(text)).replace(/\s+/g, ' ')
                };

                // Fetching recent data from cookie.
                var recentMatchBest = pub.getRecentData();

                //pub.suggestionsRecent(recentMatchBest.slice(0, maxRecentMatchToShow));
                pub.showRecentMatching(recentMatchBest != null && recentMatchBest.length > 0);
                if (recentMatchBest.length > maxRecentMatchToShow) {
                    pub.recentMatchCount(maxRecentMatchToShow);
                }
                else {
                    pub.recentMatchCount(recentMatchBest.length);
                }

                if (suggestions.cacheAvailable(message.text)) {
                    pub.displayAutoCompleteSuggestions(suggestions.filterCachedSuggestions(text, userLocationByIP.userCounty));
                }
                else {
                    if (!isRunning) {
                        isRunning = true;
                        message.size = querySize;
                        message.userCity = userLocationByIP.userCity;
                        message.userCounty = userLocationByIP.userCounty;
                        message.userState = userLocationByIP.userState;

                        xhr = $.ajax
                            ({
                                type: "post",
                                url: "/v4/AjaxHandlerUnauthenticated?message=ListingSearchAutocomplete",
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                data: JSON.stringify(message),
                                error: pub.autoCompleteOnError,
                                success: pub.autoCompleteOnSuccess
                            });
                    }
                }
            }
            else {
                pub.showNoMatching(false);
                pub.showSuggestions(false);
                pub.previewText("");
                pub.resetRecentMatching();
                pub.selectedIndex(-1);
                tabSelectedIndex = 0;
            }
        };

        pub.autoCompleteOnSuccess = function (result) {
            isRunning = false;
            if (pub.displayText().length < 3)
                return;

            suggestions.setCache(result);
            pub.displayAutoCompleteSuggestions(suggestions.filterCachedSuggestions(pub.displayText(), userLocationByIP.userCounty));
        };

        pub.displayAutoCompleteSuggestions = function (suggestionItems) {
            pub.selectedIndex(-1);
            var suggestionsBest = [];
            suggestionItems.forEach(function (item, index, array) {
                if (!item.displayAreaName)
                    item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                else
                    item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                /* Check if maximum suggestion records reached */
                /* Check if suggestion result item already exists in current recent matches */
                /* Check if suggestion result item matche with searchbar text (specially with county text) */
                if (maxSuggestionToShow > (pub.recentMatchCount() + suggestionsBest.length)
                    && !locationHelper.checkLocationExistsInArray(item, pub.suggestionsRecent())
                    && (helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(item.areaName)), locationHelper.matchWithFreeFormText(pub.displayText()))
                        || helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(item.baseAreaName) + item.stateName), locationHelper.matchWithFreeFormText(pub.displayText()))
                        || helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(locationHelper.addCountyText(item.baseAreaName, item.stateName)) + item.stateName), locationHelper.matchWithFreeFormText(pub.displayText()))
                        || helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(locationHelper.replaceStateCodeWithStateNameForAddress(item.areaName, item.stateCode, item.stateName))), locationHelper.matchWithFreeFormText(pub.displayText()))
                        || helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(locationHelper.replaceStateCodeWithStateNameForCommunity(item.areaName, item.stateCode, item.stateName))), locationHelper.matchWithFreeFormText(pub.displayText()))
                        || helper.strContainsNoCase(locationHelper.matchWithFreeFormText(resolvePreviewText(item.countyName) + item.stateName), locationHelper.matchWithFreeFormText(pub.displayText()))
                    )) {
                    suggestionsBest.push(item);
                }
            });

            pub.suggestionsBest(suggestionsBest);

            if (suggestionsBest !== null && suggestionsBest.length === 0 && pub.suggestionsRecent() !== null && pub.suggestionsRecent().length === 0) {
                pub.showNoMatching();
                pub.showSuggestions(false);
            }
            else {
                pub.showNoMatching(false);
                if (suggestionsBest !== null && suggestionsBest.length > 0) {
                    pub.showSuggestions(true);
                }
                else {
                    pub.showSuggestions(false);
                }

                var selecteditem = pub.getSelectedItem(0);
                if (selecteditem !== null && selecteditem.isExactMatch == true) {
                    if (selecteditem.areaName.toLowerCase().startsWith(pub.displayText().toLowerCase())) {
                        pub.previewText(resolvePreviewText(selecteditem.areaName));
                    }
                    else if (locationHelper.convertFromAbbreviationAreaName(selecteditem.areaName).toLowerCase().startsWith(locationHelper.convertFromAbbreviationAreaName(pub.displayText()).toLowerCase()) === true) {
                        pub.previewText(resolvePreviewText(selecteditem.areaName));
                    }
                    else {
                        pub.previewText("");
                    }
                }
                else if (selecteditem !== null && selecteditem.isExactMatch == false) {
                    pub.previewText("");
                    isNonExactMatchItemSelected = true;
                }
            }
        };

        pub.autoCompleteOnError = function (xhr, status, error) {
            isRunning = false;
        };

        pub.onClickItem = function (data, event) {
            pub.submit(data);
        };

        pub.onKeyDownSearchText = function (data, event) {
            var index, max;
            var bubbleEvent = true;

            var inputCode = (event.keyCode ? event.keyCode : event.which);

            if (inputCode === 13) // 'Enter'
            {
                pub.submitSearchedLocation();

                pub.showSuggestions(false);
                pub.selectedIndex(-1);
                bubbleEvent = false;
            }
            else if (inputCode === 27) // 'Escape'
            {
                if (isRunning && xhr != null) {
                    xhr.abort();
                    isRunning = false;
                }

                pub.selectedIndex(-1);
                pub.displayText("");
                pub.showSuggestions(false);
                pub.showRecentMatching(false);
                pub.showNoMatching(false);

                bubbleEvent = false;
            }
            else if (inputCode === 40) // 'Arrow Down'
            {
                index = pub.selectedIndex();

                max = pub.suggestionsBest().length + pub.recentMatchCount() - 1;

                if (index === null)
                    index = 0;
                else if (index < max)
                    index++;

                pub.selectedIndex(index);

                var selecteditem = pub.getSelectedItem(index);
                displayTextSubscription.dispose();
                pub.previewText("");
                if (selecteditem !== null) {
                    pub.displayText(selecteditem.areaName);
                }
                displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);

                bubbleEvent = false;
                tabSelectedIndex = index;
            }
            else if (inputCode === 38) // 'Arrow Up'
            {
                index = pub.selectedIndex();

                if (index === null)
                    index = 0;
                else if (index > 0)
                    index--;

                pub.selectedIndex(index);

                var selecteditem = pub.getSelectedItem(index);
                displayTextSubscription.dispose();
                pub.previewText("");
                if (selecteditem !== null) {
                    pub.displayText(selecteditem.areaName);
                }
                displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);

                bubbleEvent = false;
                tabSelectedIndex = index;
            }
            else if (inputCode === 9) // 'Tab'
            {
                if (isRunning && xhr != null) {
                    if (xhr != null) {
                        xhr.abort();
                    }

                    var suggestionsBest = [];
                    pub.selectedIndex(-1);
                    pub.suggestionsBest(suggestionsBest);

                    isRunning = false;
                }

                isTabbed = true;

                if (pub.selectedIndex() < 0) {
                    pub.selectedIndex(0);
                }

                var anyItem = pub.getSelectedItem(pub.selectedIndex());

                if (anyItem !== null) {
                    if (isIE && tabSelectedIndex === 0) {
                        pub.displayText(anyItem.areaName);
                    }
                }

                pub.isAvoidBlurSelection = true;
                pub.showSuggestions(false);
                pub.showRecentMatching(false);
                pub.showNoMatching(false);
            }

            return bubbleEvent;
        };

        pub.onClickSearchText = function () {
            if (txtCurrentMapArea == pub.displayText())
                return;

            if (helper.isUndefinedOrNullOrEmpty(pub.isTenantLogged)) {
                pub.isTenantLogged = false;
            }

            if (isTenantLoggedIn() && pub.isTenantLogged == false) {
                isTenantLogged = true;
                pub.clearVisitorSearch();
                pub.onChangeSearchText(pub.displayText());
            }
            else {
                pub.onChangeSearchText(pub.displayText());
            }
        };

        pub.onClickSearchButton = function () {
            pub.submitSearchedLocation();
        };

        pub.onKeyDownSearchButton = function (data, event) {
            var bubbleEvent = true;

            var inputCode = (event.keyCode ? event.keyCode : event.which);

            if (inputCode === 13) // 'Enter'
            {
                pub.submitSearchedLocation();

                pub.showSuggestions(false);
                pub.selectedIndex(-1);
                bubbleEvent = false;
            }
            tnResult.redirectUserToKoAfterLogin();
            return bubbleEvent;
        };

        pub.getRecentData = function ()
        {
            var recentMatchBest = [];
            var isUserLoggedIn = !helper.isUndefinedOrNullOrEmpty(headerModel.domain.user()) ? true : false;
            var recentMatchData = $.cookie(recentSearchCookieName);
            if (recentMatchData != null && recentMatchData != "") {
                recentMatchData = JSON.parse(recentMatchData);

                if (!helper.isUndefinedOrNullOrEmpty(recentMatchData))
                {
                    recentMatchData = _.filter(recentMatchData, function (item)
                    {
                        return item.isLoggedUserCookie == isUserLoggedIn;
                    });
                }

                if (recentMatchData != null && recentMatchData != "") {
                    recentMatchData.forEach(function (item, index, array) {
                        if (locationHelper.convertFromAbbreviationAreaName(item.areaName).toLowerCase().startsWith(locationHelper.convertFromAbbreviationAreaName(pub.displayText()).toLowerCase()) === true) {
                            item.isExactMatch = true;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check matchWithFreeFormText with AreaName(City/County Name + State Code)
                        else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.areaName)).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                            item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check matchWithFreeFormText with BaseAreaName(City/County Name + State Name)
                        else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(!helper.isUndefinedOrNullOrEmpty(item.baseAreaName) ? item.baseAreaName : "") + !helper.isUndefinedOrNullOrEmpty(item.stateName) ? item.stateName : "").toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                             item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check matchWithFreeFormText with Address + State Name
                        else if (item.areaType.toLowerCase() == 'address' && locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(locationHelper.replaceStateCodeWithStateNameForAddress(item.areaName, item.stateCode, item.stateName))).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                            item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        else if (item.areaType.toLowerCase() == 'address') {
                            var addressItem = locationHelper.getDetailedAddressItem(item);
                            // Check matchWithFreeFormText with Address with State Code for St. Address
                            if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(addressItem.addressLine + '.') + locationHelper.convertFromAbbreviationAreaName(addressItem.cityName) + addressItem.stateCode + addressItem.zipCode).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                                item.isExactMatch = false;

                                if (!item.displayAreaName)
                                    item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                                else
                                    item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                                recentMatchBest.push(item);
                            }
                            // Check matchWithFreeFormText with Address witj     State Name for St. Address
                            else if (locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(addressItem.addressLine + '.') + locationHelper.convertFromAbbreviationAreaName(addressItem.cityName) + addressItem.stateName + addressItem.zipCode).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                                item.isExactMatch = false;

                                if (!item.displayAreaName)
                                    item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                                else
                                    item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                                recentMatchBest.push(item);
                            }
                        }
                        // Check Anywhere with community name OR community location
                        else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.convertFromAbbreviationAreaName(item.areaName), locationHelper.convertFromAbbreviationAreaName(pub.displayText())) === true) {
                            item.isExactMatch = true;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check matchWithFreeFormText Anywhere with community name OR community location + State Code
                        else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.areaName)), locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText()))) === true) {
                            item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check matchWithFreeFormText Anywhere with community name OR community location + State Name
                        else if (item.areaType.toLowerCase() == 'neighborhood' && helper.strContainsNoCase(locationHelper.matchWithFreeFormText(locationHelper.replaceStateCodeWithStateNameForCommunity(item.areaName, item.stateCode, item.stateName)), locationHelper.matchWithFreeFormText(pub.displayText())) === true) {
                            item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                        // Check community with county location
                        else if (item.areaType.toLowerCase() == 'neighborhood' && !helper.isUndefinedOrNullOrEmpty(item.countyName) && locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(item.baseAreaName) + item.stateName).toLowerCase().startsWith(locationHelper.matchWithFreeFormText(locationHelper.convertFromAbbreviationAreaName(pub.displayText())).toLowerCase()) === true) {
                            item.isExactMatch = false;

                            if (!item.displayAreaName)
                                item.displayAreaName = ko.observable(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));
                            else
                                item.displayAreaName(addHighlightFormat(item.areaName, pub.displayText(), item.isExactMatch));

                            recentMatchBest.push(item);
                        }
                    });
                }
            }

            recentMatchBest = _.uniqBy(recentMatchBest, 'areaName');
            recentMatchBest = _.orderBy(recentMatchBest, ['isExactMatch', 'matchCount'], ['desc', 'desc']);

            pub.suggestionsRecent(recentMatchBest.slice(0, maxRecentMatchToShow));
            pub.recentMatchCount(recentMatchBest.length);
            return recentMatchBest;
        };

        pub.clearSearchText = function () {
            pub.resetSearchBarAndFocus();
            pub.selectedIndex(-1);
            tabSelectedIndex = 0;

            //let SEOsearchResultParameters = helper.getSEOSearchParametersCookieData();
            //if (SEOsearchResultParameters.brand != 0) {
            //    this.submit(null);
            //}

        };

        pub.onBlurSearchText = function () {

            setTimeout(function () {

                if (isRunning && xhr != null) {
                    xhr.abort();
                    isRunning = false;
                }

                // Close All Suggestion boxes.
                pub.showSuggestions(false);
                pub.showNoMatching(false);

                if (!pub.isAvoidBlurSelection) {
                    pub.showRecentMatching(false);
                    pub.ShowCurrentLocation(false);
                }

                var defaultIndex = 0;

                // fetch first location from suggetion if searchbar has some value.
                // if searchbar is blank then keep it blank.
                // Avoid this process if it is coming from Item click or Current Location click.
                if (!pub.isAvoidBlurSelection && !helper.isUndefinedOrNullOrEmpty(pub.displayText())) {
                    if (isTabbed && tabSelectedIndex !== undefined) {
                        defaultIndex = tabSelectedIndex;
                    }

                    var selecteditem = pub.getSelectedItem(defaultIndex);
                    var newSearchText = pub.displayText();
                    if (selecteditem !== null) {
                        newSearchText = selecteditem.areaName;
                    }

                    displayTextSubscription.dispose();
                    pub.displayText(newSearchText);
                    pub.previewText("");
                    displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
                    isTabbed = false;
                }

            }, 500);
        };

        pub.onGetCurrentLocation = function (data, event) {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(getCurrentPositionOnSuccess, getCurrentPositionOnFailure);
            }
            else {
                alert("We are unable to identify your Current Location.  Please manually enter a city, county, or zip code to display the results.");
            }
        };

        /**
         * success callback for getCurrentPosition
         */
        function getCurrentPositionOnSuccess (position) {
            pub.searchRentalsHome(position.coords.latitude, position.coords.longitude);
        }

        /**
         * error callback for getCurrentPosition
         */
        function getCurrentPositionOnFailure (err) {
            alert("Location Support is currently unavailable for this website. Please check your browser or device settings and try again.");
        }

        /**
         * Submit selected search and Redirect to search result page
         */
        pub.submit = function (selectedItem) {
            
            // pub.displayText (selectedItem.areaName + ', ' + selectedItem.stateCode + ' (' + selectedItem.areaType + ')');
            // Avoid OnBlur searchbar selection while Suggestion item click.
            pub.isAvoidBlurSelection = true;

            var text = '';
            var stateCode = '';
            var city = '';
            var county = '';
            var zip = '';
            var searchText = '';
            let isListingPageParamSet = false;

            if (selectedItem === null) {
                text = pub.displayText();
                searchText = pub.displayText();

                if (helper.isiOS()) {
                    displayTextSubscription.dispose();
                    pub.previewText("");
                    pub.displayText("");
                    displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
                }
            }
            else {
                selectedItem.areaName = locationHelper.convertFromAbbreviationAreaName(selectedItem.areaName);
                if (!selectedItem.displayAreaName)
                    selectedItem.displayAreaName = ko.observable(selectedItem.areaName);
                else
                    selectedItem.displayAreaName(selectedItem.areaName);

                searchText = selectedItem.areaName;

                /* Add this location in recent search cookie */
                locationHelper.addRecentSearchItem(selectedItem.baseAreaName, selectedItem.areaName, selectedItem.areaType, selectedItem.stateCode, selectedItem.stateName, selectedItem.communityId);

                displayTextSubscription.dispose();
                pub.showRecentMatching(false);
                pub.showSuggestions(false);
                pub.ShowCurrentLocation(false);
                pub.previewText("");
                pub.displayText(searchText);
                displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
            }

            if (!helper.isUndefinedOrNullOrEmpty(searchText)) {
                if (selectedItem !== null)
                    $.cookie(lastsearchqueryCookieName, searchText, { expires: 30, path: '/', secure: true });
                else
                    $.cookie(lastsearchqueryCookieName, '', { expires: -1, path: '/', secure: true });

                //Delete last sort value from cookie;
                // TODO: Please verify, is it needed or not..
                ////$.cookie('searchsortquery', null);
                ////$.cookie('searchsortquery2', null);

                if (pub.PageType == 'searchresult') {                   
                    let SEOsearchResultParameters = helper.getSEOSearchParametersCookieData();

                    SEOsearchResultParameters.page = 0;
                    SEOsearchResultParameters.state = '';
                    SEOsearchResultParameters.county = '';
                    SEOsearchResultParameters.city = '';
                    SEOsearchResultParameters.zip = '';
                    SEOsearchResultParameters.text = '';
                    SEOsearchResultParameters.landlordUserId = '';
                    SEOsearchResultParameters.schoolId = '';
                    SEOsearchResultParameters.NCESSchoolID = '';
                    SEOsearchResultParameters.education = '';
                    SEOsearchResultParameters.pos = '';
                    SEOsearchResultParameters.maxLatitude = '';
                    SEOsearchResultParameters.maxLongitude = '';
                    SEOsearchResultParameters.minLatitude = '';
                    SEOsearchResultParameters.minLongitude = '';
                    SEOsearchResultParameters.center = '';
                    SEOsearchResultParameters.zoom = '';

                    if (tnResultModel.domain.isDrawingEnabled() > 0) {
                        // Disable drawing before performing a new search.
                        tnResult.clearMapBoxVisibleArea();
                    }
                    //For redirect to normal AH listing page if user search from search box 
                    if (SEOsearchResultParameters.enterpriseId > 0 && (selectedItem !== null || text != '')) {
                        SEOsearchResultParameters.enterpriseId = null;
                        helper.updateSEOCookie(SEOsearchResultParameters);
                        window.location.href = "/v4/pages/tnresult/tnresult.aspx";
                    }
                    
                    if (selectedItem !== null) {                        
                        if (selectedItem.stateCode !== null) {
                            stateCode = selectedItem.stateCode;
                        }
                        if (selectedItem.areaType === 'county' && selectedItem.areaName !== null) {
                            county = selectedItem.baseAreaName;
                            SEOsearchResultParameters.state = stateCode;
                            SEOsearchResultParameters.county = locationHelper.removeCountyText(county);
                            SEOsearchResultParameters.city = null;
                            helper.updateSEOCookie(SEOsearchResultParameters);
                            if (tnResultModel.view.currentPage() === "tnresult") {
                                tnResult.setSearchResultParameters(0, stateCode, county, '', '', '', null, 0, 0, null,SEOsearchResultParameters.brand);
                                isListingPageParamSet = true;
                            }
                            else {
                                window.location.href = "/v4/pages/tnresult/tnresult.aspx";
                            }

                        }
                        else if (selectedItem.areaType === 'city' && selectedItem.areaName !== null) {
                            city = selectedItem.baseAreaName;
                            SEOsearchResultParameters.state = stateCode;
                            SEOsearchResultParameters.city = city;
                            helper.updateSEOCookie(SEOsearchResultParameters);
                            if (tnResultModel.view.currentPage() === "tnresult") {
                                tnResult.setSearchResultParameters(0, stateCode, '', city, '', '', null, 0, 0, null, SEOsearchResultParameters.brand);
                                isListingPageParamSet = true;
                            }
                            else {
                                window.location.href = "/v4/pages/tnresult/tnresult.aspx";
                            }
                        }
                        else if (selectedItem.areaType === 'zip' && selectedItem.areaName !== null) {
                            var fullText = pub.displayText().split(',');
                            if (fullText.length > 0) {
                                zip = fullText[0];
                                city = fullText[1].trim();
                                SEOsearchResultParameters.state = stateCode;
                                SEOsearchResultParameters.city = city;
                                SEOsearchResultParameters.zip = zip;
                                helper.updateSEOCookie(SEOsearchResultParameters);
                                if (tnResultModel.view.currentPage() === "tnresult") {
                                    tnResult.setSearchResultParameters(0, stateCode, '', city, zip, '', null, 0, 0, null, SEOsearchResultParameters.brand);
                                    isListingPageParamSet = true;
                                }
                                else {
                                    window.location.href = "/v4/pages/tnresult/tnresult.aspx";
                                }
                            }
                        }
                        else if (selectedItem.areaType === 'address' || selectedItem.areaType === 'neighborhood') {
                            var loadBrandDetailsPage = false;
                            if (tnResultModel.domain.brand() !== null && tnResultModel.domain.brand() > 0) {
                                listing.isCommunityInBrandJurisdcition(tnResultModel.domain.brand(), selectedItem.communityId,                                    
                                    function (response) {
                                        loadBrandDetailsPage = response.IsInJurisdiction;
                                    }, helper.remoteOperationFailure)
                            }
                            sessionStorage.removeItem("searchresults");
                            pub.updateDisplayText("");
                            let addressDetails = locationHelper.getDetailedAddressItem(selectedItem);
                            var displayText = '';
                            var url;
                            if (selectedItem.isCommunity === true) {
                                url = helper.returnSEOfriendlyURL(addressDetails.cityName, selectedItem.stateCode, '', selectedItem.communityId, !selectedItem.isCommunity, addressDetails.addressLine);                               
                            }
                            else {
                                displayText = addressDetails.cityName + ', ' + addressDetails.stateCode;
                                setTimeout(function () {
                                    pub.isAvoidBlurSelection = true;
                                    pub.updateDisplayText(displayText);
                                }, 1000);

                                if (typeof (tnResult) !== "undefined") {
                                    tnResultModel.domain.searchState(addressDetails.stateCode);
                                    tnResultModel.domain.searchCity(addressDetails.cityName);
                                    tnResultModel.domain.searchStateName("");
                                    tnResultModel.domain.searchZip("");
                                    tnResultModel.domain.searchText("");
                                }
                                url = helper.returnSEOfriendlyURL(addressDetails.cityName, selectedItem.stateCode, addressDetails.addressLine, selectedItem.communityId, !selectedItem.isCommunity, '');
                            }
                            if (loadBrandDetailsPage)
                                url = url + "brand-" + tnResultModel.domain.brand();

                            window.location.href = url;
                        }
                    }
                        
                    if (!selectedItem || (selectedItem.areaType !== 'address' || selectedItem.areaType !== 'neighborhood')) {
                        SEOsearchResultParameters.text = text;
                        SEOsearchResultParameters.state = stateCode;
                        SEOsearchResultParameters.city = city;
                        SEOsearchResultParameters.zip = zip;
                        SEOsearchResultParameters.county = county;
                        helper.updateSEOCookie(SEOsearchResultParameters);

                        if (isListingPageParamSet !== true) {
                            tnResult.setSearchResultParameters(0, stateCode, county, city, zip, text, null, 0, 0, null,SEOsearchResultParameters.brand);
                            isListingPageParamSet = true;
                        }
                    }
                }
                else {
                    let SEOsearchResultParameters = helper.setSEOsearchResultParameters();

                    SEOsearchResultParameters.page = 0;
                    SEOsearchResultParameters.state = '';
                    SEOsearchResultParameters.county = '';
                    SEOsearchResultParameters.city = '';
                    SEOsearchResultParameters.zip = '';
                    SEOsearchResultParameters.text = '';
                    SEOsearchResultParameters.landlordUserId = '';
                    SEOsearchResultParameters.schoolId = '';
                    SEOsearchResultParameters.NCESSchoolID = '';
                    SEOsearchResultParameters.education = '';
                    SEOsearchResultParameters.pos = '';
                    SEOsearchResultParameters.maxLatitude = '';
                    SEOsearchResultParameters.maxLongitude = '';
                    SEOsearchResultParameters.minLatitude = '';
                    SEOsearchResultParameters.minLongitude = '';
                    SEOsearchResultParameters.center = '';
                    SEOsearchResultParameters.zoom = '';

                    var stateParam = "";
                    var cityParam = "";
                    var countyParam = "";
                    var zipParam = "";
                    var textParam = "";

                    if (selectedItem !== null && selectedItem.stateCode !== null) {
                        stateCode = '&state=' + selectedItem.stateCode;
                        stateParam = selectedItem.stateCode;
                    }

                    // city and county reversed
                    if (selectedItem !== null && selectedItem.areaType === 'county' && selectedItem.areaName !== null) {
                        county = '&county=' + selectedItem.baseAreaName;
                        countyParam = selectedItem.baseAreaName
                    }
                    else if (selectedItem !== null && selectedItem.areaType === 'city' && selectedItem.areaName !== null) {
                        city = '&city=' + selectedItem.baseAreaName;
                        cityParam = selectedItem.baseAreaName;
                    }
                    else if (selectedItem !== null && selectedItem.areaType === 'zip' && selectedItem.areaName !== null) {
                        var fullText = pub.displayText().split(',');
                        if (fullText.length > 0) {
                            zip = '&zip=' + fullText[0] + '&city=' + fullText[1].trim();
                            zipParam = fullText[0];
                            cityParam = fullText[1].trim();
                        }
                    }

                    // replacing first character from query string;
                    if (selectedItem !== null && (selectedItem.areaType === 'address' || selectedItem.areaType === 'neighborhood')) {
                        sessionStorage.removeItem("searchresults");

                        let addressDetails = locationHelper.getDetailedAddressItem(selectedItem);
                        if (selectedItem.isCommunity === true) {
                            window.location.href = helper.returnSEOfriendlyURL(addressDetails.cityName, selectedItem.stateCode, '', selectedItem.communityId, !selectedItem.isCommunity, addressDetails.addressLine);
                        }
                        else {
                            window.location.href = helper.returnSEOfriendlyURL(addressDetails.cityName, selectedItem.stateCode, addressDetails.addressLine, selectedItem.communityId, !selectedItem.isCommunity, '');
                        }
                    }
                    else {
                        if (selectedItem === null) {
                            text = '&text=' + text;
                            textParam = text;
                        }
                        SEOsearchResultParameters.state = stateParam;
                        SEOsearchResultParameters.city = !helper.isUndefinedOrNullOrEmpty(cityParam) ? cityParam : null;
                        SEOsearchResultParameters.county = !helper.isUndefinedOrNullOrEmpty(countyParam) ? countyParam : null;
                        SEOsearchResultParameters.text = !helper.isUndefinedOrNullOrEmpty(textParam) ? textParam : null;
                        SEOsearchResultParameters.zip = !helper.isUndefinedOrNullOrEmpty(zipParam) ? zipParam : null;
                        helper.updateSEOCookie(SEOsearchResultParameters);
                        window.location.href = "/v4/pages/tnresult/tnresult.aspx";
                    }
                }

                if (typeof (tnResultModel) !== "undefined")
                {
                    tnResultModel.savedSearch(false);
                }

                //displaySearchBoundaries();
            }
        };

        

        /**
         * Redirect to search result page
         */
        pub.searchRentalsHome = function (latitude, longitude) {
            // Clear previewText, displayText as well as close Suggestion box on Browser back button in iPad
            displayTextSubscription.dispose();
            pub.showSuggestions(false);
            pub.previewText("");
            pub.displayText("");
            displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
            // Avoid OnBlur searchbar selection while Current Location click.
            pub.isAvoidBlurSelection = true;

            currentLocation = {
                "latitude": latitude,
                "longitude": longitude,
                "suggestion": null
            }

            var recentCurrentLocation = localStorage.getItem(currentLocationStorageName);
            if (recentCurrentLocation !== null) {
                var locationData = JSON.parse(recentCurrentLocation);
                if (locationData.latitude === latitude && locationData.longitude === longitude) {
                   pub.submit(locationData.suggestion);
                }
            }

            listing.getCurrentLocationNameByLatLong(latitude, longitude, getCurrentLocationNameOnSuccess, helper.remoteOperationFailure);
        };

        /**
         * success callback for getCurrentLocationName
         */
        function getCurrentLocationNameOnSuccess (result) {
            if (result !== null && result.currentLocation !== null && result.suggestion !== null) {
                currentLocation.suggestion = result.suggestion;

                if (!helper.isUndefinedOrNullOrEmpty(currentLocation.suggestion.areaName)) {
                    currentLocation.suggestion.areaName = locationHelper.convertFromAbbreviationAreaName(currentLocation.suggestion.areaName);
                }

                localStorage.setItem(currentLocationStorageName, JSON.stringify(currentLocation));
                pub.submit(result.suggestion);
            }
            else {
                alert("We are unable to identify your Current Location.  Please manually enter a city, county, or zip code to display the results.");
            }
        };

        /**
        * show No Matching message
        */
        pub.showNoMatching = function () {
            pub.showSuggestions(false);
            pub.previewText("");
            pub.showNoMatching(true);
        };

        /**
        * Reset Recent Matching Popup
        */
        pub.resetRecentMatching = function () {
            var suggestionsRecent = [];
            var isUserLoggedIn = !helper.isUndefinedOrNullOrEmpty(headerModel.domain.user()) ? true : false;
            /* Read data from cookie*/
            var recentMatchData = $.cookie(recentSearchCookieName);
            if (recentMatchData != null && recentMatchData != "") {
                suggestionsRecent = JSON.parse(recentMatchData).filter(z => z.baseAreaName != "");

                if (!helper.isUndefinedOrNullOrEmpty(suggestionsRecent))
                {
                    suggestionsRecent = _.filter(suggestionsRecent, function (item)
                    {
                        return item.isLoggedUserCookie == isUserLoggedIn;
                    });
                }
            }

            pub.suggestionsRecent(suggestionsRecent.slice(0, maxRecentMatchToShow));
            pub.showRecentMatching(suggestionsRecent != null && suggestionsRecent.length > 0);
            if (suggestionsRecent.length > maxRecentMatchToShow) {
                pub.recentMatchCount(maxRecentMatchToShow);
            }
            else {
                pub.recentMatchCount(suggestionsRecent.length);
            }
        };

        /**
        * Get selected item based on index from RecentMatch and SuggestionBest
        */
        pub.getSelectedItem = function (currentIndex) {
            var selecteditem = null;

            if (pub.recentMatchCount() > 0) {
                selecteditem = pub.suggestionsRecent()[currentIndex];
            }

            if (pub.suggestionsBest().length > 0 && currentIndex >= pub.recentMatchCount()) {
                selecteditem = pub.suggestionsBest()[currentIndex - pub.recentMatchCount()];
            }

            return selecteditem;
        };

        /**
        * submit selected item based on selected index or searched text from RecentMatch and SuggestionBest.
        */
        pub.submitSearchedLocation = function () {
            var selectedItem = null;
            var selectedIndex = pub.selectedIndex();

            if (selectedIndex !== null && selectedIndex != -1) {
                selectedItem = pub.getSelectedItem(selectedIndex);
            }
            else if (!helper.isUndefinedOrNullOrEmpty(pub.previewText()) || isNonExactMatchItemSelected === true) {
                selectedItem = pub.getSelectedItem(0);
                if (selectedItem === null) {
                    var recentData = pub.getRecentData();
                    if (recentData !== null && recentData.length > 0) {
                        pub.recentMatchCount(1);
                    }
                    selectedItem = pub.getSelectedItem(0);
                }
            }
            else if (helper.isUndefinedOrNullOrEmpty(pub.previewText()) && pub.getSelectedItem(0) != null && pub.getSelectedItem(0).isCommunity === true) {
                selectedItem = pub.getSelectedItem(0);
            }
            else if (!helper.isUndefinedOrNullOrEmpty(pub.displayText()) && pub.getRecentData() != null && pub.getRecentData().length > 0) {
                if (pub.displayText() === pub.getRecentData()[0].areaName) {
                    selectedItem = pub.getRecentData()[0];
                }
            }

            if (selectedItem !== null || (pub.displayText().length > 2 && pub.displayText().trim() != txtCurrentMapArea)) {
                pub.submit(selectedItem);
            }
        };

        /**
        * reset Search bar control and focus if is blank.
        */
        pub.resetSearchBarAndFocus = function () {

            if (isRunning && xhr != null) {
                if (xhr != null) {
                    xhr.abort();
                }

                isRunning = false;
            }

            isNonExactMatchItemSelected = false;
            displayTextSubscription.dispose();
            pub.showNoMatching(false);
            pub.previewText("");
            pub.displayText("");
            pub.ShowCurrentLocation(true);
            displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
            if (isIE == true && isEdge == false) {
                pub.onClickSearchText();
                setTimeout(function () { document.getElementById('searchTextbox').focus(); }, 1000);
            }
            else {
                $("#searchTextbox").focus();
            }
            pub.isAvoidBlurSelection = true;
        };


        /**
        * Add <em> tag to Highlight searched text
        */
        function addHighlightFormat(areaName, displayText, isExachMatched) {
            areaName = resolvePreviewText(areaName);
            var highlightedText = displayText.trim();
            if (isExachMatched) {
                highlightedText = '<em> ' + highlightedText + '</em>';
            }
            var myRegExp = new RegExp(displayText.trim().toLowerCase(), 'g');
            return locationHelper.applyLocationCapitalization(areaName.toLowerCase().replace(myRegExp, highlightedText));
        }

        function resolvePreviewText(areaName) {
            if (helper.isUndefinedOrNullOrEmpty(areaName))
                return null;

            var result = areaName;
            if (isAbbreviationSearched) {
                result = locationHelper.convertToAbbreviationAreaName(areaName);
            }
            else if (isAbbreviationWithSpaceSearched) {
                result = locationHelper.convertToAbbreviationAreaNameWithSpace(areaName);
            }
            else {
                result = locationHelper.convertFromAbbreviationAreaName(areaName);
            }

            return locationHelper.applyLocationCapitalization(result);
        }

        function isTenantLoggedIn() {
            return (isTenantLogged == false && headerModel.domain.user() && headerModel.domain.user().UserType().toLowerCase() === "tenant");
        }

        pub.clearVisitorSearch = function () {
            pub.previewText("");
            pub.displayText("");
            $.cookie(lastsearchqueryCookieName, '', { expires: -1, path: '/', secure: true });
        };

        pub.updateDisplayText = function (newDisplayText)
        {
            displayTextSubscription.dispose();
            pub.previewText("");
            pub.displayText(locationHelper.applyLocationCapitalization(helper.limitCharacters(newDisplayText)));
            displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
        };

        /**
         * Get user's current location details.
         * */
        pub.getUserCurrentLocation = function () {
            if (userLocationByIP == null || helper.isNullOrEmpty(userLocationByIP.userCity) || helper.isNullOrEmpty(userLocationByIP.userCounty) || helper.isNullOrEmpty(userLocationByIP.userState)) {
                if ($.cookie('userlocation') != null) {
                    var userLocationJsonByIP = JSON.parse($.cookie('userlocation'));

                    if (!helper.isNullOrEmpty(userLocationJsonByIP["City"])) {
                        userLocationByIP.userCity = userLocationJsonByIP["City"];
                    }
                    else {
                        userLocationByIP.userCity = '';
                    }

                    if (!helper.isNullOrEmpty(userLocationJsonByIP["County"])) {
                        userLocationByIP.userCounty = userLocationJsonByIP["County"];
                    }
                    else {
                        userLocationByIP.userCounty = '';
                    }

                    if (!helper.isNullOrEmpty(userLocationJsonByIP["State"])) {
                        userLocationByIP.userState = userLocationJsonByIP["State"];
                    }
                    else {
                        userLocationByIP.userState = '';
                    }
                }
                else {
                    listing.getLocationByIPAddress(getLocationByIPAddresseOnSuccess, getLocationByIPAddressOnFailure);
                }
            }
        }

        /**
         * Invoked on success when calling getLocationByIPAddress.
         */
        function getLocationByIPAddresseOnSuccess(result) {
            try {
                // If ip address is identified
                if (result && (!helper.isNullOrEmpty(result.Location.city) || !helper.isNullOrEmpty(result.Location.district) || !helper.isNullOrEmpty(result.Location.state))) {
                    var currentlocation = result.Location;
                    var zip = '';
                    var lat = '';
                    var long = '';

                    if (!helper.isNullOrEmpty(currentlocation["city"]))
                        userLocationByIP.userCity = currentlocation["city"];
                    if (!helper.isNullOrEmpty(currentlocation["district"]))
                        userLocationByIP.userCounty = currentlocation["district"];
                    if (!helper.isNullOrEmpty(currentlocation["stateProv"]))
                        userLocationByIP.userState = currentlocation["stateProv"];

                    if (!helper.isNullOrEmpty(currentlocation["zipCode"]))
                        zip = currentlocation["zipCode"];
                    if (!helper.isNullOrEmpty(currentlocation["latitude"]))
                        lat = currentlocation["latitude"];
                    if (!helper.isNullOrEmpty(currentlocation["longitude"]))
                        long = currentlocation["longitude"];

                    var locationString = JSON.stringify({
                        City: userLocationByIP.userCity,
                        County: userLocationByIP.userCounty,
                        State: userLocationByIP.userState,
                        Zip: zip,
                        Latitude: lat,
                        Longitude: long
                    });

                    //add cookie for users location
                    $.cookie("userlocation", locationString, { expires: 365, path: '/', secure: true });
                }
            }
            catch (ex) {
                go8Error.handleException(ex);
            }
        }

        /**
         * Invoked on failure when calling getLocationByIPAddress.
         */
        function getLocationByIPAddressOnFailure() {
            try {

            }
            catch (ex) {
                go8Error.handleException(ex);
            }
        }


        //// trigger from tnresult.js when window.history.replaceState change
        var replaceState = history.replaceState;
        history.replaceState = function () {
            replaceState.apply(history, arguments);
            if (typeof (tnResultModel) !== "undefined" && tnResultModel.view.isResolvedLocation() == true) {
                displayTextSubscription.dispose();
                pub.displayText(tnResultModel.view.resolvedLocation.areaName);
                pub.previewText = ko.observable("");
                pub.showRecentMatching(false);
                pub.showSuggestions(false);
                displayTextSubscription = pub.displayText.subscribe(pub.onChangeSearchText);
            }
        };

        init();

        return pub;
    }
    catch (ex) {
        go8Error.handleException(ex);
    }
}());

/**
 * Model for .
 *
 * @requires
 *     jquery
 *     knockout
 */


var go8SearchBoxForListingsModel = function (parameters) {

    var self = this;
    var isIE = /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);
    var isEdge = (window.navigator.userAgent.indexOf('Edge/') > 0);

    function init() {
        go8SearchBoxForListings.PageType = parameters.PageType;
        self.clearSearchText = go8SearchBoxForListings.clearSearchText;
        self.displayAutoCompleteSuggestions = go8SearchBoxForListings.displayAutoCompleteSuggestions;
        self.getRecentData = go8SearchBoxForListings.getRecentData;
        self.onBlurSearchText = go8SearchBoxForListings.onBlurSearchText;
        self.onChangeSearchText = go8SearchBoxForListings.onChangeSearchText;
        self.onClickSearchButton = go8SearchBoxForListings.onClickSearchButton;
        self.onClickSearchText = go8SearchBoxForListings.onClickSearchText;
        self.onGetCurrentLocation = go8SearchBoxForListings.onGetCurrentLocation;
        self.onKeyDownSearchButton = go8SearchBoxForListings.onKeyDownSearchButton;
        self.onKeyDownSearchText = go8SearchBoxForListings.onKeyDownSearchText;
        self.resetRecentMatching = go8SearchBoxForListings.resetRecentMatching;
        self.resetSearchBarAndFocus = go8SearchBoxForListings.resetSearchBarAndFocus;
        self.searchRentalsHome = go8SearchBoxForListings.searchRentalsHome;
        self.showNoMatching = go8SearchBoxForListings.showNoMatching;
        self.submit = go8SearchBoxForListings.submit;
        self.submitSearchedLocation = go8SearchBoxForListings.submitSearchedLocation;
        self.displayText = go8SearchBoxForListings.displayText;
        self.previewText = go8SearchBoxForListings.previewText;
        self.ShowCurrentLocation = go8SearchBoxForListings.ShowCurrentLocation;
        self.showRecentMatching = go8SearchBoxForListings.showRecentMatching;
        self.suggestionsRecent = go8SearchBoxForListings.suggestionsRecent;
        self.showSuggestions = go8SearchBoxForListings.showSuggestions;
        self.suggestionsBest = go8SearchBoxForListings.suggestionsBest;
        self.selectedIndex = go8SearchBoxForListings.selectedIndex;
        self.suggestionsBest = go8SearchBoxForListings.suggestionsBest;
        self.showRecentMatching = go8SearchBoxForListings.showRecentMatching;
        self.recentMatchCount = go8SearchBoxForListings.recentMatchCount;
        self.updateDisplayText = go8SearchBoxForListings.updateDisplayText;

        go8SearchBoxForListings.initTenant();

        $('body').focusin(function (e) {
            if (isIE) {
                if (e.target.className !== "suggestions" && e.target.className !== "searchTextbox" && e.target.id !== "btnSearch" && e.target.id !== "clearText" && e.target.id !== "divSearch") {
                    go8SearchBoxForListings.onBlurSearchText();
                }
            }
        });
        $('#divsearchbarbox').focusout(function (e) {
            if ((!isIE && e.target.className !== "searchButton") || (isEdge == true && e.target.className !== "searchButton")) {
                go8SearchBoxForListings.isAvoidBlurSelection = false;
                go8SearchBoxForListings.onBlurSearchText();
            }
        });
        document.addEventListener('touchmove', function (e) {
            if (e.target.className === "searchTextbox") {
                $('.searchPreviewbox').val("");
            }
        }, false);
        $('#ah_pass').focusout(function (e) {
            if(e.target.className === "ah-password")
                $("#ah_pass").focus();
        });
    }

    // This function is not recognized in mappings if defined as above by assignment.
    onClickItem = function (data, event) {
        go8SearchBoxForListings.submit(data);
    };

    init();
};
ko.components.register('go8-search-box-for-listings',
    {
        template: { element: 'searchBoxForListingsHtml' },
        viewModel: go8SearchBoxForListingsModel
    });
//$.ajax
//    ({
//        url: '/v4/controls/searchBoxForListings/searchBoxForListings.html',
//        async: false,
//        success: function (templateString) {
//            ko.components.register('go8-search-box-for-listings',
//                {
//                    template: templateString,
//                    viewModel: go8SearchBoxForListingsModel
//                });
//        }
//    });


var ahRentalPanel = (function () {

    try {
        var pub = {};

        function init() {
            pub.BaseAreaName = ko.observable("");
            pub.AreaName = ko.observable("");
            pub.AreaType = ko.observable("");
            pub.StateCode = ko.observable("");
            pub.StateName = ko.observable("");
            pub.RentalPanelList = ko.observable("");
            pub.pageName = ko.observable("");
        }

        /* Get Display text for current AreaName */
        pub.getDisplayText = function (displayPlace)
        {
            if (pub.pageName() == "Index") {
                if (displayPlace == "header") {
                    return "Affordable Rentals in " + pub.AreaName()();
                }
                else if (displayPlace == "viewalllink") {
                    return "View all rentals in " + pub.AreaName()() + "<i class='fas fa-chevron-right'></i>";
                }
            }
            else if (pub.pageName() == "PropertyDetail") {
                if (displayPlace == "header") {
                    return "Nearby Rentals";
                }
                else if (displayPlace == "viewalllink") {
                    return "See All";
                }
            }
            else {
                return pub.AreaName()();
            }
        };

        pub.getListingPageUrl = function () {
            return helper.getSEOFriendlyPropertySearchUrl(pub.StateCode()(), pub.BaseAreaName()(), null, pub.AreaType()());
        };

        /* Show listing detail page */
        pub.showListingDetail = function (item) {
            var fullAddress = '';
            if (item.AddressLine1()) {
                fullAddress = item.AddressLine1();
            }

            if (item.AddressLine2()) {
                fullAddress = fullAddress + ", " + item.AddressLine2();
            }

            if (item.City()) {
                fullAddress = fullAddress + ", " + item.City();
            }

            if (item.State()) {
                fullAddress = fullAddress + ", " + item.State();
            }

            if (item.Zip()) {
                fullAddress = fullAddress + " " + item.Zip();
            }

            /* Redirect to listing detail page */
            window.location.href = '/v4/pages/propertyDetail/propertyDetails.aspx?address=' + fullAddress;
        };

        /* View all Listing for this location */
        pub.showListingPage = function () {

            /* Add this location in last search query cookie */
            $.cookie(lastsearchqueryCookieName, pub.AreaName()(), { expires: 30, path: '/', secure: true });

            /* Add this location in recent search cookie */
            locationHelper.addRecentSearchItem(pub.BaseAreaName()(), pub.AreaName()(), pub.AreaType()(), pub.StateCode()(), pub.StateName()(), 0);

            /* Redirect to listing page based of Area Type of this location */
            window.location.href = pub.getListingPageUrl();

            return false;
        }        

        init();

        return pub;

    }
    catch (ex) {
        go8Error.handleException(ex);
    }
}());


var ahRentalPanelModel = function (parameters) {

    var self = this;
    init();

    function init() {

        ahRentalPanel.BaseAreaName = ko.observable(parameters.baseAreaName);
        ahRentalPanel.AreaName = ko.observable(parameters.areaName);
        ahRentalPanel.AreaType = ko.observable(parameters.areaType);
        ahRentalPanel.StateCode = ko.observable(parameters.stateCode);
        ahRentalPanel.StateName = ko.observable(parameters.stateName);
        ahRentalPanel.RentalPanelList = ko.observable(parameters.rentalPanelList);
        ahRentalPanel.pageName = ko.observable(parameters.pageName);
        ahRentalPanel.min = 3;
        ahRentalPanel.max = 6;
        if (parameters.min)
                ahRentalPanel.min = parameters.min;
        if (parameters.max)
                ahRentalPanel.max = parameters.max;


        self.BaseAreaName = ahRentalPanel.BaseAreaName;
        self.AreaName = ahRentalPanel.AreaName;
        self.AreaType = ahRentalPanel.AreaType;
        self.StateCode = ahRentalPanel.StateCode;
        self.StateName = ahRentalPanel.StateName;
        self.pageName = ahRentalPanel.pageName;

        if (ahRentalPanel.RentalPanelList().Length < ahRentalPanel.max && ahRentalPanel.min && ahRentalPanel.RentalPanelList().Length > ahRentalPanel.min)
            self.RentalPanelList = ahRentalPanel.RentalPanelList().slice(0, ahRentalPanel.min);
        else
            self.RentalPanelList = ahRentalPanel.RentalPanelList();

        self.showListingDetail = ahRentalPanel.showListingDetail;
        self.showListingPage = ahRentalPanel.showListingPage;
        self.getDisplayText = ahRentalPanel.getDisplayText;
        self.getListingPageUrl = ahRentalPanel.getListingPageUrl;
    }

    /* Show listing detail page */
    showListingDetail = function (item) {
        window.location.href = item.SeoFriendlyRentalUrl();
    };
};

ko.components.register('ah-rental-panel',
    {
        template: { element: 'affordableRentalsPanelHtml' },
        viewModel: ahRentalPanelModel
    });

ko.components.register('ah-rental-panel-v2',
    {
        template: { element: 'affordableRentalsPanelHtmlv2' },
        viewModel: ahRentalPanelModel
    });

