/*******************************************************

AutoSuggest - a javascript automatic text input completion component
Copyright (C) 2005 Joe Kepley, The Sling & Rock Design Group, Inc.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*******************************************************

Please send any useful modifications or improvements via 
email to joekepley at yahoo (dot) com

*******************************************************/

/********************************************************
 The AutoSuggest class binds to a text input field
 and creates an automatic suggestion dropdown in the style
 of the "IntelliSense" and "AutoComplete" features of some
 desktop apps. 
 Parameters: 
 elem: A DOM element for an INPUT TYPE="text" form field
 suggestions: an array of strings to be used as suggestions
              when someone's typing.

 Example usage: 
 
 Please enter the name of a fruit.
 <input type="text" id="fruit" name="fruit" />
 <script language="Javascript">
 var fruits=new Array("apple","orange","grape","kiwi","cumquat","banana");
 new AutoSuggest(document.getElementById("fruit",fruits));
 </script>

 Requirements: 

 Unfortunately the AutoSuggest class doesn't seem to work 
 well with dynamically-created DIVs. So, somewhere in your 
 HTML, you'll need to add this: 
 <div id="autosuggest"><ul></ul></div>

 Here's a default set of style rules that you'll also want to 
 add to your CSS: 

 .suggestion_list
 {
 background: white;
 border: 1px solid;
 padding: 4px;
 }

 .suggestion_list ul
 {
 padding: 0;
 margin: 0;
 list-style-type: none;
 }

 .suggestion_list a
 {
 text-decoration: none;
 color: navy;
 }

 .suggestion_list .selected
 {
 background: navy;
 color: white;
 }

 .suggestion_list .selected a
 {
 color: white;
 }

 #autosuggest
 {
 display: none;
 }
*********************************************************/
function AutoSuggest(elem)
{

    delete Array.prototype.containsValue;
        
    //The 'me' variable allow you to access the AutoSuggest object
    //from the elem's event handlers defined below.
    var me = this;

    //A reference to the element we're binding the list to.
    this.elem = elem;

    //Arrow to store a subset of eligible suggestions that match the user's input
    this.eligible = new Array();

    this.totalFindedResult = new Array();

    //The text input by the user.
    this.inputText = null;

    //A pointer to the index of the highlighted eligible item. -1 means nothing highlighted.
    this.highlighted = -1;

    //A div to use to create the dropdown.
    this.div = document.getElementById("autosuggest");


    //Do you want to remember what keycode means what? Me neither.
    var TAB = 9;
    var ESC = 27;
    var KEYUP = 38;
    var KEYDN = 40;
	

    //The browsers' own autocomplete feature can be problematic, since it will
    //be making suggestions from the users' past input.
    //Setting this attribute should turn it off.
    elem.setAttribute("autocomplete","off");

    //We need to be able to reference the elem by id. If it doesn't have an id, set one.
    if(!elem.id)
    {
        var id = "autosuggest" + idCounter;
        idCounter++;

        elem.id = id;
    }


    /********************************************************
	onkeydown event handler for the input elem.
	Tab key = use the highlighted suggestion, if there is one.
	Esc key = get rid of the autosuggest dropdown
	Up/down arrows = Move the highlight up and down in the suggestions.
	********************************************************/
    elem.onkeydown = function(ev)
    {
        var key = me.getKeyCode(ev);

        switch(key)
        {
            case TAB:
                me.useSuggestion();
                break;

            case ESC:
                me.hideDiv();
                break;

            case KEYUP:
                if (me.highlighted > 0)
                {
                    me.highlighted--;
                    elem.value=me.eligible[me.highlighted];
                }
                me.changeHighlight(key);
                break;

            case KEYDN:
                if (me.highlighted < (me.eligible.length - 1))
                {
                    me.highlighted++;
                    elem.value=me.eligible[me.highlighted];
                }
                me.changeHighlight(key);
                break;
        }
    };

    /********************************************************
	onkeyup handler for the elem
	If the text is of sufficient length, and has been changed, 
	then display a list of eligible suggestions.
	********************************************************/
    elem.onkeyup = function(ev)
    {
        var key = me.getKeyCode(ev);
        switch(key)
        {
            //The control keys were already handled by onkeydown, so do nothing.
            case TAB:
            case ESC:
            case KEYUP:
            case KEYDN:
                return;
            default:

                if (this.value != me.inputText && this.value.length > 0)
                {
                    me.inputText = this.value;
                    me.getEligible();
                }
                else
                {
                    me.hideDiv();
                }
        }
    };

    this.updateDiv = function()
    {
        if (this.eligible.length > 0) {
            me.inputText = this.value;
            me.createDiv();
            me.showDiv();
        }
    };

    /********************************************************
	Insert the highlighted suggestion into the input box, and 
	remove the suggestion dropdown.
	********************************************************/
    this.useSuggestion = function()
    {
        
        if (this.highlighted > -1)
        {
            //this.elem.value
            window.location = '/search.php?q='+this.eligible[this.highlighted];
            this.hideDiv();
        //It's impossible to cancel the Tab key's default behavior.
        //So this undoes it by moving the focus back to our field right after
        //the event completes.
        //setTimeout("document.getElementById('" + this.elem.id + "').focus()",0);
        }
    };

    /********************************************************
	Display the dropdown. Pretty straightforward.
	********************************************************/
    this.showDiv = function()
    {
       if (this.eligible.length > 0)
            this.div.style.display = 'block';
    };

    /********************************************************
	Hide the dropdown and clear any highlight.
	********************************************************/
    this.hideDiv = function()
    {
        this.div.style.display = 'none';
        this.highlighted = -1;
    };

    /********************************************************
	Modify the HTML in the dropdown to move the highlight.
	********************************************************/
    this.changeHighlight = function()
    {
        var lis = this.div.getElementsByTagName('LI');
        for (i in lis)
        {
            var li = lis[i];

            if (this.highlighted == i)
            {
                li.className = "selected";
            }
            else
            {
                if (li)
                    li.className = "";
            }
        }
    };

    /********************************************************
	Build the HTML for the dropdown div
	********************************************************/
    this.createDiv = function()
    {
        var ul = document.createElement('ul');

        //Create an array of LI's for the words.
        for (i in this.eligible)
        {
            var word = this.eligible[i];
            var total = this.totalFindedResult[i];
	
            var li = document.createElement('li');
            var a = document.createElement('a');
            a.href='search.php?q='+word;
            if (total>0 && total<5000)
                a.innerHTML = '<span style="float:right">'+ total + '&nbsp;результатов</span>' + word;
            else if (total>=5000)
                a.innerHTML = '<span style="float:right">больше&nbsp;5000</span>' + word;
            else
                a.innerHTML = '<span style="float:right">'+ total + '</span>' + word;

            li.appendChild(a);
	
            if (me.highlighted == i)
            {
                li.className = "selected";
            }
	
            ul.appendChild(li);
        }
	
        this.div.replaceChild(ul,this.div.childNodes[0]);
	

        /********************************************************
		mouseover handler for the dropdown ul
		move the highlighted suggestion with the mouse
		********************************************************/
        ul.onmouseover = function(ev)
        {
            //Walk up from target until you find the LI.
            var target = me.getEventSource(ev);
            while (target.parentNode && target.tagName.toUpperCase() != 'LI')
            {
                target = target.parentNode;
            }
		
            var lis = me.div.getElementsByTagName('LI');
			
	
            for (i in lis)
            {
                var li = lis[i];
                if(li == target)
                {
                    me.highlighted = i;
                    break;
                }
            }
            me.changeHighlight();
        };

        /********************************************************
		click handler for the dropdown ul
		insert the clicked suggestion into the input
		********************************************************/
        ul.onclick = function(ev)
        {
            me.useSuggestion();
            me.hideDiv();
            me.cancelEvent(ev);
            return false;
        };
	
        this.div.className="suggestion_list";
        this.div.style.position = 'absolute';

    };

    /********************************************************
	determine which of the suggestions matches the input
	********************************************************/
    this.getEligible = function()
    {
        xajax_requestAutoSuggest(this.inputText);
        this.highlighted = -1;
    };

    /********************************************************
	Helper function to determine the keycode pressed in a 
	browser-independent manner.
	********************************************************/
    this.getKeyCode = function(ev)
    {
        if(ev)			//Moz
        {
            return ev.keyCode;
        }
        if(window.event)	//IE
        {
            return window.event.keyCode;
        }
    };

    /********************************************************
	Helper function to determine the event source element in a 
	browser-independent manner.
	********************************************************/
    this.getEventSource = function(ev)
    {
        if(ev)			//Moz
        {
            return ev.target;
        }
	
        if(window.event)	//IE
        {
            return window.event.srcElement;
        }
    };

    /********************************************************
	Helper function to cancel an event in a 
	browser-independent manner.
	(Returning false helps too).
	********************************************************/
    this.cancelEvent = function(ev)
    {
        if(ev)			//Moz
        {
            ev.preventDefault();
            ev.stopPropagation();
        }
        if(window.event)	//IE
        {
            window.event.returnValue = false;
        }
    }
}

//counter to help create unique ID's
var idCounter = 0;