/**
*    Json key/value autocomplete for jQuery 
*    Provides a transparent way to have key/value autocomplete
*    Copyright (C) 2008 Ziadin Givan www.CodeAssembly.com  
*
*    This program 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 3 of the License, or
*    (at your option) any later version.
*
*    This program 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 General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public License
*    along with this program.  If not, see http://www.gnu.org/licenses/
*    
*    Examples 
*	 $("input#example").autocomplete("autocomplete.php");//using default parameters
*	 $("input#example").autocomplete("autocomplete.php",{minChars:3,timeout:3000,validSelection:false,parameters:{'myparam':'myvalue'},before : function(input,text) {},after : function(input,text) {}});
*    minChars = Minimum characters the input must have for the ajax request to be made
*	 timeOut = Number of miliseconds passed after user entered text to make the ajax request   
*    validSelection = If set to true then will invalidate (set to empty) the value field if the text is not selected (or modified) from the list of items.
*    parameters = Custom parameters to be passed
*    after, before = a function that will be caled before/after the ajax request
*/
jQuery.fn.autocomplete = function(url, settings) {
    return this.each(function()//do it for each matched element
    {
        //this is the original input
        var textInput = $(this);
        //create a new hidden input that will be used for holding the return value when posting the form, then swap names with the original input
        textInput.after('<input type=hidden id="' + textInput.attr("name") + "_id" + '" name="' + textInput.attr("name") + "_name" + '"/>').attr("name", textInput.attr("name") + "_text");
        var valueInput = $(this).next();
        //create the ul that will hold the text and values
        valueInput.after('<ul id="suggestUl" class="autocomplete"></ul>');
        var list = valueInput.next();
        var oldText = '';
        var typingTimeout;
        var size = 0;
        var selected = -1;

        settings = jQuery.extend(//provide default settings
		{
		minChars: 3,
		timeout: 0,
		after: null,
		before: null,
		validSelection: true,
		parameters: {}
}, settings);

        function getData(text) {
            window.clearInterval(typingTimeout);
            if (text != oldText && (settings.minChars != null && text.length >= settings.minChars)) {
                clear();
                if (settings.before == "function") {
                    settings.before(textInput, text);
                }
                textInput.addClass('autocomplete-loading');
                settings.parameters.text = text;
                $.getJSON(url, settings.parameters, function(data) {
                    var items = '';
                    if (data) {
                        size = data.length;
                        setUlHeight(size);
                        var sb = new StringBuilderEx();
                        for (i = 0; i < data.length; i++)//iterate over all options
                        {
                            var v = 3;
                            if (data[i].R == null || data[i].R == undefined)
                                v = data[i].ID;
                            else
                                v = data[i].R;

                            sb.append('<li>' + data[i].N.replace(new RegExp("(" + text + ")", "i"), "<strong style=\"color:#89D1FE\">$1</strong>"));
                            if (textInput.attr('id') == "adress") {
                                sb.append('<input class="cor" id="hC_' + i + '" type="hidden" value="'
                                    + data[i].LAT + ";" + data[i].LNG + '" />'
                                    + '<input class="rad" id="hR_' + i + '" type="hidden" value="'
                                    + v + '" />'
                                    + '</li>');
                            }
                            else
                                sb.append('</li>');

                            list.html(sb.toString());

                            list.show().children().
						    hover(function() {
						        $(this).addClass("selected").siblings().removeClass("selected");
						        setCoordinat($(this).children('input.cor').attr('value'));
						    }, function() { $(this).removeClass("selected") }).
						    click(function() {
						        textInput.val($(this).text());

						        if (textInput.attr('id') == "adress") {
						            valueInput.val($(this).children('input.rad').attr('value'));
						        }

						        setCoordinat($(this).children('input.cor').attr('value'));
						        clear();
						    });
                        }

                        if (settings.after == "function") {
                            settings.after(textInput, text);
                        }
                    }
                    textInput.removeClass('autocomplete-loading');
                });
                oldText = text;
            }
        }

        function clear() {
            list.hide();
            size = 0;
            selected = -1;
        }

        function setCoordinat(point) {
            if (textInput.attr('id') == "adress") {
                document.getElementById('hdnSelectedCoord').value = point;
            }
        }

        function setUlHeight(size) {
            if (textInput.attr('id') == "adress") {
                document.getElementById('suggestUl').style.height = (size * 32) + "px";                
            }
            else {
                if (size <= 9) {
                    document.getElementById('suggestUl').style.height = (size * 32) + "px";
                }
                else {
                    document.getElementById('suggestUl').style.height = "289px";
                    $('#suggestUl').css("overflow-y", "auto");
                    $('#suggestUl').css("overflow-y", "auto");
                    $('#suggestUl').css("overflow-x", "hidden");
                }
            }
        }


        textInput.keydown(function(e) {
            window.clearInterval(typingTimeout);
            if (e.which == 27)//escape
            {
                clear();
            } else if (e.which == 46 || e.which == 8)//delete and backspace
            {
                clear();
                if (settings.validSelection)
                    valueInput.val('');
            }
            else if (e.which == 13)//enter
            {
                if (list.css("display") != "none") {
                    clear();
                    e.preventDefault();
                    return false;
                }
            }
            else if (e.which == 9)//TAB da bisey yapma!
            {
                clear();
            }
            else if (e.which == 40 || e.which == 38)//move up:38, down:40
            {
                var step = 0;

                switch (e.which) {
                    case 40:
                        selected = selected >= size - 1 ? 0 : selected + 1;
                        var index = selected + 1;
                        if (index > 9) {
                            step = 32;
                            $("#suggestUl").scrollTo('+=' + step + 'px', { axis: 'y' });
                        }
                        else {
                            $("#suggestUl").scrollTo(0, { axis: 'y' });
                        }

                        break;
                    case 38:
                        selected = selected <= 0 ? size - 1 : selected - 1;

                        var up = selected + 1;
                        var j = (up - 9);
                        var k = (size - 9);
                        if (j >= 0) {
                            if (j < k) {
                                step = 32;
                                $("#suggestUl").scrollTo('-=' + step + 'px', { axis: 'y' });
                            }
                            else if (j == k) {
                                step = 32 * j;
                                $("#suggestUl").scrollTo('+=' + step + 'px', { axis: 'y' });
                            }
                        }
                        break;
                    default:
                        break;
                }

                textInput.val(list.children().removeClass('selected').eq(selected).addClass('selected').text());

                if (textInput.attr('id') == "adress") {
                    valueInput.val(document.getElementById('hR_' + selected).value);
                    setCoordinat(document.getElementById('hC_' + selected).value);
                }

            } else {
                typingTimeout = window.setTimeout(
                    function() {
                        getData(textInput.val())
                    }, settings.timeout);
            }
        });
    });
};

