/**
 * Extending jQuery with autocomplete
 * Version: 1.4.2
 * Author: Yanik Gleyzer (clonyara)
 * Modified:
 *
 */
var jQuery_MyJqac_Config;
(function($) {

    // some key codes
    var RETURN = 13;
    var TAB = 9;
    var ESC = 27;
    var ARRLEFT = 37;
    var ARRUP = 38;
    var ARRRIGHT = 39;
    var ARRDOWN = 40;
    var BACKSPACE = 8;
    var DELETE = 46;

    function debug(s) {
        $('#info').append(htmlspecialchars(s) + '<br>');
    }
// getting caret position obj: {start,end}
    function getCaretPosition(obj) {
        var start = -1;
        var end = -1;
        if (typeof obj.selectionStart != "undefined") {
            start = obj.selectionStart;
            end = obj.selectionEnd;
        }
        else if (document.selection && document.selection.createRange) {
            var M = document.selection.createRange();
            var Lp;
            try {
                Lp = M.duplicate();
                Lp.moveToElementText(obj);
            } catch(e) {
                Lp = obj.createTextRange();
            }
            Lp.setEndPoint("EndToStart", M);
            start = Lp.text.length;
            if (start > obj.value.length)
                start = -1;

            Lp.setEndPoint("EndToStart", M);
            end = Lp.text.length;
            if (end > obj.value.length)
                end = -1;
        }
        return {'start':start,'end':end};
    }


    
// set caret to
    function setCaret(obj, l) {
        obj.focus();
        if (obj.setSelectionRange) {
            obj.setSelectionRange(l, l);
        }
        else if (obj.createTextRange) {
            m = obj.createTextRange();
            m.moveStart('character', l);
            m.collapse();
            m.select();
        }
    }
    
    // prepare array with valued objects
    // required properties are id and value
    // rest of properties remaines
    function prepareArray(jsondata) {
        var new_arr = [];
        for (var i = 0; i < jsondata.length; i++) {
//            if (jsondata[i].id != undefined && jsondata[i].value != undefined) {
//                jsondata[i].id = jsondata[i].id + "";
//                jsondata[i].value = jsondata[i].value + "";
//                if (jsondata[i].info != undefined)
//                    jsondata[i].info = jsondata[i].info + "";
//                new_arr.push(jsondata[i]);
//            }
             new_arr.push(jsondata[i]);
        }
        return new_arr;
    }

    
    // php analogs
    function escapearg(s) {
        if (s == undefined || !s) return '';
        return s.replace('\\', '\\\\').
                replace('*', '\\*').
                replace('.', '\\.').
                replace('/', '\\/');
    }
    function htmlspecialchars(s) {
        if (s == undefined || !s) return '';
        return s.replace('&', '&amp;').
                replace('<', '&lt;').
                replace('>', '&gt;');
    }
    function ltrim(s) {
        if (s == undefined || !s) return '';
        return s.replace(/^\s+/g, '');
    }

// extending jQuery
    $.fn.autocomplete = function(config) {
    		var options ={
                delay     : 0 ,
                timeout   : 60000 ,
                minchars  : 0 ,
                //multi     : false ,
                //cache     : false ,
                height    : 200 ,
                //autowidth : false ,
                noresults : '对不起，找不到结果',
                width	    : false,
                left  : 2,
                right : 1,                
                returnwho   : 1,
                hint      : "输入中文/拼音，或用上下键选择",
               
                next:""				
				}
					
				options = $.extend(options,config);
           			
        return this.each(function() {
            // take me

            var me = $(this);//this is the jquery obj

            var me_this = $(this).get(0);//this is the dom obj

            me_this.options = options;
            // test for supported text elements
            if (!me.is('input:text,input:password,textarea'))
                return;

            // get or ajax_get required!
            if (!me_this.options && (!$.isFunction(me_this.options.get) || !me_this.options.ajax_get)) {
                return;
            }

            // check plugin enabled
            if (me.attr('jqac') == 'on') return;

            // plugin on!
            me.attr('jqac', 'on');

            // no browser's autocomplete!
            me.attr('autocomplete', 'off');
        
            //init input filled prompt
           
				
            // bind key events
            // handle special keys here
            me.keydown(function(ev) {
                switch (ev.which) {
                    // return choose highlighted item or default propogate
                    case RETURN:
                        if (!suggestions_menu) return true;
                        else setHighlightedValue();
                        return false;
                    // escape clears menu
                    case ESC:
                        clearSuggestions();
                        return false;
                    // up changes highlight
                    case ARRUP:
                        changeHighlight(ev.keyCode);
                        return false;
                    // down changes highlight or open new menu
                    case ARRDOWN:
                        if (!suggestions_menu) getSuggestions(getUserInput());
                        else changeHighlight(ev.keyCode);
                        return false;
                    case TAB:
                    		 
                         clearSuggestions();
                         return true;
                }
                return true;
            });

            // handle normal characters here
            //edit by huofei 2008-12-1 desc: keyup事件用bind来绑定
            me.bind("keyup", function(ev) {
                switch (ev.which) {
                    case RETURN: case ESC: case ARRLEFT: case ARRRIGHT: case ARRUP: case ARRDOWN:case TAB:
                    return true;

                    default:
                        getSuggestions(getUserInput());
                }
                return true;
            });

            // init variables
            var user_input = "";
            var input_chars_size = 0;
            var suggestions = [];
            var current_highlight = 0;
            var suggestions_menu = false;
            var suggestions_list = false;
            var loading_indicator = false;
            var clearSuggestionsTimer = false;
            var getSuggestionsTimer = false;
            var showLoadingTimer = false;
            var zIndex = me.css('110');
            
            
           

            // get user input
            function getUserInput() {
                var val = me.val();
                //add by huofei 2008-12-1
                if (val == me.attr("prompt")) val = "";
//                if (options.multi) {
//                    var pos = getCaretPosition(me_this);
//                    var start = pos.start;
//                    for (; start > 0 && val.charAt(start - 1) != ','; start--) {
//                    }
//                    var end = pos.start;
//                    for (; end < val.length && val.charAt(end) != ','; end++) {
//                    }
//                    var val = val.substr(start, end - start);
//                }
                return ltrim(val);
            }
            
            // set suggestion
            function setSuggestion(val) {
                user_input = val;
//                if (options.multi) {
//                    var orig = me.val();
//                    var pos = getCaretPosition(me_this);
//                    var start = pos.start;
//                    for (; start > 0 && orig.charAt(start - 1) != ','; start--) {
//                    }
//                    var end = pos.start;
//                    for (; end < orig.length && orig.charAt(end) != ','; end++) {
//                    }
//                    var new_val = orig.substr(0, start) + (start > 0 ? ' ' : '') + val + orig.substr(end);
//                    me.val(new_val);
//                    setCaret(me_this, start + val.length + (start > 0 ? 1 : 0));
//                }
//                else {
                    me_this.focus();
                    me.val(val);
               // }
            }
            
            // get suggestions
            function getSuggestions(val) {
                // input length is less than the min required to trigger a request
                // reset input string
                // do nothing
                if (val.length < me_this.options.minchars) {
                    clearSuggestions();
                    return false;
                }
                
                // if caching enabled, and user is typing (ie. length of input is increasing)
                // filter results out of suggestions from last request
//                if (options.cache && val.length > input_chars_size && suggestions.length) {
//                    var arr = [];
//                    for (var i = 0; i < suggestions.length; i++) {
//                        var re = new RegExp("(" + escapearg(val) + ")", 'ig');
//                        if (re.exec(suggestions[i].value))
//                            arr.push(suggestions[i]);
//                    }
//                    user_input = val;
//                    input_chars_size = val.length;
//                    suggestions = arr;
//                    createList(suggestions);
//                    return false;
//                }
//                else {// do new request

                    clearTimeout(getSuggestionsTimer);
                    user_input = val;
                    input_chars_size = val.length;
                    getSuggestionsTimer = setTimeout(
                            function() {
                                suggestions = [];
                                // call pre callback, if exists
                                if ($.isFunction(me_this.options.pre_callback))
                                    me_this.options.pre_callback();
                                
                                // call get
                                if ($.isFunction(me_this.options.get)) {
                                    suggestions = prepareArray(me_this.options.get(val));
                                    createList(suggestions);
                                }// call AJAX get
                                else if ($.isFunction(me_this.options.ajax_get)) {
                                    clearSuggestions();
                                    showLoadingTimer = setTimeout(show_loading, me_this.options.delay);
                                    me_this.options.ajax_get(val, ajax_continuation);
                                }
                            },
                            me_this.options.delay);
                //}
                return false;
            }
            ;

            // AJAX continuation
            function ajax_continuation(jsondata) {
                hide_loading();
                suggestions = prepareArray(jsondata);
                createList(suggestions);
            }

            // shows loading indicator
            function show_loading() {
                if (!loading_indicator) {
                    loading_indicator = $('<div class="jqac-menu"><div class="jqac-loading">Loading</div></div>').get(0);
                    $(loading_indicator).css('position', 'absolute');
                    var pos = me.offset();
                    $(loading_indicator).css('left', pos.left + "px");
                    $(loading_indicator).css('top', ( pos.top + me.height() + 2 ) + "px");
                    //if (!options.autowidth)
                        $(loading_indicator).width(me.width());
                    $('body').append(loading_indicator);
                }

                $(loading_indicator).show();
                setTimeout(hide_loading, 10000);
            }


            // hides loading indicator
            function hide_loading() {
                if (loading_indicator)
                    $(loading_indicator).hide();
                clearTimeout(showLoadingTimer);
            }

            
            // create suggestions list
            function createList(arr) {
                if (suggestions_menu)
                    $(suggestions_menu).remove();
                hide_loading();
                killTimeout();

            // create holding div
            suggestions_menu = $('<div class="jqac-menu"></div>').get(0);

            // ovveride some necessary CSS properties
                $(suggestions_menu).css({'position':'absolute',
                    'z-index':zIndex,
                    'max-height':me_this.options.height + 'px',
                    'overflow-y':'auto',
                    'overflow-x':'hidden'});

            // create and populate ul
                suggestions_list = $('<ul></ul>').get(0);


               //create the hint for how to search the info
               //edit by huofei 2008-12-12
                suggestions_hint = me_this.options.hint == "" ? null : $('<ul><li><span class="jqac-hint">' + me_this.options.hint + '</span></li></ul>').get(0);

                // set some CSS's
                $(suggestions_list).
                        css('list-style', 'none').
                        css('margin', '0px').
                        css('padding', '2px').
                        css('overflow', 'hidden');
	
				//edit by huofei 2008-12-12
                if (suggestions_hint != null)
                	$(suggestions_hint).
                        css('list-style', 'none').
                        css('margin', '0px').
                        css('padding', '2px').
                        css('overflow', 'hidden');

                // regexp for replace
                //var re = new RegExp("(" + escapearg(htmlspecialchars(user_input)) + ")", 'ig');
                // loop throught arr of suggestions creating an LI element for each suggestion
                for (var i = 0; i < arr.length; i++) {
                    //var val = new String(arr[i][options.right]);
                    var val;
                    if(me_this.options.right!=-1){
                    	val=arr[i][me_this.options.right];
                    }else{
                    	val="";
                    }
                    	
                    // using RE
                    //var output = htmlspecialchars(val).replace(re, '<em>$1</em>');
                    var output = val;
                    // using substr
                    
                    var span = $('<span class="jqac-link"></span>').get(0);

                    var span_value = $('<span class="jqac-value">' + output + '</span>');
                    $(span).append(span_value);
                    var span_info;
                    
                    //if (arr[i][options.right] != undefined && arr[i][options.right] != "") {
                        span_info = $('<span class="jqac-info">' + arr[i][me_this.options.left] + '</span>');
                        $(span).append(span_info);

                    //}

                    $(span).attr('name', i + 1);
                    $(span).bind("mousedown",function () {
                        setHighlightedValue();
                        return false;
                    });
                    $(span).mouseover(function () {
                        setHighlight($(this).attr('name'), true);
                    });

                    var li = $('<li></li>').get(0);
                    $(li).append(span);

                    $(suggestions_list).append(li);
                }

                // no results
                if (arr.length == 0) {
                    $(suggestions_list).append('<li class="jqac-warning">' + me_this.options.noresults + '</li>');
                }

                //add the tip suggestions_hint(about how to search the info)
                //edit by huofei 2008-12-12
                if (suggestions_hint != null)
	                $(suggestions_menu).append(suggestions_hint);
                $(suggestions_menu).append(suggestions_list);

                // get position of target textfield
                // position holding div below it
                // set width of holding div to width of field
                var pos = me.offset();

                $(suggestions_menu).css('left', pos.left + "px");
                $(suggestions_menu).css('top', ( pos.top + me.height() + 6 ) + "px");
               // if (!options.autowidth) {
                    var menu_width = me.width();
                    if (me_this.options.width!=false) {
                        menu_width =me_this.options.width
                    }else{
                    	  
                    }
                    $(suggestions_menu).width(menu_width);
                //}


                // set mouseover functions for div
                // when mouse pointer leaves div, set a timeout to remove the list after an interval
                // when mouse enters div, kill the timeout so the list won't be removed
                $(suggestions_menu).mouseover(function() {
                    killTimeout()
                });
                $(suggestions_menu).mouseout(function() {
                    killTimeout()
                   // resetTimeout()
                });

                // add DIV to document
                $('body').append(suggestions_menu);

                // bgIFRAME support
                if ($.fn.bgiframe)
                    $(suggestions_menu).bgiframe({height: suggestions_menu.scrollHeight
                        //height: suggestions_menu.scrollHeight
                                                 // top: '-1em',
                                                  //left: '-1em'
                                                  //width: suggestions_menu.width
                    });
                //$(suggestions_menu).bgiframe({ height: 180 });

                // adjust height: add +20 for scrollbar
                if (suggestions_menu.scrollHeight > me_this.options.height) {
                    $(suggestions_menu).height(me_this.options.height);
                    $(suggestions_menu).width($(suggestions_menu).width() + 20);
                }

                // currently no item is highlighted
                // default select the first
                current_highlight = 1;
                setHighlight(current_highlight);
                 //current_highlight = 0;
                // remove list after an interval
                clearSuggestionsTimer = setTimeout(function () {
                    clearSuggestions()
                }, me_this.options.timeout);
            }
            ;
            
            // set highlighted value
            function setHighlightedValue() {
                if (current_highlight && suggestions[current_highlight - 1]) {
                    var sugg = suggestions[ current_highlight - 1 ];
//                    if (sugg.affected_value != undefined && sugg.affected_value != '')
//                        setSuggestion(sugg.affected_value);
//                    else
                    
                    setSuggestion(sugg[me_this.options.returnwho])
                    
                    // pass selected object to callback function, if exists
                    if ($.isFunction(me_this.options.callback))
                        me_this.options.callback(suggestions[current_highlight - 1],me);

                    //clearSuggestions();
                   
                    if(me_this.options.next!=""){
                    	 clearSuggestions();
                    	 try{
                    	 	document.getElementById(me_this.options.next).focus();
                    	 }catch(e){
                    	 	
                    	 }
                    	 
                   
                    }else{
                    	
                       clearSuggestions();
                       me_this.blur();
                    }
                   
                }
            };

            // change highlight according to key
            function changeHighlight(key) {
                if (!suggestions_list || suggestions.length == 0) return false;
                var n;
                if (key == ARRDOWN)
                    n = current_highlight + 1;
                else if (key == ARRUP)
                    n = current_highlight - 1;

                if (n > $(suggestions_list).children().size())
                    n = 1;
                if (n < 1)
                    n = $(suggestions_list).children().size();
                setHighlight(n);
            };
            // change highlight
            function setHighlight(n, mouse_mode) {
                if (!suggestions_list) return false;
                if (current_highlight > 0) clearHighlight();
                current_highlight = Number(n);
                var li = $(suggestions_list).children().get(current_highlight - 1);
                li.className = 'jqac-highlight';
            // for mouse mode don't adjust scroll! prevent scrolling jumps
                if (!mouse_mode) adjustScroll(li);
                killTimeout();
            }
            ;
            // clear highlight
            function clearHighlight() {
                if (!suggestions_list)return false;
                if (current_highlight > 0) {
                    $(suggestions_list).children().get(current_highlight - 1).className = '';
                    current_highlight = 0;
                }
            };

            // clear suggestions list
            function clearSuggestions() {
                killTimeout();
                if (suggestions_menu) {
                    $(suggestions_menu).remove();
                    suggestions_menu = false;
                    suggestions_list = false;
                    current_highlight = 0;
                }
            };

            // set scroll
            function adjustScroll(el) {
                if (!suggestions_menu) return false;
                var viewportHeight = suggestions_menu.clientHeight;
                var wholeHeight = suggestions_menu.scrollHeight;
                var scrolled = suggestions_menu.scrollTop;
                var elTop = el.offsetTop;
                var elBottom = elTop + el.offsetHeight;
                if (elBottom > scrolled + viewportHeight) {
                    suggestions_menu.scrollTop = elBottom - viewportHeight;
                }
                else if (elTop < scrolled) {
                    suggestions_menu.scrollTop = elTop;
                }
                return true;
            }
            // timeout funcs
            function killTimeout() {
                clearTimeout(clearSuggestionsTimer);
            };

            function resetTimeout() {
                clearTimeout(clearSuggestionsTimer);
                clearSuggestionsTimer = setTimeout(function () {
                    clearSuggestions()
                }, 1000);
            }
            ;

            //handle the mouse click event
            //when click the input ,show the suggestions


					
            $(document).bind("mousedown",function(event){
               
                var myEvent = event||window.event;

                if(myEvent.target == me_this || myEvent.target == suggestions_menu ){
             
                }else{
                	  
                    clearSuggestions();
                    return true;
                }

            })
           
                      
           /*
            me.blur(function(){
            	 
            		setTimeout(function () {
            			  
                    clearSuggestions();
                }, 200)
            })
           */
            me.focus(function(){            	  
            	           	         		          				
               getSuggestions(getUserInput());
     
            })	
            
            					
        })
    };

})($);

