/* 
 * Created by David Galvis
 */

function HomeSearch(input, options){
    jQuery.extend(this, options);
    this.key = input;
    this.input = jQuery("#" + input);
    this.init();
    //this.ajaxManager = jQuery.manageAjax({manageType: 'abortOld', maxReq: 3, blockSameRequest: true});
    this.ajaxManager = jQuery.manageAjax.create('homeSearchAM', {queue: 'clear', abortOld: true, cacheResponse: true});
}

var KEY = {
    UP          : 38,
    DOWN        : 40,
    LEFT        : 37,
    RIGHT       : 39,
    DEL         : 46,
    TAB         : 9,
    RETURN      : 13,
    ESC         : 27,
    COMMA       : 188,
    PAGEUP      : 33,
    PAGEDOWN    : 34,
    BACKSPACE   : 8,
    SPACE       : 32,
    HOME        : 36,
    END         : 35,
    SHIFT       : 16

};

HomeSearch.prototype =
{
    delay: 100, // Delay for ajax query
    target : '/application/ajax/homeSearch.php',

    /**
     * Dispay results options
     */
    settings : {
        restaurants : true,
        communities : false,
        people : false,
        cities : false,
        recommendation : false,
        recorestaurant : false
    },

    /**
     * Contains search result element (p)
     */
    items : [],

    /**
     * Align of the autocomplete results
     * left | right | xRight(left of results on right of input)
     */
    align: 'left',

    /**
     * Align verticaly the the result relatively to his top
     * bottom | middle | top (TODO)
     */
    vAlign: 'bottom',
    /**
     * Class for container
     */
    className : '',

    /**
     *Class for input when loading
     */
    loadingClass : 'loading',

    /**
     * Current selected item
     */
    selected : null,

    /**
     * Submenu
     */
    submenu : null,

    /**
     * If set to true, if the input is inside a form tag, the form will be submited
     * ENTER key press
     */
    submitOnReturn : false,

    selectOnTab : true,

    useNyroModal : true,
    
    init : function()
    {
        var _this = this;

        /*
         * Result container
         */
        //var resultsContainer = jQuery("<div id='" + this.key +"_test' style='position:absolute;'></div>");
        //this.resultsContainer = resultsContainer;
        this.results = jQuery("<div class='homeSearchContainer homeSearchResults " + this.key + "'></div>");
        //resultsContainer.append(this.results);
        jQuery(document.body).prepend(this.results);
        this.input.css({position:'static'});

        

        this.input.blur(function(event){
            try{
              clearTimeout(requestTimeout);
              clearTimeout(hideTimeout);
            } catch(e){}
            setTimeout(function(){
                _this.hide();
                _this.abortRequest();
            },300);
            
            return false;
        });
        
        /*
         * Events
         */
        /*jQuery("body").click(function(event){

            try {
                var parents = jQuery(event.originalTarget).parents('.' + _this.key);
                //console.log(parents);
                if (parents.length == 0)
                _this.hide();
            } catch (e){};
            
        })*/
        
        this.input.keydown(function(event)
        {
            switch(event.keyCode)
            {
                case KEY.UP:
                    event.preventDefault();
                    _this.movePrev();
                    break;

                case KEY.DOWN:
                    event.preventDefault();
                    _this.moveNext();
                    break;

                /*case KEY.RIGHT:
                    event.preventDefault();
                    _this.showSubmenu();
                    break;*/

                case KEY.PAGEUP:
                    _this.moveFirst();
                    break;
                    
                case KEY.PAGEDOWN:
                    _this.moveLast();
                    break;
                    
                case KEY.ESC:
                    _this.hide();
                    break;

                case KEY.TAB:
                        _this.abortRequest();
                        break;  
                case KEY.RETURN:

                    if (_this.selected != null)
                        _this.selected.trigger('click');
                    _this.hide();

                    if (!_this.submitOnReturn){
                        //console.log('not submited');
                        return false;
                    }
                    //console.log(_this.submitOnReturn);
                    break;

                case KEY.SPACE:
                    break;
                    
                
                case KEY.LEFT:
                case KEY.HOME:
                case KEY.SHIFT:
                case KEY.END:
                case KEY.RIGHT:
                    break;
                default:
                    _this.sendRequest();
            }
        });

        this.input.click(function(){
           if(this.ajax)
              _this.sendRequest();
        });
    },

    sendRequest : function()
    {
        var _this = this;
        if (this.input.val().length > 1 && this.input.val()!=""){
            this.input.addClass(_this.loadingClass);
            try{
              clearTimeout(requestTimeout);
            } catch(e){}
            requestTimeout = setTimeout(function(){
                if (_this.input.val().length > 2 && _this.input.val()!=""){
                _this.ajaxManager.abort();
                _this.ajaxManager.add({
                    type: "post",
                    url : _this.target + '?ajax=' + _this.ajax,
                    data : {
                        keywords : _this.input.val(),
                        settings : jQuery.toJSON(_this.settings)
                    },
                    success : function(response){
                        if (response==null || response.length==0)
                        {
                            setTimeout(function(){
                                _this.input.removeClass(_this.loadingClass);
                            },0);
                            return;
                        }
                        _this.results.html(response);
                        _this.results.show();
                        var offset = _this.input.offset();

                        // Aligning horizontally the result box
                        var left;
                        if (_this.align == 'left')
                            left = offset.left;
                        else if (_this.align == 'xRight')
                            left = offset.left + _this.input.width()+ 20;
                        else
                            left = offset.left - (_this.results.width()-_this.input.width());

                        // Aligning vertically the result box
                        var top;
                        if (_this.vAlign == 'middle')
                            top = offset.top - (_this.results.height()/2);
                        else
                            top = offset.top + _this.input.height()+10;

                        // Position if the result box
                        _this.results.css({
                            zIndex:99000,
                            top: top,
                            left: left,
                            textAlign:'left'
                        });

                        jQuery(function(){
                            var options = {
                                exact:"partial",
                                style_name_suffix:false,
                                highlight: '.homeSearchResults',
                                nohighlight : ".not_highlightable",
                                keys:_this.input.val()
                            };
                            //jQuery('.homeSearchResults').SearchHighlight(options);
                            //jQuery('.homeSearchResults').highlight(_this.input.val());
                            _this.addItemEffects();
                            _this.items = _this.results.find(".item");
                        });
                        setTimeout(function(){
                            _this.input.removeClass(_this.loadingClass);
                        },100);
                    }

                });

                } else
                    {
                            _this.input.removeClass(_this.loadingClass);
                      _this.hide();
                    }
            },_this.delay);
        } else {
            //this.results.empty();
            this.hide();
        }
    },

    hide : function(){
        var _this = this;
        try{
          clearTimeout(hideTimeout);
        } catch(e){}
        hideTimeout = setTimeout(function(){
            _this.results.hide();
        },350);
    },

    /**
     * Adds effects to mouse over actions
     */
    addItemEffects : function(){
        var _this = this;
        // Mouseover effect
        this.results.find(".item").each(function(){
            //
            jQuery(this).mouseover(function(event){
                event.preventDefault();
                event.stopPropagation();
                _this.select(jQuery(this));
                //_this.showSubmenu(jQuery(this));
                // Shows submenu
                var item = jQuery(this);
                try{
                    clearTimeout(expandTimeout);
                }catch(e){}
                expandTimeout = setTimeout(function(){
                    _this.showSubmenu(item);
                },0);
                return false;
            });
            jQuery(this).mouseout(function(){
                _this.unselect(jQuery(this));
                return false;
            });
        });
        if (this.useNyroModal)
            jQuery('.item a.nyroModal').nyroModal();
    },

    /**
     * Selects the item (highlight)
     * @param jquery item
     */
    select : function(item){
        this.unselectAll();

        // Hide visible submenus
        try{
            // If parent is a submenu container
            if (!item.parent('div').hasClass('submenu'))
                this.hideSubmenu();
        } catch(e){};
    
        this.selected = item;
        item.addClass("homeSearchOver");
    },

    /**
     * Unselects item
     */
    unselect : function(item){
        //this.previous = item;
        this.selected = null;
        item.removeClass("homeSearchOver");
    },

    /**
     * Unselects all items
     */
    unselectAll : function(){
        var _this = this;
        this.items.each(function(){
            _this.unselect(jQuery(this));
        });
    },

    /**
     * Move to next item
     */
    moveNext : function()
    {
        var item;
        if (this.selected == null)
            item = this.results.find(".item:first");
        else {
            if(this.selected.nextAll("* .item").length == 0)
                item = this.results.find(".item:first");
            else { 
                item = this.selected.nextAll("* .item");
                item = item[0];
                if (jQuery(item).attr('class') != 'item'){
                    item = this.selected.next("* .item").next("* .item");
                }
            }
        }
        this.unselectAll();
        this.select(jQuery(item));
    },

    /**
     * Move to previous item
     */
    movePrev : function()
    {
        var item;
        if (this.selected == null)
            item = this.results.find(".item:last");
        else {
            if(this.selected.prevAll("* .item").length == 0)
                item = this.results.find(".item:last");
            else {
                item = this.selected.prevAll("* .item");
                item = item[0];
                if (jQuery(item).attr('class') != 'item')
                    item = this.selected.prev("* .item").prev("* .item");
            }
        }
        this.unselectAll();
        this.select(jQuery(item));
    },

    /**
     * Moves to last element
     */
    moveLast : function()
    {
        var item = this.results.find(".item:last");
        this.unselectAll();
        this.select(jQuery(item));
    },
    /**
     * Moves to last element
     */
    moveFirst : function()
    {
        var item = this.results.find(".item:first");
        this.unselectAll();
        this.select(jQuery(item));
    },

    /**
     * Displays the submenu if it exists
     * @param object item  Element to expand
     */
    showSubmenu : function(item)
    {
        this.submenu = item.next('.submenu');
        this.submenu.show();
    },

    hideSubmenu : function(){
        this.results.find('.submenu').hide();
    },

    ajaxRequest: function(bool){
        this.ajax = bool;
    },
    
    setTarget : function(target){
        this.target = target;
    },

    setSettings : function(settings){
        this.settings = settings;
    },

    abortRequest : function(){
        this.input.removeClass(this.loadingClass);
        this.hide();
        this.ajaxManager.abort();
    }
};

