classdef (Hidden,Sealed) UIARIMAXParameterDialog < internal.EconModeler.Dialogs.UIModelParameterDialog
    %UIARIMAXPARAMETERDIALOG  Dialog for creating ARIMAX Models in the
    %econModeler App
    
    %Copyright 2017-2019 The MathWorks Inc.
    
    properties(Access = protected)
        Title = getString(message('econ:econModeler:ARIMAXModelTitle'));
        ModelType = internal.EconModeler.Enumerations.ModelTypes.ARIMAX;
        NeedsTypeTabs = true;
        NeedsNonSeasonalPanel = true;
        NeedsSeasonalPanel = false;
        NeedsIntegration = true;
        NeedsAR = true;
        NeedsMA = true;
        NeedsConstant = true;
        NeedsSeasonal = false;
        NeedsPredictors = true;
        NeedsGARCH = false;
        NeedsARCH = false;
        NeedsLeverage = false;
        NeedsOffset = false;
    end
    
    methods(Access = ?internal.EconModeler.DialogFactory)
        function this = UIARIMAXParameterDialog(session,source)
            
            %Error out if there is only one time series in the app
            allTS = session.getAllTimeSeries();
            if length(allTS) <= 1
                error(message('econ:econModeler:ARIMAXMultipleTSRequired'));
            end
            
            this = this@internal.EconModeler.Dialogs.UIModelParameterDialog(session,source);
            
            if isa(source,'internal.EconModeler.EconComponents.AbstractModel')
                %Use old model "source" to fill in the controls
                switch source.DefiningTab
                    case 'Order'
                        this.NonSeasonalAROrderSpinner.Value = length(source.ARLags);
                        this.setARVector;
                        this.NonSeasonalMAOrderSpinner.Value = length(source.MALags);
                        this.setMAVector;
                        this.TypeTabGroup.SelectedTab = this.OrderTab;
                    case 'Vector'
                        this.NonSeasonalARVectorEdit.Value = this.lags2ModifyString(source.ARLags);
                        this.NonSeasonalMAVectorEdit.Value = this.lags2ModifyString(source.MALags);
                        this.TypeTabGroup.SelectedTab = this.VectorTab;
                end
                this.OrderDegreeIntegrationSpinner.Value = source.DegreeIntegration;
                this.VectorDegreeIntegrationSpinner.Value = source.DegreeIntegration;
                this.OrderConstantCheckBox.Value = isnan(source.Constant);
                this.VectorConstantCheckBox.Value = isnan(source.Constant);
                
                predictors = {source.Parent(2:end).Name};
                [~,indicesToSelect] = intersect(this.PredictorTable.Data(:,2),predictors);
                this.PredictorTable.Data(indicesToSelect,1) = {true};
                
                this.InnovationDropDown.Value = source.Distribution;
                this.setModelEquation();
            end
        end
    end
    
     methods(Access = protected)
        function arrangeComponents(this)
            %Position and set visibility for all relevant components
            this.Figure.Position = [100 100 706 464];
            
            this.TypeTabGroup.Visible = 'on';
            this.TypeTabGroup.Layout.Column = [1 2];
            
            this.OrderGrid.RowHeight = {20,20,20,'fit'};
            this.OrderGrid.ColumnWidth = {'1x','fit','fit','1x'};
            
            this.NonSeasonalAROrderLabel.Visible = 'on';
            this.NonSeasonalAROrderLabel.Parent = this.OrderGrid;
            this.NonSeasonalAROrderLabel.Layout.Row = 1;
            this.NonSeasonalAROrderLabel.Layout.Column = 2;
            
            this.NonSeasonalAROrderSpinner.Visible = 'on';
            this.NonSeasonalAROrderSpinner.Parent = this.OrderGrid;
            this.NonSeasonalAROrderSpinner.Layout.Row = 1;
            this.NonSeasonalAROrderSpinner.Layout.Column = 3;
            
            this.OrderDegreeIntegrationLabel.Visible = 'on';
            this.OrderDegreeIntegrationLabel.Parent = this.OrderGrid;
            this.OrderDegreeIntegrationLabel.Layout.Row = 2;
            this.OrderDegreeIntegrationLabel.Layout.Column = 2;
            
            this.OrderDegreeIntegrationSpinner.Visible = 'on';
            this.OrderDegreeIntegrationSpinner.Parent = this.OrderGrid;
            this.OrderDegreeIntegrationSpinner.Layout.Row = 2;
            this.OrderDegreeIntegrationSpinner.Layout.Column = 3;
            
            this.NonSeasonalMAOrderLabel.Visible = 'on';
            this.NonSeasonalMAOrderLabel.Parent = this.OrderGrid;
            this.NonSeasonalMAOrderLabel.Layout.Row = 3;
            this.NonSeasonalMAOrderLabel.Layout.Column = 2;
            
            this.NonSeasonalMAOrderSpinner.Visible = 'on';
            this.NonSeasonalMAOrderSpinner.Parent = this.OrderGrid;
            this.NonSeasonalMAOrderSpinner.Layout.Row = 3;
            this.NonSeasonalMAOrderSpinner.Layout.Column = 3;
            
            this.OrderConstantCheckBox.Visible = 'on';
            this.OrderConstantCheckBox.Parent = this.OrderGrid;
            this.OrderConstantCheckBox.Layout.Row = 4;
            this.OrderConstantCheckBox.Layout.Column = [2 3];
            
            this.VectorGrid.RowHeight = {20,20,20,'fit'};
            
            this.NonSeasonalARVectorLabel.Visible = 'on';
            this.NonSeasonalARVectorLabel.Parent = this.VectorGrid;
            this.NonSeasonalARVectorLabel.Layout.Row = 1;
            this.NonSeasonalARVectorLabel.Layout.Column = 2;
            
            this.NonSeasonalARVectorEdit.Visible = 'on';
            this.NonSeasonalARVectorEdit.Parent = this.VectorGrid;
            this.NonSeasonalARVectorEdit.Layout.Row = 1;
            this.NonSeasonalARVectorEdit.Layout.Column = 3;
            
            this.VectorDegreeIntegrationLabel.Visible = 'on';
            this.VectorDegreeIntegrationLabel.Parent = this.VectorGrid;
            this.VectorDegreeIntegrationLabel.Layout.Row = 2;
            this.VectorDegreeIntegrationLabel.Layout.Column = 2;
            
            this.VectorDegreeIntegrationSpinner.Visible = 'on';
            this.VectorDegreeIntegrationSpinner.Parent = this.VectorGrid;
            this.VectorDegreeIntegrationSpinner.Layout.Row = 2;
            this.VectorDegreeIntegrationSpinner.Layout.Column = 3;
            
            this.NonSeasonalMAVectorLabel.Visible = 'on';
            this.NonSeasonalMAVectorLabel.Parent = this.VectorGrid;
            this.NonSeasonalMAVectorLabel.Layout.Row = 3;
            this.NonSeasonalMAVectorLabel.Layout.Column = 2;
            
            this.NonSeasonalMAVectorEdit.Visible = 'on';
            this.NonSeasonalMAVectorEdit.Parent = this.VectorGrid;
            this.NonSeasonalMAVectorEdit.Layout.Row = 3;
            this.NonSeasonalMAVectorEdit.Layout.Column = 3;
            
            this.VectorConstantCheckBox.Visible = 'on';
            this.VectorConstantCheckBox.Parent = this.VectorGrid;
            this.VectorConstantCheckBox.Layout.Row = 4;
            this.VectorConstantCheckBox.Layout.Column = [2 3];
            
            this.PredictorPanel.Visible = 'on';
            this.PredictorPanel.Layout.Row = 1;
            this.PredictorPanel.Layout.Column = 3;
            
            %Fill the predictor list with all time series other than the
            %selected one
            allTS = this.Session.getAllTimeSeries();
            selectedTS = this.TimeSeries;
            tsToSelect = allTS(allTS ~= selectedTS); 
            this.PredictorTable.Visible = 'on';
            this.PredictorTable.Data = [num2cell(false(length(tsToSelect),1)),{tsToSelect(:).Name}'];
%             this.PredictorTable.Position = [0 0 this.PredictorPanel.InnerPosition(3) this.PredictorPanel.InnerPosition(4)-5];
% 
%             
%             this.ModelEqAxes.Position = [17 48 670 170];
%             
%             this.InnovationLabel.Position = [17 17 127 15];
%             this.InnovationDropDown.Position = [159 13 100 22];
%             this.DetailsButton.Position = [373 13 100 22];
%             this.EstimateButton.Position = [484 13 100 22];
%             this.CancelButton.Position = [595 13 100 22];
        end
        
        function str = getEquation(this,p)
           try
               %Build ARIMAX Equation
               str = "y_{t} = ";
               str = "$$" + this.getARString(p) + this.getDegreeString() + ...
                   str + this.getConstantString() + this.getPredictorString() +...
                   this.getMAString(p) + "\varepsilon_{t}$$";
           catch 
                %Display message if this fails
                str = getString(message('econ:econModeler:InvalidEquation'));
           end
        end
        
        function requestEstimate(this,~,~)
            try
                params = this.getParameters;
            catch ME
                uialert(this.Figure,ME.message,...
                    getString(message('econ:econModeler:AppTitle')),...
                    'Icon','error','Modal',true);
                return;
            end
            if isempty(params.Exogenous)
                uialert(this.Figure,getString(message('econ:econModeler:NoPredictors')),...
                    getString(message('econ:econModeler:AppTitle')),...
                    'Icon','error','Modal',true);
                return;
            end
            requestEstimate@internal.EconModeler.Dialogs.UIModelParameterDialog(this);
        end
       
        function launchHelp(~,~,~)
            helpview('econ','arimax_topic');
        end
    end
end

