var TypeAhead =
{
    ids:
    {
        queryTextBox: "textbox",
        submitQueryButton: "submitQueryButton",
        dropdown: "dropdown"
    },

    elements:
    {
        queryTextBox: null,
        submitQueryButton: null,
        dropdown: null,
        currentListItems: null,
        bannersToHide: []
    },

    defaultQueryTextBoxText: "Skriv din søgetekst her",
    searchUrlGet: "/?query=",
    suggestionUrl: "?query=",
    asyncTransport: null,
    lastSuggestionQuery: null,
    performSearchTimer: null,
    searchDate: null,
    loadingIndicatorShownDate: null,
    loadingIndicatorTimer: null,

    minQueryLength: 3,
    inputtingPerformSearchDelay: 300,
    searchInstantlyDelay: 1500,

    currentListItemIndex: null,

    dropdownContainsItems: false,
    dropdownMouseDown: false,

    documentReady: function()
    {
        this.asyncTransport = new AsyncTransport("get", this.asyncTransportOnSuccess.bind(this), this.asyncTransportOnFailure.bind(this));

        // Get jQuery elements.
        this.elements.queryTextBox = $("#" + this.ids.queryTextBox);
        this.elements.submitQueryButton = $("#" + this.ids.submitQueryButton);
        this.elements.dropdown = $("#" + this.ids.dropdown);
        
        // Hiding right top banner.
        var divs = $("#colRight > div");
        
        for (var i = 0; i < divs.length; i++)
        {
            var div = $(divs[i]);
            
            if (div.hasClass("colRightTopAd"))
            {
                this.elements.bannersToHide.push(div);
            }
        }

        // Bind events.
        this.elements.queryTextBox.keyup(this.queryTextBoxOnKeyUp.bind(this));
        this.elements.queryTextBox.keydown(this.queryTextBoxOnKeyDown.bind(this));
        this.elements.queryTextBox.blur(this.queryTextBoxOnBlur.bind(this));
        this.elements.queryTextBox.focus(this.queryTextBoxOnFocus.bind(this));
        this.elements.dropdown.mousedown(this.dropdownOnMouseDown.bind(this));
        this.elements.dropdown.click(this.dropdownOnClick.bind(this));
        $(document).click(this.documentOnClick.bind(this));

        var productListItems = $("#productList > li");
        var typeAHead = this;

        productListItems.click(function()
        {
            window.location.href = $(this).find("a")[0].href;
            typeAHead.hideDropDown(null, true);
        });

        productListItems.mouseover(function()
        {
            $(this).addClass("selected");
        });

        productListItems.mouseout(function()
        {
            $(this).removeClass("selected");
        });

        var categoryListItems = $("#categoryList > li");

        categoryListItems.click(function()
        {
            window.location.href = $(this).find("a")[0].href;
            typeAHead.hideDropDown(null, true);
        });

        categoryListItems.mouseover(function()
        {
            $(this).addClass("selected");
        });

        categoryListItems.mouseout(function()
        {
            $(this).removeClass("selected");
        });

        var adListItems = $("#adList > li");

        adListItems.click(function() {
            //window.location.href = $(this).find("a")[0].href;
            typeAHead.hideDropDown(null, true);
        });

        var seeAllListItems = $("#seeAllResultsList > li");

        seeAllListItems.click(function()
        {
            window.location.href = $(this).find("a")[0].href;
            typeAHead.hideDropDown();
        });

        seeAllListItems.mouseover(function()
        {
            $(this).addClass("selected");
        });

        seeAllListItems.mouseout(function()
        {
            $(this).removeClass("selected");
        });
    },

    showLoadingIndicator: function()
    {
        window.clearTimeout(this.loadingIndicatorTimer);
        this.loadingIndicatorShownDate = new Date();
        this.elements.queryTextBox.addClass("loading");
    },

    hideLoadingIndicator: function()
    {
        window.clearTimeout(this.loadingIndicatorTimer);

        if (this.loadingIndicatorShownDate != null)
        {
            var miliseconds = this.loadingIndicatorShownDate.valueOf();
            var currentMiliseconds = (new Date()).valueOf();
            var diffMiliseconds = (currentMiliseconds - miliseconds);

            if (diffMiliseconds < 400)
            {
                this.loadingIndicatorTimer = window.setTimeout(this.hideLoadingIndicator.bind(this), 100);
                return;
            }
        }

        this.elements.queryTextBox.removeClass("loading");
    },

    asyncTransportOnSuccess: function(data)
    {
        this.hideLoadingIndicator();

        var itemsToDisplay = false;

        if (data != null && data.Hits && ( (data.Products != null && data.Products.length > 0) || (data.Categories != null && data.Categories.length > 0) ))
        {
            $("#productsHeading").text(data.ProductsTitle);
            $("#categoriesHeading").text(data.CategoriesTitle);
            $("#productsNotFound").text(data.NoProducts);
            $("#categoriesNotFound").text(data.NoCategories);

            var anchor = $("#seeAllResultsAnchor");
            anchor.text(data.SeeAllResultsText);
            anchor[0].href = data.SeeAllResultsLink;

            if (data.Products != null && data.Products.length > 0)
            {
                itemsToDisplay = true;

                for (var i = 0; i < 4; i++)
                {
                    var product = (i <= data.Products.length ? data.Products[i] : null);

                    if (product == null)
                    {
                        $("#productListItem" + (i + 1) + "").addClass("none");
                    }
                    else
                    {
                        var listItem = $("#productListItem" + (i + 1) + "");
                        listItem.removeClass("selected");
                        listItem.removeClass("none");

                        var image = $("#pimg" + (i + 1));
                        image.error(function()
                        {
                            $(this).attr("src", "/gfx/common/noImage.39x39.png");
                        });
                        image[0].src = product.ImageUrl;
                        
                        var anchor = $("#panc" + (i + 1))[0];
                        anchor.href = product.DetailsUrl;
                        anchor.innerHTML = product.DisplayName;
						anchor.title = product.Name;
						
						var paragraph = $("#pCategory" + (i + 1))[0];
						paragraph.innerHTML = product.Category != '' ? 
								data.ProductInCategoryTitle + ' ' + product.Category : '';
                    }
                }
                
                $("#productList").show();
                $("#productsNotFound").hide();
            }
            else
            {
                for (var i = 0; i < 4; i++)
                {
                    $("#productListItem" + (i + 1) + "").addClass("none");
                }

                $("#productList").hide();
                $("#productsNotFound").show();
            }

            if (data.Categories != null && data.Categories.length > 0)
            {
                itemsToDisplay = true;

                for (var i = 0; i < 4; i++)
                {
                    var category = (i <= data.Categories.length ? data.Categories[i] : null);

                    if (category == null)
                    {
                        $("#categoryListItem" + (i + 1) + "").addClass("none");
                    }
                    else
                    {
                        var listItem = $("#categoryListItem" + (i + 1));
                        listItem.removeClass("selected");
                        listItem.removeClass("none");
                        
                        var anchor = $("#canc" + (i + 1))[0];
                        anchor.href = category.Url;
                        anchor.innerHTML = category.Name;
                    }
                }

                $("#categoryList").show();
                $("#categoriesNotFound").hide();
            }
            else
            {
                for (var i = 0; i < 4; i++)
                {
                    $("#categoryListItem" + (i + 1) + "").addClass("none");
                }

                $("#categoryList").hide();
                $("#categoriesNotFound").show();
            }

            $("#seeAllResultsList > li").removeClass("selected");
        }

        this.elements.currentListItems = null;
        this.currentListItemIndex = null;

        if (itemsToDisplay)
        {
            this.elements.currentListItems = $("#typeahead li:not(.none)").filter(":not(.ad)");

            this.dropdownContainsItems = true;
            this.showDropDown();
        }
        else
        {
            this.dropdownContainsItems = false;
            this.hideDropDown();
        }
    },

    asyncTransportOnFailure: function()
    {
        this.hideLoadingIndicator();

        this.dropdownContainsItems = false;
        this.hideDropDown();
    },

    showDropDown: function(e)
    {
        if ($.browser.msie && jQuery.browser.version.substr(0,1) == "6")
        {
            this.currentSelectedMainMenuListItem = $("#menuParent > ul > li.selected")
            this.currentSelectedMainMenuListItem.removeClass("selected");
        }
        
        if (this.elements.bannersToHide.length > 0)
        {
            for (var i = 0; i < this.elements.bannersToHide.length; i++)
            {
                this.elements.bannersToHide[i].css("visibility", "hidden");
            }
	    }

        this.elements.dropdown.stop();
        this.elements.dropdown.animate( { "height" : "500px" }, 400 );
    },

    hideDropDown: function(e, force)
    {
        if (this.elements.bannersToHide.length > 0)
        {
            for (var i = 0; i < this.elements.bannersToHide.length; i++)
            {
                this.elements.bannersToHide[i].css("visibility", "visible");
            }
		}
		
        this.elements.dropdown.stop();
        this.elements.dropdown.animate( { "height" : "0px" }, 400, "", this.onDropDownHidden.bind(this));
    },

    onDropDownHidden: function()
    {
        if ($.browser.msie && jQuery.browser.version.substr(0,1) == "6")
        {
            if (this.currentSelectedMainMenuListItem != null)
            {
                $("#menuParent > ul > li").removeClass("selected");
                this.currentSelectedMainMenuListItem.addClass("selected");
            }
        }
    },

    isDropDownHidden: function()
    {
        return $("#typeahead").is(":hidden");
    },

    queryTextBoxOnKeyUp: function(e)
    {
        // 38 = arrow up
        if (e.which == 38 && !this.isDropDownHidden())
        {
            return;
        }
        // 40 = arrow down
        else if (e.which == 40 && !this.isDropDownHidden())
        {
            return;
        }
        else
        {
            //window.clearTimeout(this.loadingIndicatorTimer);

            var query = this.elements.queryTextBox.val();
            var queryTrimmed = query.trim();					

            if (queryTrimmed.length == 0)
            {
                this.lastSuggestionQuery = "";
                this.dropdownContainsItems = false;
                this.hideLoadingIndicator();
                this.hideDropDown(e);
                return;
            }

            window.clearTimeout(this.performSearchTimer);

            var miliseconds = (this.searchDate == null ? (new Date()).valueOf() : this.searchDate.valueOf());
            var currentMiliseconds = (new Date()).valueOf();
            var diffMiliseconds = (currentMiliseconds - miliseconds);

            if (queryTrimmed.length >= this.minQueryLength)
            {
                // Perform search instantly if it's been a while since the user laster entered chars into the query text box.
                if (diffMiliseconds > this.searchInstantlyDelay)
                {
                    this.performSearch(queryTrimmed);
                }
                else
                {
                    window.clearTimeout(this.loadingIndicatorTimer);
                    this.performSearchTimer = window.setTimeout(this.performSearch.bind(this, queryTrimmed), this.inputtingPerformSearchDelay);
                }
            }
        }
    },

    queryTextBoxOnKeyDown: function(e)
    {
        // 38 = arrow up
        if (e.which == 38 && !this.isDropDownHidden())
        {
            if (this.currentListItemIndex == null)
            {
                this.currentListItemIndex = this.elements.currentListItems.length - 1;
            }
            else
            {
                this.elements.currentListItems.eq(this.currentListItemIndex).removeClass("selected");
                this.currentListItemIndex--;
            }

            if (this.currentListItemIndex < 0)
                this.currentListItemIndex = this.elements.currentListItems.length - 1;
            
            this.elements.currentListItems.eq(this.currentListItemIndex).addClass("selected");
        }
        // 40 = arrow down
        else if (e.which == 40 && !this.isDropDownHidden())
        {
            if (this.currentListItemIndex == null)
            {
                this.currentListItemIndex = 0;
            }
            else
            {
                this.elements.currentListItems.eq(this.currentListItemIndex).removeClass("selected");
                this.currentListItemIndex++;
            }

            if (this.currentListItemIndex >= this.elements.currentListItems.length)
                this.currentListItemIndex = 0;
            
            this.elements.currentListItems.eq(this.currentListItemIndex).addClass("selected");
        }
        // 13 = enter
        else if (e.which == 13)
        {
            if (this.currentListItemIndex)
            {
                window.location.href = this.elements.currentListItems.eq(this.currentListItemIndex).find("a")[0].href;
            }
            else
            {
                var query = this.elements.queryTextBox.val();
                var queryTrimmed = query.trim();

                if (queryTrimmed.length > 0)
                    window.location.href = this.searchUrlGet.replace("{searchTerms}", encodeURIComponent(queryTrimmed));
            }

            this.hideDropDown();
            e.preventDefault();
            e.stopPropagation();
        }
    },

    queryTextBoxOnBlur: function(e)
    {
        if (this.elements.queryTextBox.val() == "")
            this.elements.queryTextBox.val(this.defaultQueryTextBoxText);

        if (this.dropdownMouseDown == false)
            this.hideDropDown(e);
    },

    queryTextBoxOnFocus: function(e)
    {
        if (this.elements.queryTextBox.val() == this.defaultQueryTextBoxText)
            this.elements.queryTextBox.val("");

        if (this.dropdownContainsItems)
            this.showDropDown(e);
    },

    dropdownOnMouseDown: function(e)
    {
        this.dropdownMouseDown = true;
    },

    dropdownOnClick: function(e)
    {
        this.dropdownMouseDown = false;
    },

    documentOnClick: function(e)
    {
    },

    performSearch: function(query)
    {
        if (this.lastSuggestionQuery == query)
        {
            this.hideLoadingIndicator();
            return;
        }

        this.showLoadingIndicator();

        if (this.asyncTransport.executing)
            this.asyncTransport.cancel();

        this.lastSuggestionQuery = query;
        this.searchDate = new Date();
        this.asyncTransport.send(this.suggestionUrl + encodeURIComponent(query));
    }
}
