/**
 * AutocomplateEntity - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 *
 *
 * Copyright (c) 2010 Davydkin Timur (lumen_tim@mail.ru)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.0
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

(function($) {
    var appl_url    = 'http://'+location.host+'/';
    var publACE,
    class_names = {
        pool            : 'ACE_pool',
        pool_cont       : 'ACE_pool_cont',
        input           : 'ACE_input',
        devider         : 'ACE_devider',
        items_list      : 'ACE_items_list',
        items_list_delete   : 'ACE_items_list_delete',
        srch_list       : 'ACE_search_list',
        srch_list_item  : 'ACE_search_list_item',
        srch_list_sel   : 'ACE_search_list_selected',
        srch_list_info  : 'ACE_search_list_info',
        srch_list_info_desc : 'ACE_search_list_info_desc',
        srch_list_info_fixed: 'ACE_fixed',
        srch_list_info_link : 'ACE_search_list_info_link',
        sl_entity_name  : 'ACE_entity_name',
        sl_entity_select    : 'ACE_entity_select',
        sl_entity_view  : 'ACE_entity_view',
        sl_entity_info  : 'ACE_entity_info',
        view_entity     : 'ACE_view_entity',
        add_entity      : 'ACE_add_entity',
        select_entity   : 'ACE_select_entity'
    },
    identifier = {
        srch_list_item  : 'ACE_iid_',
        input           : 'ACE_input'
    },
    settings,
    isTyping = false,

    $overlay,
    $pool,
    $poolCont,
    $itemList,
    $input,
    $srchList,
    $srchListItem,
    $srchListInfo,
    $srchListInfoLink,
    $selectButton,
    css_styles = {
        sl_entity_name  : {color: "#fe6f02"},
        sl_entity_select   : {"font-weight":"bold","text-align":"left"},
        sl_entity_view  : {"font-weight":"bold", "text-align":"center"},
        sl_entity_info  : {"text-align":"center"},
        sl_info_p       : {"color":"#fff", "padding":"0px 0px 0px 20px", "margin-bottom":"5px", background:"url("+appl_url+"images/ace_triangle.png) no-repeat 10px 50%"},
        sl_info_desc    : {"font-weight":"bold", "padding-left":"20px", background:"url("+appl_url+"images/ace_info.png) no-repeat 0% 50%"},
        srch_list       : {background:"#fff",border:"1px solid #afafaf",width:"285px","position":"absolute"},
        srch_list_sel   : {background:'#e8e8e8'},
        srch_list_nsel  : {background:'#fff'},
        input           : {color:"#bfbfbf", padding:"2px 5px 2px 5px", margin:"3px 0px 0px 3px", width:"270px", border:"1px"},
        pool_cont       : {height: "50px", background: '#fff', border:"1px solid #afafaf"},
        pool_item       : {"float":"left", border:"1px solid #f6d9bb", background:"#f2fde2",
                            padding:"2px 5px 2px 5px","font-weight":"bold",margin:"3px 0px 0px 3px"},
        srch_list_item_info : {width: "190px", padding: "5px", position: "absolute",display:"none",'z-index':1150,
                            border: '1px solid #afafaf', background:"#484848", opacity:"0.9", color:"#fff"}

    },
    css = {
        selectButton    : "float:right;padding: 5px 20px 5px 0px;",
        devider         : "height:1px;background:#c3c3c3;",
        srchListItemTbl : "width:100%;margin-bottom:10px;",
        infoLink        : "",
        infoP           : "padding: 2px 5px 2px 5px;color:#fff;"
    },
    html = {
        div_clear_both  : '<div style="clear:both;"></div>'
    },

    defaults = {
        id          :'',
        root_url    : 'http://'+location.host+'/',
        texts       : {
            msg_welcome         : "Type entity name",
            button_select       : "Select entity",
            select              : "Select",
            viewEntity          : "View entity",
            storedInformation   : "Stored information",
            speakersInformation : "Speaker information",
            votings             : "Votings",
            speakers            : "Speakers",
            amandementen        : "Amandementen"
        },
        html : {
            select_button   : '<a href="javascript:void(0)" class="button_3" ><i></i><span>Select entity</span><em></em> </a>'
            
        },
        limit_items  : true,
        items_count  : 5,

        selected_items  :{},
        url_data    : {
                      page:"main",
                      action:"entPoolListSelect",
                      async:1,
                      str:''},
        start       : 0,
        onHeightChange  : function(){},
        onSelectEntities: function(params){
             selectEntity(params);
        },
        beforeStart : function(){},
        afterEnd    : function(){}
    };

    publACE = $.fn.autocompleteEntity = function(o) {

        settings = $.extend(defaults, o || {});

        $(this).each(function() {

            init($(this));




        });
    }

    publACE.addPoolItemExt = function (o){
        addPoolItem(o);

    }
/*
 * Main functions
 *
*/
    function init($this){

        settings.beforeStart();

        createElements($this);

        addBinds();
        
        setSelectedItems();

        $input.blur();
        
        settings.afterEnd();
    }

    function  createElements($this){
        $overlay = $this;
        $overlay.append('<div class="'+class_names.pool_cont+'"><div class="'+class_names.pool+'" ></div></div>');

        $poolCont = $("."+class_names.pool_cont,$overlay);
        $poolCont.css( css_styles.pool_cont );

        $pool = $("."+class_names.pool,$overlay);

        $pool.append('<ul class="'+class_names.items_list+'" ></ul>');
        $itemList = $("."+class_names.items_list,$pool);

        $pool.append('<input id="'+identifier.input+'" class="'+class_names.input+'" value="'+
            settings.texts.msg_welcome+'"  />'+html.div_clear_both);
        $input = $( "."+class_names.input, $pool );
        $input.css( css_styles.input );

        $selectButton = $overlay.append('<div class="'+class_names.select_entity+'" style="'+css.selectButton+'" >'+
            settings.html.select_button+'</div>'+html.div_clear_both);
        $selectButton = $('.'+class_names.select_entity);

    }
/*
 *@todo add for ESC - clearInput
 **/
    function addBinds(){

         $selectButton.click( function(){
             selectPoolItems();


         });

         $poolCont.click(function(){
            inputClick();
         });

         $input.blur( function(){

            inputBlur();

         });

         $input.keydown( function(event){
            /*
             * Key codes:
             * 8 - Backspace
             * 27 - Escape
             * 13 - Enter
             * 37 - Left
             * 38 - UP
             * 39 - Right
             * 40 - DOWN
             * 46 - DELETE
             *
             **/
            var key     = event.keyCode || event.charCode;

            var isChar  = (( key >= 65 && key <= 90) || ( key >= 97 && key <= 122) )? 1: 0;

            var _str    =  $input.val();
            var _char   = '';

            var carPos  = getCaretPosition(document.getElementById(this.id));

            _str        = keypressValueProcessing({str:_str, 'key':key, 'carPos':carPos, 'isChar':isChar});

            switch (key) {
                
                case 13:
                    var _data = getItemDataForAddPool();
                    if (_data) addPoolItem(_data);
                    break;

                case 27:hideSearchList();break;
                    
                case 38:searchListNavigate('up');break;

                case 40:searchListNavigate('down');break;
            }

            if (!isChar && !_str) isTyping = false;
                else if (isChar) isTyping = true;
                

            if ( isChar || key == 8 || key == 46){


                settings.url_data.str = _str;

                $.getJSON(
                    settings.root_url,
                    settings.url_data,
                    function (json){
                        showSearchResultList(json);
                    }
                );

            }

        });

    }

    function addBindsSearchResultList(){
        $('li',$srchList).hover(

            function (){
                searchListItemSelect($(this));
            },
            function(){
                searchListItemSelect($(this), 1);
            }
        );

        $('.'+class_names.sl_entity_select+', .'+class_names.sl_entity_view,$srchList).hover(
            function (){
                $(this).css('text-decoration', 'underline');
            },
            function (){
                $(this).css('text-decoration', 'none');
            }
        );

        $("."+class_names.add_entity,$srchList).click(function (){

            var _data = getItemDataForAddPool($(this));

            addPoolItem(_data);
            
            hideSearchList();
            isTyping = false;
            inputClick();

        });

        $("."+class_names.view_entity,$srchList).click(function (){

            clearPool();

            var _data = getItemDataForAddPool($(this));

            addPoolItem(_data);

            selectPoolItems();
            
        });
    }

    function  addBindsSearchResultItemInfo(){
        $srchListInfo.hover(function(){},
            function(){
                $(this).hide().removeClass(class_names.srch_list_info_fixed);

            }
        );

        $srchListInfoLink.click( function(){

            var jq = InfoLinkGetInfo($(this));

            if (jq.is(":visible")){

                if ( jq.hasClass(class_names.srch_list_info_fixed)){
                    jq.removeClass(class_names.srch_list_info_fixed).hide();
                }else
                    jq.addClass(class_names.srch_list_info_fixed);

            }else{
                jq.addClass(class_names.srch_list_info_fixed).show();
                
            }

        });

        $srchListInfoLink.parent().hover(
            function(){
                $('.'+class_names.srch_list_info,$srchList).hide().removeClass(class_names.srch_list_info_fixed);

                var jq = InfoLinkGetInfo($(this));
                jq = jq.show();
            },
            function(){

                var jq = InfoLinkGetInfo($(this));
                
                if ( !jq.hasClass(class_names.srch_list_info_fixed) )    jq = jq.hide();

            }
        );

    }

    /*
     *
     **/
    function addPoolItem(data){
        if (data){
            data.id = data.id? data.id : 0;
            data.name = data.name? data.name : '';
            
            if (!data.type_name){
                data.type_name = data.typeName? data.typeName : ''; //data.typeName - for support data type from flash map
            }
            
        }
        if (!data || !data.id || !data.name || !trim(data.name) ||  isEntityAdded(data.id) || isFullPool() )
            return false;

        $itemList.append('<li>'+data.type_name+' '+data.name+'<input type=hidden value="'+data.id+'">'+
            ' <img class="'+class_names.items_list_delete+'" src="'+appl_url+'images/icons/iconCancel.png"/></li>');
        $("li",$itemList).css(css_styles.pool_item);

        $("."+class_names.items_list_delete,$itemList).click(function(){

            $(this).parent().remove();
        });

//        $input.focus();

        checkPoolHeight();

        return true;
    }

    function setSelectedItems(){
        for(var i in settings.selected_items){
            if (settings.selected_items[i] && isFinite(i))
                addPoolItem(settings.selected_items[i]);
        }
    }
    /*
     *@todo not show list result when no data returned
     **/
    function showSearchResultList(json){
        if ($srchList)
            $srchList.remove();
        var ent_list = '';
        var ents = json.data;
        
        if ( ents.length > 0){

            $pool.after('<ul class="'+class_names.srch_list+'" >'+ent_list+'</ul>');
            $srchList = $("."+class_names.srch_list, $overlay);
            $srchList.css(css_styles.srch_list);

            for (var i in ents) {

                if ( ents[i] && isFinite( parseInt(i) )){
                    ent_list = '';
                    ent_list += '<li class="'+class_names.srch_list_item+'" ><table style="'+css.srchListItemTbl+'" >'+
                        '<tr><td colspan="3">'+
                        '<a href="javascript:void(0)" name="'+identifier.srch_list_item+ents[i].id+'" class="'+class_names.add_entity+' '+class_names.sl_entity_name+'"  >'+ents[i].type+' '+ents[i].name+'</a>'+
                        '<input id="'+identifier.srch_list_item+ents[i].id+'" type="hidden"  value="'+ents[i].name+'"/>'+
                        '<input id="'+identifier.srch_list_item+ents[i].id+'_type" type="hidden"  value="'+ents[i].type+'"/>'+
                        '</td></tr>';
                    ent_list += '<tr><td><a href="javascript:void(0)" name="'+identifier.srch_list_item+ents[i].id+'" class="'+
                        class_names.add_entity+' '+class_names.sl_entity_select+'">'+settings.texts.select+'</a></td>'+
                        '<td><a href="javascript:void(0)" class="'+class_names.view_entity+' '+class_names.sl_entity_view+'">'+
                        settings.texts.viewEntity+' </a></td>'+
                        '<td style="background: url('+appl_url+'images/triangle.png)  no-repeat scroll 100% 50%;"><a href="javascript:void(0)" class="'+
                        class_names.srch_list_info_link+' '+class_names.sl_entity_info+'" >'+settings.texts.storedInformation+'</a></td></tr>'+
                        '</table></li>';
                    $srchList.append(ent_list);

                    //add styles and created item to list
                    $srchListItem = $('li:last',$srchList);
//                    $('td:not(:first)',$srchListItem).css("text-align", "center");
                    $srchListInfoLink = $("."+class_names.srch_list_info_link,$srchListItem);

                    showSearchResultItemInfo( ents[i]);

                }
            }

            $('a',$srchList).css({"text-decoration":"none",width:"100%",display:"block"});
            $('li',$srchList).css({"padding-left":"5px"});
//            $('.'+class_names.sl_entity_select+',.'+class_names.sl_entity_view+',.'+class_names.sl_entity_info,$srchList).css({"font-size":"10px"});
            $('.'+class_names.sl_entity_name,$srchList).css(css_styles.sl_entity_name);
            $('.'+class_names.sl_entity_select,$srchList).css(css_styles.sl_entity_select);
            $('.'+class_names.sl_entity_view,$srchList).css(css_styles.sl_entity_view);
            $('.'+class_names.sl_entity_info,$srchList).css(css_styles.sl_entity_info);

            
            addBindsSearchResultList();
        }

    }

    function showSearchResultItemInfo(_data){

//        var devider = '<div class="'+class_names.devider+'" style="'+css.devider+'"></div>';
        var Pstyle  = ' style="'+css.infoP+'"';

        var itemInfo = ( _data.desc )? '<p class="'+class_names.srch_list_info_desc+'">'+_data.desc+'</p>' : '';
        if (_data.contents)
            for (var i in _data.contents) {
                if ( typeof (_data.contents[i]) == 'string' ) itemInfo += '<p>'+_data.contents[i]+'</p>';
            }
        
        if ( !itemInfo ) return false;
        
        $srchListItem.prepend('<div class="'+class_names.srch_list_info+'" >'+itemInfo+'</div>');
        $srchListInfo = $("."+class_names.srch_list_info);

        $( "p", $srchListInfo).css(css_styles.sl_info_p);
        $( "."+class_names.srch_list_info_desc, $srchListInfo).css(css_styles.sl_info_desc);
        $srchListInfo.css(css_styles.srch_list_item_info);
        $srchListInfo.css({right:'-'+$srchListInfo.innerWidth()+'px'});

        addBindsSearchResultItemInfo();
    }

    function selectPoolItems(){

        var params = {};

        params.entity_ids = getPoolItemsIds();

        settings.onSelectEntities(params);

    }

/*
 * Helper functions
 *
 * @todo navigation must go from first to last and from last to first immediatly
 */
    function searchListNavigate(course){

        course = course.toLowerCase();
        var $cur_item = $("."+class_names.srch_list_sel,$srchList);
        var $next_item;

        switch (course) {
            case 'up':
                $next_item = (!$cur_item.size()) ? $("li:last",$srchList) : $cur_item.prev();
                break;
            case 'down':
                $next_item = (!$cur_item.size()) ? $("li:first",$srchList) : $cur_item.next();
                break;
            default:
                return false;
                break;
        }

        searchListItemSelect($cur_item,1);
        searchListItemSelect($next_item,0);

        return true;

    }

    /*
     *@todo Cnange selecting item to take from hidden input by found in parent for clicked elements or in selected item
     **/
    function getItemDataForAddPool(){
        var $this = $("."+class_names.srch_list_sel+' .'+class_names.add_entity,$srchList);

        if (!$this.size())
            $this = $('.'+class_names.add_entity+':first',$srchList);

        if (!$this.size())
            return false;

        var _type_name  = $("#"+$this.attr('name')+"_type",$srchList).val();
        var _name       = $("#"+$this.attr('name'),$srchList).val();
        var _id         = $this.attr('name').replace(identifier.srch_list_item,'');

        return {id:_id,name:_name,type_name:_type_name};
    }

    function getPoolItemsIds(){
        var ids = [];
        $("input[type=hidden]",$itemList ).each(function (){
            ids.push($(this).val());
        });

        return ids;
    }

    function searchListItemSelect(elem,deselect){
        deselect = deselect || 0;
        if (!deselect)
           elem.css(css_styles.srch_list_sel).addClass(class_names.srch_list_sel);
       else
           elem.css(css_styles.srch_list_nsel).removeClass(class_names.srch_list_sel);
    }

    function  checkPoolHeight(){
        var _hp = $pool.innerHeight();
        var _hpc = $poolCont.innerHeight();
        
        if (_hp > _hpc){
            $poolCont.height(_hp + 5);
            settings.onHeightChange();
        }
    }

    function clearInput(){
        if (!isTyping)
            $input.val('');
    }

    function clearPool(){
       $itemList.empty();
    }

    function hideSearchList(){
        $srchList.hide();
    }

    function inputClick(){
        clearInput();
        $input.css({color:"#000"});
        $input.focus();
    }

    function inputBlur(){

        if (!isTyping){
            $input.val(settings.texts.msg_welcome).css(css_styles.input);
        }
    }

    function InfoLinkGetInfo($infoLink){

        return  $infoLink.parents('.'+class_names.srch_list_item).children('.'+class_names.srch_list_info);

    }

    function isEntityAdded(eid){
        var eids = [];
        $("input[type=hidden]",$itemList).each( function(){
            eids.push($(this).val());
        });

        if ( typeof(eid) == 'number' )
            eid = eid.toString();

        if ( eids.indexOf(eid) >= 0 )
            return true;
        else
            return false;
    }

    function isFullPool(){
        
        var poolItemsSize = $("input[type=hidden]",$itemList).size();

        if ( settings.limit_items && poolItemsSize >= settings.items_count)
            return true;
        else
            return false;
    }

    function keypressValueProcessing(data){
        if (!data)          data = {};
        if (!data.str)      data.str = '';
        if (!data.key)      data.key = '';
        if (!data.carPos)   data.carPos = 0;
        if (!data.isChar)   data.isChar = (( data.key >= 65 && data.key <= 90) || ( data.key >= 97 && data.key <= 122) )? 1: 0;

        var result = '';

        var prefix  = data.str.substring(0,data.carPos);
        var sufix   = data.str.substring(data.carPos);

        if (data.isChar){
            
            result = prefix + String.fromCharCode(data.key) + sufix;

        }else {
            switch (data.key) {
                case 8://BACSPACE key
                    prefix = prefix.slice(0,-1);break;
                case 46: //DELETE key
                    sufix = sufix.slice(1);break;
            }

            result = prefix + sufix;

        }

        return result;

    }

})(jQuery);
