/**
 * Top search component
 *
 * @author  Mista K.
 * @responces

{"tobs":[
    {"id":2,"name":"Aka","selected":false,"subtob":[
        {"id":4,"name":"Cykel","selected":false},
        {"id":6,"name":"Motorcykel","selected":false}
    ]},
    {"id":3,"name":"Gora","selected":false,"subtob":[
        {"id":28,"name":"Shopping","selected":false},
        {"id":29,"name":"Kultur","selected":false}
    ]},
    {"id":4,"name":"Servering","selected":false,"subtob":[
        {"id":25,"name":"Bar","selected":false},
        {"id":22,"name":"Lunch ","selected":false}
    ]},
    {"id":1,"name":"Bo","selected":true,"subtob":[
        {"id":13,"name":"Lagenhet","selected":false},
        {"id":14,"name":"Hus","selected":false}
	]}
],
"keywords": {
    "categories":[
        {"id":2,"name":"Athmosphere","keywords":[
            {"id":108,"name":"Rofylld","selected":false},
            {"id":106,"name":"Familjar","selected":false}
        ]},
        {"id":101,"name":"Sasong","keywords":[
            {"id":104,"name":"Var","selected":false},
            {"id":102,"name":"Vinter","selected":false}
        ]}
    ],
    "regions":[
        {"id":13,"name":"V%C3%A4stra G%C3%B6taland","selected":false},
        {"id":11,"name":"S%C3%B6dermanland","selected":false}
    ]
}
}

{"count":1, "products":[
    {"id":1,
     "name":"Hangglider Combat L 12",
     "link":"%2Ftravel%2Fproduct%2F1",
     "desc":"The Aeros Combat L 12 is a further development of the Combat L 07, a glider that...",
     "dests":["Gullsp%C3%A5ng","V%C3%A4stra G%C3%B6taland"]
     }
]}
 
 
*/

(function () {

    /**
     * Create private slider as quick solution
     *
     * @param  target  {DOMNode}  "#top-search .tob-slider"
     * @param  index   {Integer}  index of active item
     */
    var Slider = function (target, index) {
        // holder for all slider positions
        var sliderPos = [];
        var sliderObj;

        var me = this;
        TRAVEL.Observable2(this);

        var eles = $(".tob-list li", target);
        var i, w = 0;
        for (i = 0; i < eles.length; i++) {
            var outW = $(eles.get(i)).outerWidth();
            sliderPos[i] = w + Math.floor(outW / 2) - 13;
            w += outW;
        }
        
        var getSliderIndex = function(value) {
            var v = 100000, index;
            for (var i = 0; i < sliderPos.length; i++) {
                var testMin = Math.abs(value - sliderPos[i]);
                if (testMin < v) {
                    v = testMin;
                    index = i;
                }
            }
            return (index);
        };
        
        var glueToNearest = function(e, ui) {
            var index = getSliderIndex(ui.value);
            if (Math.abs(ui.value - sliderPos[index]) > 2) {
                $(sliderObj).slider("moveTo", sliderPos[index]);
            }
            me.notify("onChange", index);
        };
        
        sliderObj = $(".ui-slider", target).css("width", w).
            slider({'axis': 'horizontal', 'max': w - 26,
                'startValue': sliderPos[index || 0], 'stop': glueToNearest});

        $("span", eles).click(function () {
            var index = $.inArray(this.parentNode, eles);
            if (index >= 0 && index < sliderPos.length) {
                $(sliderObj).slider("moveTo", sliderPos[index]);
            }
        });

    };


    /**
     * Constructor
     *
     * @param  target  {DOMNode}  #top-search
     */
    TRAVEL.TopSearch = function (target) {

        var assets = TRAVEL.Assets.TopSearch;

        var self = this;
        var root = target;
        
        var head = $(".top-search-head", root).get(0);

        var searchOptions = {
            panel: '',
            tob: 0,
            subtobs: [],
            keywords: [],
            regions: [],
            search: ''
        };

        var searchTimer = null, searchId = 0;

        var activeTob = -1;

        var alwaysOpen = false;

        var panels = {
            "product": { ajaxSearch: baseUrl + 'ajaxCommand.service?command=travel.JSONSearchProductModelProvider' },
            "destination": { ajaxSearch: baseUrl + 'ajaxCommand.service?command=travel.JSONSearchDestinationModelProvider' },
            "sweetspot": { ajaxSearch: baseUrl + 'ajaxCommand.service?command=travel.JSONSearchSweetSpotModelProvider' },
            "producer": { ajaxSearch: baseUrl + 'ajaxCommand.service?command=travel.JSONSearchProducerModelProvider' }
        };

        this.setAlwaysOpen = function(flag) {
            alwaysOpen = !!flag;

            if (alwaysOpen) {
                self.togglePanel(searchOptions.panel);
            } else {
                self.closePanel();
            }
        };

        /**
         * Create Top Search panel form TOBs, SubTOBs and keywords list
         */
        this.create = function (model, currentPanel) {

            var i, j;
            var obj = [];

            // remove unused tobs
            for (i = model.tobs.length - 1; i >= 0; i--) {
                if (model.tobs[i].id === 2 || model.tobs[i].id === 4) {
                    model.tobs.splice(i, 1);
                }
            }

            searchOptions.panel = currentPanel || 'product';

            var buildKeywordsGroup = function (name, keywords, isRegions) {
                var j;
                var obj = [];
                var itemName = (isRegions) ? "region" : "keyword";
                
                obj.push('<div class="group', (isRegions ? ' regions no-border' : ''), '">',
                    '<h2>', name, '</h2>',
                    '<ul class="unselectable keywords clearer', ((isRegions) ? ' regions' : ''), '">');
                    for (j = 0; j < keywords.length; j++) {
                        var keywordClass = ((j === keywords.length - 1) ? "last" : "") + (keywords[j].selected ? " selected" : "");
                        obj.push('<li id="', itemName, '-', keywords[j].id, '" class="', keywordClass, '"><span unselectable="on">', keywords[j].name, '</span></li>');
                    }
                obj.push('</ul></div>');
                return(obj.join(''));
            };
            
            obj.push('<div class="top-search-options">',
                '<div class="clearer">',
                    '<div class="column1">',
                    '<div class="tob"><div class="tob-cap">',
                        '<div class="tob-slider">',
                            '<ul class="unselectable tob-list clearer">');
            for (i = 0; i < model.tobs.length; i++) {
                var tobId = model.tobs[i].id;
                if (tobId !== 0) {
                    obj.push('<li id="tob-', tobId, '"><span unselectable="on">');
                    obj.push(model.tobs[i].name);
                    obj.push('</span></li>');
                    if (model.tobs[i].selected || activeTob === -1) {
                        activeTob = i;
                    }
                }
            }
            obj.push(       '</ul>',
                            '<div class="ui-slider"><div class="ui-slider-handle"></div></div>',
                        '</div>',
                        '<div class="subtob-list">');
            for (i = 0; i < model.tobs.length; i++){
                obj.push('<ul class="unselectable keywords clearer hidden', (model.tobs[i].id === 0 ? ' sweetspottype' : ''), '">');
                var subtob = model.tobs[i].subtob;
                for (j = 0; j < subtob.length; j++) {
                    var subtobClass = ((j === subtob.length - 1) ? "last" : "") + (subtob[j].selected ? " selected" : "");
                    obj.push('<li id="subtob-', (model.tobs[i].id === 0 ? 'sweetspottype-' : ''), subtob[j].id, '" class="', subtobClass, '">',
                            '<span unselectable="on">', subtob[j].name, '</span>',
                        '</li>');
                }
                obj.push('</ul>');
            }
            obj.push('</div>',
                    '</div></div>',
                    '<div class="additional"><div class="additional-cap">',
                        '<div class="additional-title">',
                            '<h1>', assets.itshouldbetakenintoaccount, '</h1>',
                            '<div class="collapse">Collapse</div>',
                        '</div>');
            var data = model.keywords;
            for (i = 0; i < data.categories.length; i++) {
                obj.push(buildKeywordsGroup(data.categories[i].name, data.categories[i].keywords, false));
            }
            obj.push(buildKeywordsGroup("Regions", data.regions, true));
            obj.push('</div>',
                    '<div class="bottom"><div class="bottom-cap">&nbsp;</div></div>',
                    '</div>',
                    '</div>'); // column1

            obj.push('<div class="column2">',
                    '<div class="results"><div class="results-cap">',
                        '<div class="results-bush">',
                            '<div class="count"><a href="#"><span></span></a></div>',
                            '<div class="filter">',
                                '<span>', assets.enterkeyword, '</span><br />',
                                '<input type="text" value="" /></div>',
                            '<div class="goto"><a href="#"><span>', assets.viewresults, '</span></a> &rarr;</div>',
                        '</div>',
                    '</div></div>',
                    '<div class="additional"><div class="additional-cap">',
                        '<div class="preview hidden">',
                            '<h2>', assets.resultspreview, '</h2>',
                        '</div>',
                    '</div>',
                    '<div class="bottom"><div class="bottom-cap">&nbsp;</div></div>',
                    '</div>',
                '</div>', // column2
            '</div></div>');


            var panelEle = $(obj.join('')).appendTo(head.parentNode);


            $('.additional .collapse', panelEle).click(function () {
                $(this).parents('.additional').toggleClass('open');
                collectKeywords();
                triggerSearch();
            });

            $(".subtob-list span", panelEle).click(subtobClickListener);

            $(".results .filter input", panelEle).keyup(function () {
                searchOptions.search = $(this).val();
                triggerSearch();
            });

            $(".additional .keywords span", panelEle).click(keywordClickListener);

            $(".top-search-head li span", root).click(function () {
                var panelName = this.className; /* product, destination or producer */
                self.togglePanel(panelName);
            });

            $("div.collapse-red", root).click(function () {
                self.closePanel();
            });

            updateTob(activeTob);
        };

        /**
         * send search request
         */
        var triggerSearch = function () {

            if (searchTimer) {
                window.clearTimeout(searchTimer);
            }

            searchTimer = window.setTimeout((function (query) {
                return function () {
                    var results = $(".results", root).get(0);

                    query.id = (new Date()).getTime().toString();

                    TRAVEL.postJSON(panels[searchOptions.panel].ajaxSearch, query, function (data) {

                        if (searchId > data.id) {
                            // request was returned too late
                            return;
                        }

                        searchId = data.id;
                        
                        var searchUrl;
                        if (data.hash) {
                            searchUrl = baseUrl + query.panel + '-search/' + data.hash;
                        } else {
                            searchUrl = baseURLParts;
                        }

                        results.firstChild.firstChild.childNodes[0].firstChild.href = searchUrl;
                        results.firstChild.firstChild.childNodes[2].firstChild.href = searchUrl;

                        if (query.panel == "product")
                            $(".results .count span", root).text(assets.productsfound.sprintf(data.count));
                        else if (query.panel == "destination")
                            $(".results .count span", root).text(assets.destinationsfound.sprintf(data.count));
                        else if (query.panel == "producer")
                            $(".results .count span", root).text(assets.producersfound.sprintf(data.count));
                        else
                            $(".results .count span", root).text(data.count + " " + query.panel + "s found");

                        if (data.count > 0) {
                            var previewObj = ['<ul>'];
                            var items = data.items;
                            for (var i = 0; i < items.length; i++) {
                                previewObj.push('<li', (i === items.length - 1 ? ' class="last"' : ''), '>',
                                        (items[i].image ? ('<img alt="" src="'+items[i].image+'" />') : ''),
                                        '<h3><a href="', items[i].link, '">',
                                            items[i].name,
                                        '</a></h3>',
                                        '<p class="location">', items[i].location.join(', '),  '</p>',
                                        '<p>', items[i].desc, '</p>',
                                    '</li>');
                            }
                            previewObj.push('</ul>');
                            $(".preview", root).children("ul").remove().end().append(previewObj.join('')).removeClass("hidden");
                        } else {
                            $(".preview", root).addClass("hidden");
                        }
                    });
                    
                    searchTimer = null;
                };
            })(searchOptions), 15); //1500
        
        };

        var collectKeywords = function () {
            searchOptions.keywords = [];
            searchOptions.regions = [];

            var keyHolders = $(".additional.open .keywords", root);
            var kEles = $("li.selected", keyHolders.not(".regions"));
            var rEles = $("li.selected", keyHolders.filter(".regions"));

            kEles.each(function () {
                var eleId = (this.id).match(/^keyword-(\d+)$/);
                searchOptions.keywords.push(eleId[1]);
            });

            rEles.each(function () {
                var eleId = (this.id).match(/^region-(\d+)$/);
                searchOptions.regions.push(eleId[1]);
            });
        };

        var collectSubtobs = function () {
            searchOptions.subtobs = [];
            var subtob = $(".subtob-list", root).children().not(".hidden");
            var eles = $("li.selected", subtob);
            eles.each(function () {
                var subtobId = (this.id).match(/^subtob-(sweetspottype-)*(\d+)$/);
                searchOptions.subtobs.push(subtobId[2]);
            });
        };

        var updateTob = function (index) {
            var eles = $(".subtob-list", root).children();
            $(eles).addClass("hidden");
            $(eles.get(index)).removeClass("hidden");

            eles = $(".tob-list", root).children();
            var tobId = (eles.get(index).id).match(/^tob-(\d)+$/);
            searchOptions.tob = tobId[1];

            collectSubtobs();

            if ($(root).hasClass("open")) {
                triggerSearch();
            }
        };

        var subtobClickListener = function () {
            $(this.parentNode).toggleClass("selected");
            collectSubtobs();
            triggerSearch();
        };

        var keywordClickListener = function () {
            $(this.parentNode).toggleClass("selected");
            collectKeywords();
            triggerSearch();
        };

        this.closePanel = function () {
            $(root).removeClass("open");
            $("li.selected", head).removeClass("selected");
        };

        this.togglePanel = function (panelName) {
            // test for registred panel name
            if (!panels[panelName]) {
                return;
            }
            
            var headItem = $("li span." + panelName, head).parent();

            if ($(headItem).hasClass("selected") && $(root).hasClass("open")) {
                // close panel
                if (!alwaysOpen) {
                    self.closePanel();
                }
            } else {
                // open appropriate panel
                $("li.selected", head).removeClass("selected");
                $(headItem).addClass("selected");
                searchOptions.panel = panelName;
                $(root).addClass("open");

                if (panelName === 'sweetspot') {
                    $('.tob-slider', root).addClass('hidden');
                    $('.group:not(.regions)', root).addClass('hidden');
                    $('.subtob-list', root).children('ul').addClass('hidden')
                            .filter('.sweetspottype').removeClass('hidden');
                } else {
                    $('.tob-slider', root).removeClass('hidden');
                    $('.group', root).removeClass('hidden');
                    $('.subtob-list', root).children('ul.sweetspottype').addClass('hidden');
                    if (!self.slider) {
                        self.slider = new Slider($(".tob-slider", root).get(0), activeTob);
                        self.slider.attachObserver("onChange", updateTob);
                    } else {
                        self.slider.notify('onChange', activeTob)
                    }
                }

                triggerSearch();
            }
        };
    };
    
})();