classdef(Hidden,Sealed) UIRegARIMAParameterDialog < internal.EconModeler.Dialogs.UIModelParameterDialog
    %UIREGARIMAPARAMETERDIALOG Dialog for creating RegARIMA Models in the
    %econModeler App
    
    %Copyright 2017-2019 The MathWorks Inc.
    
    properties(Access = protected)
        Title = getString(message('econ:econModeler:RegARMAModelTitle'));
        ModelType = internal.EconModeler.Enumerations.ModelTypes.REGARIMA;
        NeedsTypeTabs = true;
        NeedsNonSeasonalPanel = true;
        NeedsSeasonalPanel = false;
        NeedsIntegration = false;
        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 = UIRegARIMAParameterDialog(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:RegARMAMultipleTSRequired'));
            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.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)
            %Postiion and set visibility for all relevant components
            this.Figure.Position = [100 100 650 400];
            
            this.TypeTabGroup.Visible = 'on';
            this.TypeTabGroup.Layout.Column = [1 2];
            
            this.OrderGrid.RowHeight = {20,20,'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.NonSeasonalMAOrderLabel.Visible = 'on';
            this.NonSeasonalMAOrderLabel.Parent = this.OrderGrid;
            this.NonSeasonalMAOrderLabel.Layout.Row = 2;
            this.NonSeasonalMAOrderLabel.Layout.Column = 2;
            
            this.NonSeasonalMAOrderSpinner.Visible = 'on';
            this.NonSeasonalMAOrderSpinner.Parent = this.OrderGrid;
            this.NonSeasonalMAOrderSpinner.Layout.Row = 2;
            this.NonSeasonalMAOrderSpinner.Layout.Column = 3;
            
            this.OrderConstantCheckBox.Visible = 'on';
            this.OrderConstantCheckBox.Parent = this.OrderGrid;
            this.OrderConstantCheckBox.Text = getString(message('econ:econModeler:IncludeIntercept'));
            this.OrderConstantCheckBox.Layout.Row = 3;
            this.OrderConstantCheckBox.Layout.Column = [2 3];
            
            this.VectorGrid.RowHeight = {20,20,'fit','1x'};
            
            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.NonSeasonalMAVectorLabel.Visible = 'on';
            this.NonSeasonalMAVectorLabel.Parent = this.VectorGrid;
            this.NonSeasonalMAVectorLabel.Layout.Row = 2;
            this.NonSeasonalMAVectorLabel.Layout.Column = 2;
            
            this.NonSeasonalMAVectorEdit.Visible = 'on';
            this.NonSeasonalMAVectorEdit.Parent = this.VectorGrid;
            this.NonSeasonalMAVectorEdit.Layout.Row = 2;
            this.NonSeasonalMAVectorEdit.Layout.Column = 3;
            
            this.VectorConstantCheckBox.Visible = 'on';
            this.VectorConstantCheckBox.Parent = this.VectorGrid;
            this.VectorConstantCheckBox.Text = getString(message('econ:econModeler:IncludeIntercept'));
            this.VectorConstantCheckBox.Layout.Row = 3;
            this.VectorConstantCheckBox.Layout.Column = [2 3];
            
            this.PredictorPanel.Visible = 'on';
            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}'];
        end
        
        function str = getEquation(this,p)
            try 
                %Build RegARIMA equation
                str = "$$y_{t} = " + this.getConstantString + this.getPredictorString() + "\mu_{t}$$" + newline;
                str = str + "$$" + this.getARString(p)+ "\mu_{t} = " + 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','regarima_topic');
        end
     end
end

