﻿var suggestTextBoxClass = "TextBoxSuggest"; /*Класс текстового поля с подстановкой*/
var suggestItemClass = "suggest-item"; /*Класс варианта подстановки*/
var suggestCurrentClass = "current"; /*Класс текущего варианта подстановки*/
var visibleTextClass = "visible-text"; /*Класс видимого текста*/
var insertingTextClass = "inserting-text"; /*Класс подставляемого текста*/
var valueSuggestClass = "values"; /*Класс значения подстановки*/

var RequestDelay = 300; /*Время задержки вызова*/
var minSuggestQueryLength = 3; /*Минимальное количество символов*/

var currentItemElement; /*Элемент текущего варианта подстановки*/
var suggestTextBoxElement; /*Элемент элемент текстбокса*/

/*Переменная для хранения таймера, который откладывает вызов запроса на сайт*/
var queryTimer = false;


function BindEventToSuggestItem() {
    $("." + suggestItemClass).hover(function() {
        SetCurrentItem($(this));
    }, "");

    $("." + suggestItemClass).click(function() {
        SetCurrentItem($(this));
        ChooseCurrentItem();
    });
}

function BindEventToSuggestTextBox() {


    $("." + suggestTextBoxClass).keydown(function(e) {
        e = e || event;
        switch (e.keyCode) {
            case 38: { PrevItem(); return false; } /*Стрелка вниз*/
            case 40: { NextItem(); return false; } /*Стрелка вверх*/
            case 13: { ChooseCurrentItem(); return false; } /*Enter*/
        }
    });

    $("." + suggestTextBoxClass).keyup(function(e) {
        e = e || event;
        switch (e.keyCode) {
            case 38: { return false; } /*Стрелка вниз*/
            case 40: { return false; } /*Стрелка вверх*/
            case 13: { return false; } /*Enter*/
            case 39: { return true; } /*Стрелка вправо*/
            case 37: { return true; } /*Стрелка влево*/
        }

        RemoveValuesToHiddenFields(this);

        NoteUserText(this);
        HideSuggest();
        LoadSuggest(this);
    });

    $("." + suggestTextBoxClass).attr("autocomplete", "off");

    $("." + suggestTextBoxClass).focusout(function() {
        ChooseCurrentItem();
    });

    $("." + suggestTextBoxClass).mouseup(function() {
        this.select();

        var userText = GetUserText(this);
        if (userText != null) {
            HideSuggest();
            LoadSuggest(this, GetUserText(this));
        }

    });

}

/*Устанавливает следующий элемент*/
function NextItem() {
    if (currentItemElement) {
        var nextElement = $(currentItemElement).next("." + suggestItemClass);
        if (nextElement.length != 0) SetCurrentItem(nextElement); else { currentItemElement = null; NextItem(); }
    }
    else {
        SetCurrentItem(GetCurrentSuggest().children("." + suggestItemClass + ":first"));
    }
}

/*Устанавливает предыдущий элемент*/
function PrevItem() {
    var prevElement = $(currentItemElement).prev("." + suggestItemClass);
    SetCurrentItem(prevElement);
}


/*Устанавливает переданный элемент как текущий*/
function SetCurrentItem(item) {
    $("." + suggestItemClass).removeClass(suggestCurrentClass);
    item.addClass(suggestCurrentClass);
    currentItemElement = item;
}

/*Возращает текущий TextBox*/
function GetCurrentTextBox() {
    return $(suggestTextBoxElement);
}

/*Возращает текущий элемент с вариантами подстановок*/
function GetCurrentSuggest() {
    return $("#" + GetCurrentTextBox().attr("meta:suggestElementId"));
}

/*Возращает текущий элемент с вариантами подстановок*/
function GetCurrentSuggestValueElement() {
    return $("#" + GetCurrentTextBox().attr("meta:suggestValueElementId"));
}

/*Выбирает текущий элемент*/
function ChooseCurrentItem() {
    if (currentItemElement) {
        var insertingTextElement = $(currentItemElement).children("." + insertingTextClass + ":first");
        if (insertingTextElement.length == 0)
        {
            insertingTextElement = $(currentItemElement).children("." + visibleTextClass + ":first");
        }
        GetCurrentTextBox().val(insertingTextElement.text());

        var valueSuggest = $(currentItemElement).children("." + valueSuggestClass + ":first");

        CopyValuesToHiddenFields(valueSuggest, GetCurrentTextBox());

    }
    GetCurrentTextBox().blur();
    HideSuggest();
}

/*Скрывает варианты*/
function HideSuggest() {
    if (suggestTextBoxElement != null) {
        GetCurrentSuggest().css("display", "none");
        suggestTextBoxElement = null;
        currentItemElement = null;
    }

}

/*Запоминает текст введенные пользователем*/
function NoteUserText(textBox) {
    var text = $(textBox).val();
    $(textBox).attr("meta:userText", text);
}

/*Запоминает текст введенные пользователем*/
function RemoveUserText(textBox) {
    $(textBox).removeAttr("meta:userText");
}

/*Возращает текст введенные пользователем*/
function GetUserText(textBox) {
    return $(textBox).attr("meta:userText");
}

/*Показывает варианты*/
function ShowSuggest(suggestText, textBoxid) {
    suggestTextBoxElement = $("#" + textBoxid);
    var suggestElement = GetCurrentSuggest();
    suggestElement.html(suggestText);

    ShowUnder(suggestTextBoxElement, suggestElement);

    currentItemElement = null;

    BindEventToSuggestItem();

    ChooseIfOne(suggestElement);
}


function ChooseIfOne(suggestElement) {
    if (suggestElement.find("." + suggestItemClass).length == 1) {
        RemoveUserText(GetCurrentTextBox());
        NextItem();
        ChooseCurrentItem();
    }
}


/*Функция отображает элемент showingElement под элементом parentElement*/
function ShowUnder(parentElement, showingElement) {
    var absolutePosition = parentElement.offset();
    var left = absolutePosition.left;
    var top = absolutePosition.top + parentElement.outerHeight();

    showingElement = $(showingElement);

    showingElement.css("display", "inline");
    showingElement.css("position", "absolute");
    showingElement.css("z-index", "101");
    showingElement.offset({ top: top, left: left });
    showingElement.offset({ top: top, left: left });
    showingElement.width(parentElement.width());
}


/*Функция посылает запрос на поиск текста*/
function LoadSuggest(textBox, text) {
    textBox = $(textBox);

    if (text == null) { text = textBox.val(); }
    var controller = textBox.attr("meta:controller");
    var action = textBox.attr("meta:action");
    var textBoxId = textBox.attr("id");

    if (text.length < minSuggestQueryLength) {
        return;
    }
    
    if (queryTimer) StopQueryTimer();
    StartQueryTimer(text, controller, action, textBoxId);
}

/*Останавливает таймер запроса*/
function StopQueryTimer() {
    clearTimeout(queryTimer);
    queryTimer = false;
}

/*Запускает таймер отсрочки запроса*/
function StartQueryTimer(text, controller, action, textBoxId) {
    queryTimer = setTimeout("RequestSuggest('" + text + "','" + controller + "','" + action + "','" + textBoxId + "');", RequestDelay);
}

/*Функция отсылки запроса*/
function RequestSuggest(text, controller, action, textBoxId) {
    $.ajax({
        type: "POST",
        url: "/" + controller + "/" + action,
        dataType: "html",
        data: ({ text: text }),
        success: function(html) { ShowSuggest(html, textBoxId) },
        error: function(xMLHttpRequest, textStatus, errorThrown) { alert("Ошибка: " + xMLHttpRequest.responseText); }
    });
}

/*--------------------------------------------------------------------*/
/*-----------------Не унифицированный код-----------------------------*/

function CopyValuesToHiddenFields(sourceElement, textBoxElement) {
    var idValuesHolderElement = $("#" + textBoxElement.attr("meta:idValuesHolder"));
    var locationTypeValuesHolderElement = $("#" + textBoxElement.attr("meta:locationTypeValuesHolder"));

    idValuesHolderElement.val(sourceElement.attr("meta:id"));
    locationTypeValuesHolderElement.val(sourceElement.attr("meta:locationType"));
}

function RemoveValuesToHiddenFields(textBoxElement) {
    var textBoxElement = $(textBoxElement);
    var idValuesHolderElement = $("#" + textBoxElement.attr("meta:idValuesHolder"));
    var locationTypeValuesHolderElement = $("#" + textBoxElement.attr("meta:locationTypeValuesHolder"));

    idValuesHolderElement.val(null);
    locationTypeValuesHolderElement.val(null);
}