$(function () {
    var grid = $('.productGrid');

    // parse hash
    function parseURLState() {
        var s = {};
        $.each(window.location.hash.replace(/^.*#-/, '').split("&"), function(i, v) {
	    var p = v.split("=");
	    if (p[1])
	        s[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
        });

        return s;
    }

    var urlState = parseURLState();
    
    // pagination
    grid.bind('paginationchanged', function (e, p) {
        var on = (Math.ceil(p.from / p.pageSize) + 1),
            tot = Math.ceil(p.total / p.pageSize);
        if (tot == 0)
            tot = 1;
        $(".productOverview .pagination").text("Side " + on + " af " + tot);
    });


    /*
    $(".leftSidebar #id_freetext").labelify({
        text: function () { return "navn/varenummer"; },
        labelledClass: "labelified"
    });*/

    // searching
    
    var query = {
        concepts: [],
        types: [],
        text: [],
        price: { from: null, to: null }
    };

    var types = $(".productOverview .searchBar .productTypes div"),
        concepts = $(".productOverview .searchBar .productConcepts div"),
        boxes = $(".productOverview .product");
    
    function executeQuery() {
        function match(data) {
            if (!overlapping(data.concepts, query.concepts))
                return false;

            if (data.type != null && $.inArray(data.type, query.types) == -1)
                return false;

            for (var i = 0; i < query.text.length; ++i)
                if (data.searchtext.indexOf(query.text[i]) == -1)
                    return false;

            if ((query.price.from != null && data.price < query.price.from) ||
                (query.price.to != null && data.price > query.price.to))
                return false;
            
            return true;
        }

        var changed = false;
        
        boxes.each(function () {
            var b = $(this), id = this.id.substring(1);

            if (match(productData[id])) {
                if (b.hasClass("notInQuery"))
                    changed = true;
                b.removeClass("notInQuery");
            }
            else {
                if (!b.hasClass("notInQuery"))
                    changed = true;
                b.addClass("notInQuery");
            }
        });

        if (changed)
            grid.trigger('querychanged', []);
    }

    // searching by clicking concepts and types
    function fillInIds(elements, res) {
        $.each(elements, function () {
            res.push(parseInt(this.id.substring(2)));
        });
    }
    
    function animationTarget(t) {
        t = $(t);
        if (t.find('img').length > 0)
            return t.find('img');
        else
            return t;
    }
        
    function setupSearchByToggles(elements, queryArray) {
        fillInIds(elements, queryArray);
        
        elements.hover(function () {
            animationTarget(this).animate({ opacity: 0.7 }, 200);
        }, function () {
            var id = parseInt(this.id.substring(2), 10);
            if ($.inArray(id, queryArray) != -1)
                animationTarget(this).animate({ opacity: 1 }, 200);
            else
                animationTarget(this).animate({ opacity: 0.3 }, 200);
        }).click(function () {
            // empty the array if it's full
            if (queryArray.length == elements.length) {
                animationTarget(elements.not(this)).animate({ opacity: 0.3 }, 200);
                queryArray.splice(0, queryArray.length);
            }
                
            var id = parseInt(this.id.substring(2), 10)
                i = $.inArray(id, queryArray);
            if (i == -1) {
                queryArray.push(id);
                animationTarget(this).animate({ opacity: 1 }, 200);
            }
            else {
                queryArray.splice(i, 1);
                if (queryArray.length == 0) {
                    fillInIds(elements, queryArray);
                    animationTarget(elements).animate({ opacity: 1 }, 200);
                }
                else
                    animationTarget(this).animate({ opacity: 0.5 }, 200);
            }

            setResetState();
            executeQuery();
        });
    }

    setupSearchByToggles(types, query.types);
    setupSearchByToggles(concepts, query.concepts);
    

    // search text
    var textTimer = null, oldText = "";
    function searchTextChanged() {
        var t = $.trim($(".searchBox input").val());
        if (t == oldText)
            return;

        query.text = t.split(/\s+/);
        $.each(query.text, function (i, val) {
            query.text[i] = val.toLowerCase();
        });
        oldText = t;
        setResetState();
        executeQuery();
    }
    
    $(".searchBox input").keyup(function () {
        if (textTimer)
            return;
        
        textTimer = setTimeout(function () {
            textTimer = null;
            searchTextChanged();
        }, 200);
    }).change(function () {
        searchTextChanged();
    });

    searchTextChanged();

    // price range
    $(".productOverview .priceRange").change(function () {
        var v = $(this).val();
        var from = null, to = null;
        if (v != "") {
            var t = v.split(':');
            if (t[0] != "")
                from = +t[0];
            if (t[1] != "")
                to = +t[1];
        }

        if (from != query.price.from || to != query.price.to) {
            query.price.from = from;
            query.price.to = to;
            setResetState();
            executeQuery();
        }
    });
    
    // setup reset button
    var resetButton = $(".productOverview .searchBar .reset");
    function resetIsActive() {
        return query.types.length != types.length ||
            query.concepts.length != concepts.length ||
            query.text.length != 0 ||
            query.price.from != null || query.price.to != null;
    }

    function setResetState() {
        var active = resetIsActive();
        if (resetIsActive())
            resetButton.fadeIn(300);
        else
            resetButton.fadeOut(300);
    }

    function resetUI() {
        function reset(elements, queryArray, selectedElements) {
            queryArray.splice(0, queryArray.length);
            
            if (selectedElements) {
                fillInIds(selectedElements, queryArray);
                animationTarget(selectedElements).animate({ opacity: 1 }, 200);
                animationTarget(elements.not(selectedElements)).animate({ opacity: 0.3 }, 200);
            }
            else {
                fillInIds(elements, queryArray);
                animationTarget(elements).animate({ opacity: 1 }, 200);
            }
        }

        var selectedTypes = null, selectedConcepts = null;
        if (urlState.t) {
            selectedTypes = types.filter('#pt' + urlState.t);
            urlState.t = null;
        }
        if (urlState.c) {
            selectedConcepts = concepts.filter('#pc' + urlState.c);
            urlState.c = null;
        }

        reset(types, query.types, selectedTypes);
        reset(concepts, query.concepts, selectedConcepts);
        query.text = [];
        $(".searchBox input").val("");

        query.price.from = null;
        query.price.to = null;
        
        var priceRange = $(".productOverview .priceRange").get(0);
        var priceRangeIndex = 0;
        if (urlState.p) {
            var p = +urlState.p;
            urlState.p = null;

            if (p) {
                $.each(priceRange.options, function (i, v) {
                    if (v.value == "") // skip dummy
                        return;
                    
                    var t = v.value.split(':'),
                        lower = +t[0], upper = +t[1];
                    if (p >= lower && (!upper || p <= upper)) {
                        priceRangeIndex = i;
                        query.price.from = lower;
                        query.price.to = upper ? upper : null;
                        return false;
                    }
                });
            }
        }
        priceRange.selectedIndex = priceRangeIndex;
        
        setResetState();
        executeQuery();
    }
    
    resetButton.click(function () {
        if (!resetIsActive())
            return;
        
        resetUI();
    });

    resetUI();
    
    
    // switch box on reseller pages
    var direction = -1;
    $(".leftSidebar .switchBox").click(function () {
        var box = $(this).parents(".box");
        
        // possibly switch direction 
        if (direction > 0 && box.prev(".box").length == 0)
            direction = -1;
        else if (direction < 0 && box.next(".box").length == 0)
            direction = 1;

        box.parents(".inner").animate({ left: "+=" + direction * 200 });
    });

    // product type hover tip
    types.qtip(qtipProductTypeStyle);
});
