PW = PW || {};

$(function() {

    // global variables {{{
    var defaults = {
        thumbImageSize: 250,
        presetSize: 50,
        showOutfits: true,
        showItems: true,
        preloadPages: 3,
        saveState: false,
        buttonsTxt: {
            'all': 'all',
            'new': 'new',
            'sale': 'sale',
            'me': 'my closet',
            'friends': 'friends'
        },
        rows: 2,
    };

    // }}}

    // set Default settings {{{
    PW.productNavDefaults = function(obj) {
        if (typeof obj == "object") {
            defaults = $.extend({}, defaults, obj);
        }
    };
    // }}}

    /**
     *  Simple callback that is called for each result page
     */
    PW.onResults = function(type) {
    };
    
    PW.productNav = function(options) {
        var 
            that    = this,
            pages   = {},
            buffer  = {},
            curPage = {},
            maxPage = {},
            form,
            target = $('body'); //default target 

        // setPagination {{{
        function setPagination(type, page, max) {
            var el, href;
            el = $('.' + type + 's-page-count', target);
            

            $('.'+type+'s_moveprev').hide();
            $('.'+type+'s_movenext').hide();

            max = max || maxPage[type];

            if (!el.length || max < 1) {
                el.hide();
                return;
            }
            
            el.parent().show().end()
              .children('span:first').text(page).end();

            if (max) {
                el.find('span:last').text(max).end();
            }

            if (page > 1) {
                $('.'+type+'s_moveprev').show();
            }

            if (max && page != max) {
                $('.'+type+'s_movenext').show();
            }
        }
        // }}}

        // renderCurrentPage {{{
        function renderCurrentPage(type, data) {
            logClicktale('PW.productNavSupport.renderCurrentPage(' + JSON.stringify(type) + ', ' + JSON.stringify(data) + ')');
            
            var dest = $("#results-" + type + "s", target).empty();
            var tpl = $('#prNavItems').html();
            
            dest.removeClass('preloader').append(tpl, {docs:data, imageSize:options.thumbImageSize, presetSize:options.thumbRealImageSize, type:type});
            $('.' + type + 's-pagination').show();

            PW.onResults(dest, type, data);
        }
        // }}}

        // showResultPage {{{
        function showResultPage(type, limit, page) {
            logClicktale('PW.productNavSupport.showResultPage(' + JSON.stringify(type) + ', ' + JSON.stringify(limit) + ', ' + JSON.stringify(page) + ')');
            
            var params = form.values();
            params.limit  = (limit*options.preloadPages);
            params.types  = [type];
            params.offset = (page*limit);

            if (typeof buffer[type] == "undefined") {
                buffer[type]  = {};
            }


            curPage[type] = page;

            if (options.saveState) {
                $.cookie('nav:' + options.saveState, JSON.stringify($.extend({page:curPage}, form.values())));
            }

            if (typeof buffer[type][page] == "object") {
                renderCurrentPage(type, buffer[type][page]);
                setPagination(type, page+1);
                return;
            }

            $('#results-' + type + 's', target).addClass("preloader");

            $.ajax({
                url: '/search/nav', 
                data: params,
                dataType: 'json',
                success: function(json) {
                    if (json && json.status && json.status == 'success') {

                        for (var i=0; i < options.preloadPages; i++) {
                            buffer[type][page+i] = json.data[type].docs.slice(limit*i, (i+1)*limit);
                        }

                        renderCurrentPage(type, buffer[type][page]);
                        maxPage[type] = Math.ceil(json.data[type].numFound/pages[type]);
                        setPagination(type, page+1);
                    }
                }
            });
        }
        // }}}

        // doSearch {{{
        function reloadSearch(e) {
            e ? e.preventDefault() : '';
            buffer  = {};

            if (options.showItems) {
                showResultPage('item', pages.item, curPage.item);
            }

            if (options.showOutfits) {
                showResultPage('outfit', pages.outfit, curPage.outfit);
            }

            return false;
        }

        function doSearch(e, page) {
            e ? e.preventDefault() : '';

            buffer  = {};
            curPage = {};

            if (options.showItems) {
                showResultPage('item', pages.item, 0);
            }

            if (options.showOutfits) {
                showResultPage('outfit', pages.outfit, 0);
            }

            return false;
        }
        // }}}

        // calcItemsPerPage {{{
        function calcItemsPerPage() {
            var i =  Math.floor($('#results-items', target).width() / (options.thumbRealImageSize||options.thumbImageSize))
                items = i * (options.rowsItem || options.rows),
                outfits = i * (options.rowsOutfits || options.rows),
                changed = pages.item != items || pages.outfit != outfits; 

            pages.item   = items;
            pages.outfit = outfits;

            return changed;
        }
        // }}}

        // select {{{
        /**
         *  Create a 'select' element, the vork way.
         */
        function createSelect(name, values, firstElement) {
            var elem = $('<select>').attr({name:name, id:name}).addClass('data-storage');

            elem.append( $('<option>').html(firstElement || name).val('').attr('selected', true) );

            var e, value, i, group;
            for(e in values) {
               value = values[e];
               if (typeof value == "object") {
                    group = $('<optgroup>').attr('label', e);
                    for (i in value) {
                        group.append( $('<option>').html(value[i]).val(i) );
                    }
                    elem.append(group);
               } else {
                    elem.append( $('<option>').html(value).val(e) );
               }
            }
            elem.change(doSearch);

            return elem;
        }
        // }}}

        // Presets {{{
        function presetClick(elem) {
                for(var i in elem.fields) {
                    $('#' + i, target).val(elem.fields[i]);
                }
                form.submit();
        }
        
        function presetClickEvent(elem) {
            return function(e) {
                e.preventDefault();
                
                logClicktale('PW.productNavSupport.presetClick(' + JSON.stringify(elem) + ')');
                presetClick(elem);
            };
        }

        function showPresets() {
            var i, elem, dest, tpl = $('#prNavElement').html()

            if (options.showOutfits && typeof options.presets == "object" && typeof options.presets.outfits == "object") {
                dest = $('<ul>').attr('class', 'search-presets').appendTo($('#results-outfits', target).empty());
                for(var i in options.presets.outfits) {
                    elem = options.presets.outfits[i];
                    dest
                        .append(tpl, {elem:elem, i:i, presetSize: options.presetSize})
                        .find('li:last').find('a')
                            .click(presetClickEvent(elem));
                }
                dest.removeClass('displayNone');
                dest.paginate(pages.outfit,'Featured');
            }

            if (options.showItems && typeof options.presets == "object" && typeof options.presets.items == "object") {
                dest = $('<ul>').attr('class', 'search-presets').appendTo($('#results-items', target).empty());
                for(var i in options.presets.items) {
                    elem = options.presets.items[i];
                    dest.
                        append(tpl, {elem:elem, i:i, presetSize: options.presetSize})
                        .find('li:last').find('a')
                            .click(presetClickEvent(elem))
                            .mousedown(presetClickEvent(elem));
                }
                $('.items-pagination,.outfits-pagination', target).hide();
                dest.removeClass('displayNone');
                dest.paginate(pages.item,'Browse By Category');
            }
        }
        // }}}

        // setupFormEvents {{{
        function setupFormEvents() {
            form = $('form', target);
            form.submit(doSearch);
            $('#nav-form-reset', target).click(function(e) {
                e.preventDefault();
                logClicktale("jQuery('#nav-form-reset').click()");
                // reset form
                $(':input', form)
                    .not(':button, :submit, :reset, :hidden')
                        .not('*[type=radio]')
                            .val('')
                        .end().end()
                    .removeAttr('checked')
                    .removeAttr('selected');
                $('#friends', form).hide();
                showPresets();
                if (options.saveState) {
                    $.cookie('nav:' + options.saveState, null);
                }
                $("#closetof label", target).removeClass('selected');
                return false;
            });
            
            $('.items_moveprev,.items_movenext,.outfits_movenext,.outfits_moveprev', target).click(function(e) {
                e.preventDefault();
                if (!$(this).is(':visible')) {
                    return;
                }
                var type = $(this).attr('class').match(/^(([^s][^_])+)/)[0];
                    page = curPage[type];

                if ($(this).attr('class').match(/_movenext/)) {
                    page++;
                } else {
                    page--;
                }

                showResultPage(type, pages.item, page);
            });

            $("#closetof label", target).click(function(e) {
                if ($(this).hasClass('selected')) {
                    return e.preventDefault();
                }
                $("#closetof label", target).removeClass('selected');
                var id = $(this).addClass('selected').attr('for');
                $("#" + id, target).attr('checked', 'true');
            });

            $(':radio[name=closetof]', target).click(function() {
                this.value == 'friends' ?$('#friends', target).show():$('#friends', target).hide();
            });

            $(document).keydown(function(e){
                if (isAlt || $("#savecanvasdialog", target).is(':visible')) {
                    return;
                }
                
                if (e.keyCode == 37 && $('.items_moveprev,.outfits_moveprev', target).length) {
                    $('.items_moveprev:first,.outfits_moveprev:first', target).trigger('click');
                    return false;
                }
                if (e.keyCode == 39 && $('.items_movenext,.outfits_movenext', target).length) {
                    $('.items_movenext:first,.outfits_movenext:first', target).trigger('click');
                    return false;
                }
            });

            jQuery.resize.delay = 2000;
            $(window).resize(function() {
                if (!calcItemsPerPage()) {
                    return;
                }
            });
        }
        // }}}

        // createForm  {{{
        function createForm() {
            var tmp,
                column = $('<div class="column"></div>'),
                dest  = $('div.fields', target),
                dest1 = $('<div class="row"></div>').appendTo(dest),
                dest2 = $('<div class="row"></div>').appendTo(dest);


            if (options.optgroupCategories) {
                dest1.append(column.clone().append(createSelect('category', options.optgroupCategories, 'all categories')));
            }

            if (options.optgroupCategories) {
                dest1.append(column.clone().append(createSelect('price', options.prices)));
            }

            var input, container, button;
            var autocomplete = {
                delay:0,
                minLength: 0
            };

            var placeholderCSS = {
                    'font':'1em Georgia', 
                    'color':'grey', 
                    'position': 'absolute', 
                    'left':'6px',
                    'top':'1px', 
                    'overflow-x': 'hidden'
            };

            function select(input) {
                return function(event, ui) {
                    input.val(ui.item.value);
                    doSearch();
                }
            }
            
            // dataSource {{{
            function dataSource() {
                var keys = [], uniq = {};
                for (var i = 0, j = arguments.length; i < j; i++) {
                    if (typeof arguments[i] !== "object") {
                        continue;
                    }
                    for (var e in arguments[i]) {
                        if (typeof uniq[e] == "undefined") {
                            keys.push({value:e, label: arguments[i][e]});
                            uniq[e] = 1;
                        }
                    }
                }
                return function(request, response) {
                    var arr = [];
                    var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
                    for (var i in keys) {
                        if (!request.term || matcher.test(keys[i].label)) {
                            arr.push(keys[i]);
                            if (arr.length > 500) {
                                break;
                            }
                        }
                    }
                    response(arr);
                };
            }
            // }}}

            function onClick(input) {
                return function() {
                    if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
                        input.autocomplete( "close" );
                        return;
                    }
                    $( this ).blur();
                    input.autocomplete( "search", "" );
                    input.focus();
                }
            }    

            if (options.brands) {
                container = column.clone();
                input  = $('<input>').attr({id:'brand', name:'brand'});
                button = $('<input>').attr({'id':'brandsButton','type':'button'})
                    .val('sel').click(onClick(input));

                container.append(input);
                container.append(button);
                dest.append(container);
                
                autocomplete.source = dataSource(options.brands.stores, options.brands.brands);
                autocomplete.select = select(input);
                input.attr('placeholder', 'brands and stores')
                     .autocomplete(autocomplete)
                     .placeholder({'placeholderCSS' : placeholderCSS});
		
                input.autocomplete("widget").attr('id','brandsList');
            }

            if (options.trends) {
                container = column.clone();
                input  = $('<input>').attr({id:'trends', name:'trends'});
                button = $('<input>').attr({'id':'trendsButton','type':'button'})
                    .val('sel').click(onClick(input));
                container.append(input);
                container.append(button);
                dest.append(container);

                autocomplete.source = dataSource(options.trends);
                autocomplete.select = select(input);
                input.attr('placeholder', 'trends')
                     .autocomplete(autocomplete)
                     .placeholder({'placeholderCSS' : placeholderCSS});
                input.autocomplete("widget").attr('id','trendsList');
            }

            $('input[type=radio]', target).click(doSearch);
            $('#closetof_label label', target).click(doSearch);

            $('#closetof_label', target).html(options.buttonsTxt['all']);
            $('#closetof_newlabel', target).html(options.buttonsTxt['new']);
            $('#closetof_melabel', target).html(options.buttonsTxt['me']);
            $('#closetof_salelabel', target).html(options.buttonsTxt['sale']);
            $('#closetof_friendslabel', target).html(options.buttonsTxt['friends']);

            if (options.friends) {
                $('#closetof', target).parent().append(createSelect('friends', options.friends, 'all friends')
                    .hide());
            }
        }
        // }}}

        /**
         *  Constructor (I miss PHP :P)
         */
         function construct() {
            options = $.extend({}, defaults, options || {});

            if (options.target) {
                target = $(options.target);
            }
            
            // append template
            $(target).append($('#prNavTemplate').html(), options);
            
            calcItemsPerPage();
            createForm();
            showPresets();
            setupFormEvents();

            $('#results-outfits,#results-items', target).addClass('results-' + options.thumbRealImageSize);

            if (options.saveState) {
                var objStr = $.cookie('nav:' + options.saveState), obj;
                try {
                    obj = JSON.parse(objStr);
                    form.values(obj);
                    curPage = obj.page || {item:0,outfit:0};
                    reloadSearch();
                } catch (e) {}
            }
        }

        if($('#prNavTemplate').length == 1) {
            construct();
        } else {
            // load template
            $.get('/closet/getProductNavTemplate',  function(obj) {
                if (typeof obj == "object" && typeof obj['product-nav2'] == "string") {
                    $(obj['product-nav2']).appendTo(body);
                    construct();
                }

            }, 'json');
        }
        
        PW.productNavSupport = {
            presetClick: presetClick,
            renderCurrentPage: renderCurrentPage,
            showResultPage: showResultPage
        };
        
        return that;
    };
    
});

