﻿/// <reference path="jquery.js" />

// AJAX dropdown
(function($) {

    function move(state, a) {
        if (a.length > 0) {
            state.a.removeClass("autocomplete-hover");
            a.addClass("autocomplete-hover");
            state.a = a;
        }
    }

    function moveup(state) {
        move(state, state.a.prev("a"));
    }

    function movedown(state) {
        move(state, state.a.next("a"));
    }

    function focus(state) {
        if (state.blurTimeout) {
            clearTimeout(state.blurTimeout);
            state.blurTimeout = undefined;
        }
        state.div.show();
    }

    function blur(state) {
        state.blurTimeout = setTimeout(function() { state.div.hide(); }, 333);
    }

    function enter(state) {
        if (state.request) {
            setTimeout(function() { enter(state); }, 150);
            return;
        }
        state.a.click();
        state.text.blur();
    }

    function create(state, msg) {
        state.div.children().remove();
        for (var i = 0; i < Math.min(msg.data.length, 100); i++) {
            var a = $(document.createElement("a"));
            a.text(msg.data[i].name);
            a.bind('click', { state: state, item: msg.data[i] }, function(e) {
                e.data.state.text.val(e.data.item.name);
                e.data.state.hidden.val(e.data.item.value);
            });
            a.bind('mouseover', state, function(e) { move(e.data, $(this)); });
            state.div.append(a);
            move(state, state.div.find("a:first"));
        }
    }

    function elapsed(state, text) {
        state.request = $.ajax({
            type: "POST",
            contentType: "application/x-www-form-urlencoded",
            url: state.url,
            data: $.param({ text: text }),
            dataType: "json",
            success: function(msg) { create(state, msg); },
            complete: function() { state.request = undefined; }
        });
    }

    $.fn.extend({
        autocomplete: function(dataSourceClientUrl) {
            this.each(function() {
                var context = $(this);
                var state = {
                    hidden: context.find("input[type='hidden']:first"),
                    text: context.find("input[type='text']:first"),
                    button: context.find("a:first"),
                    div: context.find("div.autocomplete-div:first"),
                    a: $([]),
                    keypressTimeout: undefined,
                    blurTimeout: undefined,
                    url: dataSourceClientUrl,
                    request: undefined
                };
                state.text.bind('focus', state, function(e) { focus(e.data); });
                state.text.bind('blur', state, function(e) { blur(e.data); });
                state.text.bind('keydown', state, function(e) {
                    if (e.which == 13 || (e.ctrlKey && e.which == 32) || e.which == 38 || e.which == 40) {
                        if (e.which == 13) // enter
                            enter(e.data);
                        else if (e.ctrlKey && e.which == 32) // ctrl + space
                            elapsed(e.data, e.data.text.val());
                        else if (e.which == 38) // up
                            moveup(e.data);
                        else if (e.which == 40) // down
                            movedown(e.data);
                        e.preventDefault();
                        return false;
                    } else {
                        // when typing into the auto-complete text box, 
                        // the text and value are no longer in sync
                        e.data.hidden.val("");
                        if (e.data.keypressTimeout) {
                            clearTimeout(e.data.keypressTimeout);
                            e.data.keypressTimeout = undefined;
                        }
                        e.data.keypressTimeout = setTimeout(function() { elapsed(e.data, e.data.text.val()); }, 500);
                    }
                });
                state.button.bind('click', state, function(e) {
                    e.data.text.focus();
                    elapsed(e.data, e.data.text.val());
                    e.preventDefault();
                    return false;
                });
            });
        }
    });

})(jQuery);