angular.module("app").directive("sqDataInput", function ($rootScope, $state, SQEvents, SQConstants, UniqueIdGenerator, $timeout, $document, AppService) {
    return {
        restrict: 'E',
        replace: false,
        scope: {
            sqModel: '=',
            change: '&',
        },
        templateUrl: "../app/directives/sqDataInput/sqDataInput.html",
        controller: function ($scope, $element) {
            $scope.selectChange = function (item) {
                if (Array.isArray(item)) {
                    $scope.sqModel = item[0];
                    $scope.innerModel = [item[0]];
                }
                else {
                    $scope.sqModel = item;
                }
                $($element).find(".sq-data-input-dropdown input").blur();
                if ($scope.recentlyUsedSymbols.indexOf($scope.sqModel) < 0) {
                    $scope.recentlyUsedSymbols.unshift($scope.sqModel);
                    $scope.recentlyUsedSymbols = $scope.recentlyUsedSymbols.slice(0, 5); // brat jen poslednich 6 symbolu
                    AppService.saveSetting("recentlyUsedSymbols", $scope.recentlyUsedSymbols.join(","), function () { });
                }
            }

            $scope.inputClick = function () {
                $scope.searchString = "";
                $scope.dropdownOpened = true;
                $scope.innerModel = [$scope.sqModel];
                $scope.onSearchStringChanged();

                $timeout(function () {
                    $($element).find(".sq-data-input-dropdown input").focus()[0].value = "";
                }, 0, false);
            };

            $scope.dropdownClicked = function (event) {
                event.stopPropagation();
            }
        },
        link: function (scope, element, attrs) {
            function loadAvailableData() {
                scope.availableData.length = 0;
                var constants = SQConstants.getConstants();
                if (!constants.data) return;

                for (var i = 0; i < constants.data.length; i++) {
                    var data = constants.data[i];
                    if (data.rows > 0 && data.show) {
                        scope.availableData.push(data);
                    }
                }

                scope.availableData.sort().reverse();

                if (SQConstants.getSettings().recentlyUsedSymbols != undefined) {
                    scope.recentlyUsedSymbols = ("" + SQConstants.getSettings().recentlyUsedSymbols).split(",");
                }
            }

            function onEvent(event, data) {
                if (event == SQEvents.get('DATA_CHANGED')) {
                    loadAvailableData(data);
                }
                else return;

                try { scope.$digest(); } catch (er) { }
            }

            $document.bind('click', function () {
                scope.dropdownOpened = false;
            })

            element.bind('click', function (e) {
                e.stopPropagation();
            });

            var destroySearchStringWatch = scope.$watch('searchString', function () {
                scope.onSearchStringChanged();
            });

            scope.onInputBlur = function (event) {
                if (event.relatedTarget != undefined && event.relatedTarget.tagName.toLowerCase() == "select") {
                    return;
                }
                scope.dropdownOpened = false;
            }

            scope.onSelectKeyUp = function (event) {
                if (event.key != "ArrowDown" && event.key != "ArrowUp") {
                    if (event.key == "Backspace") {
                        scope.searchString = scope.searchString.slice(0, -1);
                        $(element).find(".sq-data-input-dropdown input").val(scope.searchString);
                    }
                    if (event.key.length == 1) {
                        scope.searchString += event.key;
                        $(element).find(".sq-data-input-dropdown input").val(scope.searchString);
                    }
                    if (event.key == "Enter") {
                        scope.onInputKeyUp(event);
                        return;
                    }
                    $timeout(function () {
                        $(element).find(".sq-data-input-dropdown input").focus();
                    }, 0, false);
                }
            }

            scope.onInputKeyUp = function (event) {
                var $s = $(element).find('.sq-data-input-dropdown select');
                var selectOptions = $s.find("option");

                if (event.key == "ArrowDown") {
                    event.preventDefault();
                    var newI = 0;
                    for (var i = 0; i < selectOptions.length; i++) {
                        if (selectOptions[i].value == $s[0].value && i + 1 < selectOptions.length) {
                            $s.val(selectOptions[i + 1].value);
                            $s.focus();
                            return;
                        }
                    }
                    $s.val(selectOptions[0].value);
                    $s.focus();
                    return;
                }
                if (event.key == "ArrowUp") {
                    event.preventDefault();
                    for (var i = 0; i < selectOptions.length; i++) {
                        if (selectOptions[i].value == $s[0].value && i - 1 >= 0) {
                            $s.val(selectOptions[i - 1].value);
                            $s.focus();
                            return;
                        }
                    }
                    $s.val(selectOptions[selectOptions.length - 1].value);
                    $s.focus();
                    return;
                }

                if (event.key == "Enter") {
                    event.preventDefault();
                    event.stopPropagation();
                    scope.innerModel = [$s[0].value.replace("string:", "")];
                    scope.selectChange(scope.innerModel);
                    return;
                }

                if (event.key == "Escape") {
                    event.preventDefault();
                    scope.dropdownOpened = false;
                    $(element).find(".sq-data-input-dropdown input").blur();
                    return;
                }

                scope.searchString = event.target.value;
                scope.onSearchStringChanged();
                $timeout(function () {
                    $s[0].selectedIndex = 0;
                }, 0, false);
            }

            scope.onSearchStringChanged = function () {
                var allData = [];

                scope.filteredData = [];

                for (var i = 0; i < scope.availableData.length; i++) {
                    if (scope.availableData[i].symbol.toLowerCase().indexOf(scope.searchString.toLowerCase()) > -1) {
                        if (scope.recentlyUsedSymbols.indexOf(scope.availableData[i].symbol) == -1) {
                            scope.filteredData.push(scope.availableData[i].symbol);
                        }
                    }
                    allData.push(scope.availableData[i].symbol);
                }

                scope.filteredData.sort();

                var recentsToAdd = [];
                if (scope.searchString == "") {
                    // pridavani recently used symbols
                    for (var i = 0; i < scope.recentlyUsedSymbols.length; i++) {
                        if (allData.indexOf(scope.recentlyUsedSymbols[i]) >= 0) {
                            recentsToAdd.push(scope.recentlyUsedSymbols[i]);
                        }
                    }
                }

                scope.filteredData = recentsToAdd.concat(scope.filteredData);
            }

            scope.isRecentItem = function (item) {
                return (scope.recentlyUsedSymbols.indexOf(item) >= 0)
            }

            scope.$on("$destroy", function () {
                destroySearchStringWatch();
                destroySqModelWatch();
                SQEvents.removeListener(listenerId);
                UniqueIdGenerator.removeId(id);
            });

            var destroySqModelWatch = scope.$watch("sqModel", function () {
                scope.innerModel = [scope.sqModel];
            });

            var id = UniqueIdGenerator.generateId();
            var listenerId = "SQDataInput-" + id;

            scope.availableData = [];
            scope.filteredData = [];
            scope.symbol = "";
            scope.searchString = "";
            scope.dropdownOpened = false;
            scope.innerModel = [];
            scope.recentlyUsedSymbols = [];

            loadAvailableData();
            if (scope.availableData.length > 0) {
                scope.symbol = scope.availableData[0].symbol;
            }

            SQEvents.addListener(listenerId, [
                SQEvents.get('DATA_CHANGED')
            ], onEvent);
        }
    };
});