angular.module("app").directive("chartSetupSimple", function ($rootScope, $timeout, L, AppService, DataService, AutoRetestDataService, UniqueIdGenerator, SQConstants, SQEvents) {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: "../app/directives/chartSetupSimple/views/chartSetupSimple.html",
        scope: {
            setup: '=',
            ngDisabled: '=',
            detailedConfig: '='
        },
        link: function (scope, element, attrs) {

            function init() {
                scope.symbolDateRange = DataService.getSymbolDateRange(scope.setup.symbol);

                scope.constants.subchartData = angular.copy(scope.availableData);
                scope.constants.subchartData.splice(0, 0, {
                    symbol: 'Same as main chart'
                });

                DataService.loadAvailablePrecisions(scope.precisions, scope.setup.symbol, scope.setup.engine);

                oldDateFrom = scope.setup.dateFrom;
                oldDateTo = scope.setup.dateTo;

                scope.settingsChanged();

                $timeout(function () {
                    initialized = true;
                    scope.forceDateChange = false;
                    
                    if(!scope.setup.symbol && scope.availableData.length>0) {
                        scope.setup.symbol = scope.availableData[0].symbol;
                    }
                    // scope.settingsChanged();
                }, 0, false);
            }

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

            scope.getPrecisionLabel = function(){
                var selectedPrecision = getItem(scope.precisions, "value", scope.setup.precision);
                return selectedPrecision ? L.tsq(selectedPrecision.name) : '';
            }

            function getCommissionsConfigElement() {
                return xmlToObject(scope.setup.commissions).find("Commissions")[0];
            }

            scope.getCommissionLabel = function(){
                if(!commGridLoaded) return L.tsq("N/A");

                var type = scope.commPGInstance.getSelectedType();     
                if(!type) return L.tsq("N/A");

                var data = scope.commPGInstance.getSelectedValues();       
                
                var commissionsLabel = type;

                var method = getItem(scope.commissionMethods, "class", type);
                if(method) {
                    commissionsLabel = L.tsq(method.display);

                    for(var i=0; i<data.length; i++) {
                        var property = data[i];
                        var value = property.value;
                        var key = property.key;
                        
                        return commissionsLabel.replace("#"+key+"#", value);
                    }
                }

                return commissionsLabel;
            }

            scope.getSwapLabel = function(){
                if(!scope.setup.swap){
                    return L.tsq("No swap");
                }

                let elSwap = xmlToObject(scope.setup.swap).find("Swap")[0];
                if(!getAttrBooleanValue(elSwap, "use", false)){
                    return L.tsq("No swap");
                }

                let swapType = getAttrStringValue(elSwap, "type", scope.constants.swapTypes.money);
                let swapLong = getAttrFloatValue(elSwap, "long", 0);
                let swapShort = getAttrFloatValue(elSwap, "short", 0);
                let typeChar = swapType === scope.constants.swapTypes.money ? "$" : (swapType === scope.constants.swapTypes.percent ? "%" : "points");

                return L.tsq("long: %s, short: %s", [(swapLong + typeChar), (swapShort + typeChar)]); 
            }

            var commGridLoaded = false;
            scope.afterPGInit = function(){
                var config = DataService.getCommissionSettings(null, getCommissionsConfigElement());
                scope.commPGInstance.setSettings(config);
                commGridLoaded = true;

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

            scope.onCommPGChange = function () {
                var newType = scope.commPGInstance.getSelectedType(); //method name
                var configElement = getCommissionsConfigElement();

                //switching to other method
                if (curCommissionType != newType) {
                    curCommissionType = newType;

                    var commissionSettings = DataService.getCommissionSettings(newType, configElement);

                    if (commissionSettings.method == newType) {
                        scope.commPGInstance.setSettings(commissionSettings);
                    }
                }
                
                DataService.updateCommissionSettings(newType, scope.commPGInstance, configElement);
                scope.setup.commissions = xmlToString(configElement);
            }

            scope.showCommissionsPopup = function(){
                showPopup('#commissionsPopup-' + scope.id);
            }

            scope.showSwapPopup = function(){
                showPopup('#swapPopup-' + scope.id);
            }

            scope.settingsChanged = function(useCustomValue, type = "") {
                if(!initialized) return;

                if(useCustomValue) { //zaisti nastavenie default hodnoty pri zaskrtnuti custom checkboxu
                    DataService.changeSetupDetails(scope.setup, scope.precisions, scope.setup.symbol);
                }

                var mainSetup = scope.isAutoRetest ? AutoRetestDataService.setup : DataService.config.setups[0];
                var symbolData = getItem(scope.constants.data, "symbol", scope.setup.symbol);

                scope.setup.minDistance = scope.setup.useCustomDistance ? scope.setup.minDistance : mainSetup.minDistance;

                if(!scope.setup.useCustomSlippage){
                    scope.setup.slippage = symbolData.slippage;
                } else if(scope.setup.useCustomSpread && type == "slippage") {
                    scope.setup.slippage = symbolData.slippage;
                }
                
                if(!scope.setup.useCustomSpread) {
                    scope.setup.spread = symbolData.spread;
                } else if(scope.setup.useCustomSpread && type == "spread") {
                    scope.setup.spread = symbolData.spread;
                }

                if(!scope.setup.useCustomTF && getTFSeconds(symbolData.timeframe) <= getTFSeconds(mainSetup.timeframe)){
                    scope.setup.timeframe = mainSetup.timeframe;
                }
                
                if(!scope.setup.useCustomDates){
                    scope.setup.dateFrom = new Date(mainSetup.dateFrom) < new Date(symbolData.dateFrom) ? timeToDateString(symbolData.dateFrom) : mainSetup.dateFrom;
                    scope.setup.dateTo = new Date(mainSetup.dateTo) > new Date(symbolData.dateTo) ? timeToDateString(symbolData.dateTo) : mainSetup.dateTo;
                }

                if(!scope.setup.dateFrom || scope.setup.dateFrom == "null"){
                    scope.setup.dateFrom = timeToDateString(symbolData.dateFrom);
                }
                if(!scope.setup.dateTo || scope.setup.dateTo == "null"){
                    scope.setup.dateTo = timeToDateString(symbolData.dateTo);
                }

                if(!scope.setup.useCustomPrecision && getItem(scope.precisions, "value", mainSetup.precision)){
                    scope.setup.precision = mainSetup.precision;
                }

                if(!scope.setup.useCustomCommission){
                    let commissions = angular.copy(symbolData.commissions);
                    if(commissions.indexOf("<Commissions>") == -1){
                        commissions = "<Commissions>" + commissions + "</Commissions>"
                    }
                    scope.setup.commissions = commissions;
                }

                if(!scope.setup.useCustomSwap){
                    scope.setup.swap = angular.copy(symbolData.swap);
                }

                if(commGridLoaded){
                    var config = DataService.getCommissionSettings(null, getCommissionsConfigElement());
                    scope.commPGInstance.setSettings(config);
                }

                if(!scope.setup.useCustomSession || (mainSetup.engine != 'Tradestation' && mainSetup.engine != 'Multicharts')){
                    scope.setup.session = mainSetup.session;
                }

                if(!scope.setup.useCustomSubCharts){
                    scope.setup.subcharts = JSON.parse(JSON.stringify(mainSetup.subcharts))
                }
            }

            scope.resetDates = function () {
                var symbolData = DataService.getSymbolData(scope.setup.symbol);
                var mainSetup = scope.isAutoRetest ? AutoRetestDataService.setup : DataService.config.setups[0];

                if (symbolData) {
                    scope.setup.dateFrom = new Date(mainSetup.dateFrom) < new Date(symbolData.dateFrom) ? timeToDateString(symbolData.dateFrom) : mainSetup.dateFrom;
                    scope.setup.dateTo = new Date(mainSetup.dateTo) > new Date(symbolData.dateTo) ? timeToDateString(symbolData.dateTo) : mainSetup.dateTo;
                    onDateChange()
                }
            }
            
            scope.onDateFromChange = function (date) {
                scope.setup.dateFrom = date;
                onDateChange();
            }

            scope.onDateToChange = function (date) {
                scope.setup.dateTo = date;
                onDateChange();
            }

            function onDateChange() {
                var dateFrom = getDate(scope.setup.dateFrom);
                var dateTo = getDate(scope.setup.dateTo);

                if (dateTo < dateFrom) {
                    if (oldDateFrom && oldDateTo) {
                        scope.setup.dateFrom = oldDateFrom;
                        scope.setup.dateTo = oldDateTo;
                    }

                    $rootScope.showError(L.tsq("Date from must be before date to"));
                    return;
                }
                
                oldDateFrom = scope.setup.dateFrom;
                oldDateTo = scope.setup.dateTo;
            }

            //- Event Handlers --------------------------------------------------------------

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

                    scope.constants.subchartData = angular.copy(scope.availableData);
                    scope.constants.subchartData.splice(0, 0, {
                        symbol: 'Same as main chart'
                    });

                    scope.symbolDateRange = DataService.getSymbolDateRange(scope.setup.symbol);
                } 
                else if (event == SQEvents.get('SETTINGS_TAB_RELOAD')) {
                    if (data == 'Data' || data == 'all') {
                        initialized = false;
                        scope.forceDateChange = true;
                    }
                } 
                else return;

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

            var destroySymbolWatch = scope.$watch("setup.symbol", function (newValue, oldValue) {
                if (initialized) {
                    if(newValue == null || newValue == 'null'){
                        scope.setup.symbol = '';
                        return;
                    }

                    DataService.changeSetupDetails(scope.setup, scope.precisions, oldValue);
                    scope.symbolDateRange = DataService.getSymbolDateRange(scope.setup.symbol);
                    scope.settingsChanged();

                } else {
                    $timeout(init, 0, false);
                }
            });
            
            var destroySubchartsWatch = scope.$watch("setup.subcharts", function (newValue, oldValue) {
                if (initialized) {
                    DataService.correctSubcharts(scope.setup);
                } 
            }, true);
            
            var destroySymbolDataRangeWatch = scope.$watch("symbolDateRange", function (newValue, oldValue) {
                if (valueFilled(newValue) && newValue != "N/A"){
                    var dates = scope.symbolDateRange.split(" - ");
                    if (dates.length == 2) {
                        scope.symbolDateRangeFrom = dates[0];
                        scope.symbolDateRangeTo = dates[1];
                    }
                    else {
                        var defaultDate = getDateString(new Date(0));
                        scope.symbolDateRangeFrom = defaultDate;
                        scope.symbolDateRangeTo = defaultDate;
                    }
                }
            });

            scope.$on("$destroy", function () {
                destroySymbolWatch();
                destroySymbolDataRangeWatch();
                destroySubchartsWatch();

                SQEvents.removeListener(listenerId);
                UniqueIdGenerator.removeId(scope.id);
            });

            //- Initialization --------------------------------------------------------------

            var initialized = false;
            var oldDateFrom, oldDateTo;

            var curCommissionType;

            scope.id = UniqueIdGenerator.generateId();

            scope.constants = angular.copy(SQConstants.getConstants());
            scope.precisions = scope.constants.precisions;
            scope.symbolDateRange = "N/A";
            
            scope.forceDateChange = false;
            scope.availableData = [];

            scope.commPGInstance = {};
            scope.commissionMethods = DataService.commissionMethods;

            scope.isAutoRetest = AppService.getTask().type == "AutomaticRetest";

            loadAvailableData();
            init(); 
            
            var listenerId = "ChartSetupSimple-" + scope.id;
            SQEvents.addListener(listenerId, [
                SQEvents.get('DATA_CHANGED'), 
                SQEvents.get('SETTINGS_TAB_RELOAD')
            ], onEvent);
        }
    };
});

/**
 * Commission settings are saved as an xml string of property grid config in setup.commissions object
 */