angular.module("app").directive("timeframePicker", function ($rootScope, BackendService, SQEvents, SQConstants, UniqueIdGenerator, L) {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: "../app/directives/timeframePicker/timeframePicker.html",
        scope: {
            timeframe: '=',
            minTimeframe: '=',
            label: '@',
            enableTickTf: '@',
            ngDisabled: '=',
            mainDataOption: '@',
            mainChart: '@',
            higherTfsDisabled: '=',
            customTfsDisabled: '='
        },
        link: function (scope, element, attrs) {

            scope.innerTimeframe = scope.timeframe;

            function loadAvailableTimeframes() {
                scope.availableTimeframes.length = 0;
                if (!scope.minTimeframe) {
                    scope.minTFSeconds = 1000000000;
                    return;
                }

                if (scope.higherTfsDisabled) {
                    scope.availableTimeframes.push(scope.minTimeframe);
                    scope.minTFSeconds = 1000000000;
                    return;
                }

                if (scope.mainDataOption) {
                    scope.availableTimeframes.push("Same as main data");
                }

                if (scope.minTimeframe == TF.Intraday) {
                    scope.availableTimeframes.push(TF.Intraday);
                    scope.minTFSeconds = 1000000000;
                    return;
                }

                var minTFSeconds = getTFSeconds(scope.minTimeframe);
                scope.minTFSeconds = minTFSeconds;

                for (var i = 0; i < scope.timeframes.length; i++) {
                    var timeframe = scope.timeframes[i];
                    if (!scope.enableTickTf && timeframe == 'TICK') continue;

                    if (getTFSeconds(timeframe) >= minTFSeconds) {
                        scope.availableTimeframes.push(timeframe);
                    }
                }

                if (!scope.customTfsDisabled) {
                    scope.availableTimeframes.push(L.tsq("Custom..."));
                }
            }

            scope.showTFPopup = function () {
                scope.newTF = {
                    prefix: getMinPrefix(),
                    seconds: 1,
                    minutes: 1,
                    hours: 1,
                    days: 1
                };
                showPopup('#' + scope.timeframesPopupId);
            }

            function getMinPrefix() {
                if (scope.minTFSeconds <= 1) return 'S';
                else if (scope.minTFSeconds <= 60) return 'M';
                else if (scope.minTFSeconds <= 3600) return 'H';
                else if (scope.minTFSeconds <= 86400) return 'D';
            }

            scope.hideTFDropDown = function () {
                $('.dropdown-tf').hide();
            }

            scope.saveTimeframe = function () {
                if (document.activeElement != undefined && document.activeElement.classList.contains('sq-data-input-input')) {
                    return;
                }
                var timeframe = getNewTFStr();
                if (timeframe) {
                    BackendService.getPromise('data/addTimeframe', {
                        timeframe: timeframe
                    }).then(function (result) {
                        if (result.success) {
                            scope.hideTFDropDown();
                            newTF = timeframe;
                        } else {
                            $rootScope.showError(result.data.error);
                        }
                    });
                }
            }

            function getNewTFStr() {
                var value = 0;

                switch (scope.newTF.prefix) {
                    case 'S':
                        value = scope.newTF.seconds;
                        break;
                    case 'M':
                        value = scope.newTF.minutes;
                        break;
                    case 'H':
                        value = scope.newTF.hours;
                        break;
                    case 'D':
                        value = scope.newTF.days;
                        break;
                    default:
                        $rootScope.showError(L.tsq("Unknown timeframe prefix '%s'", [scope.newTF.prefix]));
                        return false;
                }

                return scope.newTF.prefix + value;
            }

            function isTFSupported(tf) {
                return scope.availableTimeframes.indexOf(tf) >= 0;
            }

            var destroyMinTFWatch = scope.$watch('minTimeframe', function (newValue, oldValue) {
                if (valueFilled(newValue)) {
                    loadAvailableTimeframes();
                    if (!isTFSupported(scope.timeframe)) {
                        scope.timeframe = scope.availableTimeframes[0];
                    }
                }
                else {
                    scope.availableTimeframes.length = 0;
                }
            });

            var destroyTFWatch = scope.$watch('timeframe', function (newValue, oldValue) {
                scope.innerTimeframe = newValue;
            });

            var destroyInnerTFWatch = scope.$watch('innerTimeframe', function (newValue, oldValue) {
                if (newValue == L.tsq("Custom...")) {
                    if (newValue != oldValue) {
                        scope.timeframe = oldValue;
                        scope.innerTimeframe = oldValue;
                        scope.showTFPopup();
                    }
                    return;
                }

                scope.timeframe = scope.innerTimeframe;

                if (disableWatch) {
                    disableWatch = false;
                    return;
                }

                if (valueFilled(newValue)) {
                    if (!isTFSupported(scope.timeframe)) {
                        disableWatch = true;
                        scope.timeframe = scope.availableTimeframes[0];
                    }

                    if (scope.mainChart) SQEvents.notifyListeners(SQEvents.get("MAIN_TF_CHANGED", scope.timeframe));
                }
            });

            var destroyHigherTfsDisabledWatch = scope.$watch('higherTfsDisabled', function (newValue, oldValue) {
                if (valueFilled(newValue)) {
                    loadAvailableTimeframes();
                }
            });

            function onEvent(event, data) {
                if (event == SQEvents.get('TIMEFRAMES_CHANGED')) {
                    scope.timeframes = angular.copy(data);
                    loadAvailableTimeframes();

                    if (newTF && getTFSeconds(newTF) >= getTFSeconds(scope.minTimeframe)) {
                        scope.timeframe = newTF;
                    }
                }

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

            scope.$on('$destroy', function () {
                destroyMinTFWatch();
                destroyTFWatch();
                destroyInnerTFWatch();
                destroyHigherTfsDisabledWatch();

                SQEvents.removeListener(listenerId);
                UniqueIdGenerator.removeId(uniqueId);
                UniqueIdGenerator.removeId(scope.timeframesPopupId);
            });

            var newTF = null; //recently added timeframe to be selected in setup popup after timeframes update
            var disableWatch = false;

            scope.timeframes = SQConstants.getConstants().timeframes;
            var TF = SQConstants.getConstants().timeframe;

            scope.availableTimeframes = [];
            scope.minTimeframe = scope.minTimeframe || 'M1';
            scope.minTFSeconds = getTFSeconds(scope.minTimeframe);

            loadAvailableTimeframes();

            var uniqueId = UniqueIdGenerator.generateId();
            var listenerId = "TimeframePicker-" + uniqueId;
            SQEvents.addListener(listenerId, [SQEvents.get('TIMEFRAMES_CHANGED')], onEvent);

            scope.timeframesPopupId = UniqueIdGenerator.generateId();
        }
    };
});