﻿var keys = {
    VK_UP: 0x26,
    VK_DOWN: 0x28,
    VK_RETURN: 0x0d,
    VK_ESCAPE: 0x1b,
    VK_DASH1: 0xbd,
    VK_DASH2: 0x6d,
    VK_COMMA1: 0xbc,
    VK_COMMA2: 0x6e,
    VK_TAB: 0x9
};
var autoState = {
    currentItems: null,
    currentIndex: 0,
    lastSearchText: null,
    initialized: false,
    getCurrentItem: function() {
        return autoState.currentItems[autoState.currentIndex];
    },
    canSelect: function() {
        return (itemState.active && !itemState.selecting && autoState.currentItems && autoState.currentItems.length > 0 && itemState.getCurrentText().length > 0);
    },
    requests: [],
    requestTimers: []
};
var itemState = {
    active: false,
    selecting: false,
    textParts: [],
    idParts: [],
    typeParts: [],
    isRange: false,
    currentIndex: 0,
    rangeStart: null,
    getCurrentText: function() {
        var text = itemState.textParts[itemState.currentIndex];

        if (itemState.isRange) {
            var dashIndex = text.indexOf("-");

            if (dashIndex > -1)
                text = text.substring(dashIndex + 1);
        }

        return $.trim(text);
    }
};
function registerAutoComplete(registerChange) {
    var textInput = $("input#location-text");
    var autoList = $("div#auto-complete");

    textInput.focus(function () {
        if (!autoState.initialized) {
            var left = textInput.position().left - 7;
            var top = textInput.position().top + textInput.outerHeight();

            autoList.css("left", left + "px");
            autoList.css("top", top + "px");

            autoState.initialized = true;

            parseInputState();
        }

        showAutoComplete();
    });

    textInput.blur(function () {
        hideAutoComplete();

        if (registerChange && $.trim($(this).val()) != "")
            $(this).trigger("change");
    });

    textInput.keyup(function(event) {
        if (itemState.active)
            updateAutoComplete();
    });

    textInput.keydown(function (event) {
        switch (event.which) {
            case keys.VK_ESCAPE:
                hideAutoComplete();
                break;
            case keys.VK_DOWN:
                if (itemState.active)
                    scrollDown();
                else {
                    showAutoComplete();
                    updateAutoComplete();
                }
                event.preventDefault();
                break;
            case keys.VK_UP:
                if (itemState.active)
                    scrollUp();
                event.preventDefault();
                break;
            case keys.VK_RETURN:
            case keys.VK_TAB:
                if (autoState.canSelect()) {
                    selectCurrent(false);

                    if (event.which != keys.VK_TAB)
                        event.preventDefault();
                } else if (registerChange)
                    $(this).trigger("blur");
                break;
            case keys.VK_COMMA1:
            case keys.VK_COMMA2:
                if (autoState.canSelect())
                    selectCurrent(false);

                event.preventDefault();
                break;
            case keys.VK_DASH1:
            case keys.VK_DASH2:
                if (autoState.canSelect()) {
                    selectCurrent(true);
                    event.preventDefault();
                }
                break;
        }
    });
}
function parseInputState() {
    var idInput = $("input#location-ids");
    var typeInput = $("input#location-types");
    var textInput = $("input#location-text");

    itemState.idParts = idInput.val().split(",");
    itemState.typeParts = typeInput.val().split(",");
    itemState.textParts = textInput.val().split(",");

    for (var i = 0; i < itemState.textParts.length; i++)
        itemState.textParts[i] = $.trim(itemState.textParts[i]);
}
function showAutoComplete() {
    var autoList = $("div#auto-complete");

    autoList.show();
    itemState.active = true;
}
function hideAutoComplete() {
    var autoList = $("div#auto-complete");

    autoList.hide();
    itemState.active = false;
}
function updateAutoComplete() {
    updateItemState();
    tryUpdateItems();
}
function selectFromIndex(index) {
    autoState.currentIndex = index;

    selectCurrent(false);

    updateAutoComplete();
}
function selectCurrent(range) {
    itemState.selecting = true;
    
    var item = autoState.getCurrentItem();

    var wasRange = itemState.isRange;

    if (!wasRange) {
        itemState.textParts[itemState.currentIndex] = item.query;
        itemState.idParts[itemState.currentIndex] = item.id;
        itemState.typeParts[itemState.currentIndex] = item.type;
        itemState.isRange = range;

        if (range)
            itemState.rangeStart = item.query;
    } else {
        itemState.textParts[itemState.currentIndex] = itemState.rangeStart + "-" + item.query;
        itemState.typeParts[itemState.currentIndex] = "CityRange";
        itemState.isRange = false;
        itemState.rangeStart = null;
    }

    var addSeparator = (itemState.currentIndex == itemState.textParts.length - 1);

    updateFormState(addSeparator, range);

    autoState.currentItems = null;
    itemState.selecting = false;
}
function updateFormState(addSeparator, range) {
    updateFormHidden(addSeparator, range);
    updateFormText(addSeparator, range);
}
function updateFormText(addSeparator, range) {
    var separator = range ? "-" : ", ";

    var textSep = addSeparator ? separator : "";

    $("input#location-text").val(itemState.textParts.join(", ") + textSep);
}
function updateFormHidden(addSeparator, range) {
    var separator = range ? "-" : ", ";

    var idSep = addSeparator ? "," : "";

    $("input#location-ids").val(itemState.idParts.join(",") + idSep);
    $("input#location-types").val(itemState.typeParts.join(",") + idSep);
}
function updateItemState() {
    var pos = getCaretPosition();
    var parts = $("input#location-text").val().split(",");
    var len = 0;
    var partIndex = -1;
    for (var i = 0; i < parts.length; i++) {
        len += parts[i].length + 1;

        if (partIndex == -1 && len > pos)
            partIndex = i;

        parts[i] = $.trim(parts[i]);
    }

    if (itemState.textParts[partIndex] != parts[partIndex]) {
        itemState.idParts[partIndex] = null;
        itemState.typeParts[partIndex] = null;

        updateFormHidden(false, false);
    }
    itemState.textParts = parts;
    itemState.currentIndex = partIndex;
}
function scrollUp() {
    if (autoState.currentIndex == 0)
        autoState.currentIndex = autoState.currentItems.length - 1;
    else
        autoState.currentIndex--;

    updateListSelectionUi();
}
function scrollDown() {
    if (autoState.currentIndex == autoState.currentItems.length - 1)
        autoState.currentIndex = 0;
    else
        autoState.currentIndex++;

    updateListSelectionUi();
}
function updateListUi() {
    var autoList = $("div#auto-complete ul");

    autoList.children().remove();
    for (var i = 0; i < autoState.currentItems.length; i++) {
        var item = autoState.currentItems[i];

        var el = $("<li><a href=\"#\" /></li>");
        el.children("a").text(item.display);

        autoList.append(el);
    }

    updateListSelectionUi();

    var links = $("li a", autoList);
    links.each(function(index) {
        $(this).mousedown(function() {
            selectFromIndex(index);

            return false;
        });
    });
}
function updateListSelectionUi() {
    var listItems = $("div#auto-complete ul li");

    listItems.removeClass("selected");
    listItems.eq(autoState.currentIndex).addClass("selected");
}
function getCaretPosition() {
    var input = $("input#location-text")[0];
    var pos = 0;
    if (document.selection) {
        var range = document.selection.createRange();
        range.moveStart("character", -input.value.length);

        pos = range.text.length;
    } else if (input.selectionStart || input.selectionStart == "0")
        pos = input.selectionStart;
	
    return pos;
}
function clearRequestTimers() {
    for (var i = 0; i < autoState.requestTimers.length; i++)
        clearTimeout(autoState.requestTimers[i]);

    autoState.requestTimers = [];
}
function getUpdateUrl(searchText) {
    return "/Home/GetAutoCompleteJson/?section=" + Bolig.section + "&searchText=" + searchText + "&range=" + itemState.isRange;
}

function tryUpdateItems() {
    var searchText = itemState.getCurrentText();
    var url = getUpdateUrl(searchText);

    if (!searchText || searchText.length == 0) {
        autoState.currentItems = new Array();
        updateListUi();

        return;
    } else if (searchText == autoState.lastSearchText)
        return;

    clearRequestTimers();

    var fn = function () { updateItems(searchText, url); };
    var timerId = setTimeout(fn, 100);
    autoState.requestTimers.push(timerId);
}
function updateItems(searchText, url) {
    $.getJSON(url, null, function (data) {
        if (data.query == searchText) {
            autoState.currentItems = data.matches;
            autoState.currentIndex = 0;
            autoState.lastSearchText = searchText;

            updateListUi();
        }
    });
}
