classdef(Hidden,Sealed) UIGJRParameterDialog < internal.EconModeler.Dialogs.UIModelParameterDialog
    %UIGJRPARAMETERDIALOG Dialog for creating GJR Models in the
    %econModeler App
    
    %Copyright 2017-2019 The MathWorks Inc.
    
    properties(Access = protected)
        Title = getString(message('econ:econModeler:GJRModelTitle'));
        ModelType = internal.EconModeler.Enumerations.ModelTypes.GJR;
        NeedsTypeTabs = true;
        NeedsNonSeasonalPanel = true;
        NeedsSeasonalPanel = false;
        NeedsIntegration = false;
        NeedsAR = false;
        NeedsMA = false;
        NeedsConstant = false;
        NeedsSeasonal = false;
        NeedsPredictors = false;
        NeedsGARCH = true;
        NeedsARCH = true;
        NeedsLeverage = true;
        NeedsOffset = true;
    end
    
    methods (Access = ?internal.EconModeler.DialogFactory)
        function this = UIGJRParameterDialog(session,source)
            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.GARCHOrderSpinner.Value = length(source.GARCHLags);
                        this.setGARCHVector;
                        this.ARCHOrderSpinner.Value = length(source.ARCHLags);
                        this.setARCHLeverageVector;
                        this.TypeTabGroup.SelectedTab = this.OrderTab;
                    case 'Vector'
                        this.GARCHVectorEdit.Value = this.lags2ModifyString(source.GARCHLags);
                        this.ARCHVectorEdit.Value = this.lags2ModifyString(source.ARCHLags);
                        this.LeverageVectorEdit.Value = this.lags2ModifyString(source.LeverageLags);
                        this.TypeTabGroup.SelectedTab = this.VectorTab;
                end
                this.OrderOffsetCheckBox.Value = isnan(source.Offset);
                this.VectorOffsetCheckBox.Value = isnan(source.Offset);
                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 450 350];
            
            this.TypeTabGroup.Visible = 'on';
            this.TypeTabGroup.Layout.Column = [1 3];
            
            this.OrderGrid.RowHeight = {20 20 'fit'};
            
            this.ARCHOrderLabel.Visible = 'on';
            this.ARCHOrderLabel.Layout.Row = 1;
            this.ARCHOrderLabel.Layout.Column = 2;
            
            this.ARCHOrderSpinner.Visible = 'on';
            this.ARCHOrderSpinner.Layout.Row = 1;
            this.ARCHOrderSpinner.Layout.Column = 3;
            
            this.GARCHOrderLabel.Visible = 'on';
            this.GARCHOrderLabel.Layout.Row = 2;
            this.GARCHOrderLabel.Layout.Column = 2;
            
            this.GARCHOrderSpinner.Visible = 'on';
            this.GARCHOrderSpinner.Layout.Row = 2;
            this.GARCHOrderSpinner.Layout.Column = 3;
            
            this.OrderOffsetCheckBox.Visible = 'on';
            this.OrderOffsetCheckBox.Layout.Row = 3;
            this.OrderOffsetCheckBox.Layout.Column = [2 3];
            
            this.VectorGrid.RowHeight = {20 20 20 'fit'};
            
            this.ARCHVectorLabel.Visible = 'on';
            this.ARCHVectorLabel.Layout.Row = 1;
            this.ARCHVectorLabel.Layout.Column = 2;
            
            this.ARCHVectorEdit.Visible = 'on';
            this.ARCHVectorEdit.Layout.Row = 1;
            this.ARCHVectorEdit.Layout.Column = 3;
            
            this.GARCHVectorLabel.Visible = 'on';
            this.GARCHVectorLabel.Layout.Row = 2;
            this.GARCHVectorLabel.Layout.Column = 2;
            
            this.GARCHVectorEdit.Visible = 'on';
            this.GARCHVectorEdit.Layout.Row = 2;
            this.GARCHVectorEdit.Layout.Column = 3;
            
            this.LeverageVectorLabel.Visible = 'on';
            this.LeverageVectorLabel.Layout.Row = 3;
            this.LeverageVectorLabel.Layout.Column = 2;
            
            this.LeverageVectorEdit.Visible = 'on';
            this.LeverageVectorEdit.Layout.Row = 3;
            this.LeverageVectorEdit.Layout.Column = 3;
            
            this.VectorOffsetCheckBox.Visible = 'on';
            this.VectorOffsetCheckBox.Layout.Row = 4;
            this.VectorOffsetCheckBox.Layout.Column = [2 3];
         end
         
         function str = getEquation(this,p)
             try
                 %Build GJR equation
                 if ~isempty(string(p.garchLagEdit))
                     garchLags = this.lagStr2Num(p.garchLagEdit,this.GARCHVectorLabel.Text);
                 elseif this.TypeTabGroup.SelectedTab == this.OrderTab
                     garchLags = this.spinnerValue2Lags(this.GARCHOrderSpinner.Value,1,1,1);
                 else
                     garchLags = this.lagStr2Num(this.GARCHVectorEdit.Value,this.GARCHVectorLabel.Text);
                 end

                 if ~isempty(string(p.archLagEdit))
                     archLags = this.lagStr2Num(p.archLagEdit,this.ARCHVectorLabel.Text);
                 elseif this.TypeTabGroup.SelectedTab == this.OrderTab
                     archLags = this.spinnerValue2Lags(this.ARCHOrderSpinner.Value,1,1,1);
                 else
                     archLags = this.lagStr2Num(this.ARCHVectorEdit.Value,this.ARCHVectorLabel.Text);
                 end
                 
                 if ~isempty(string(p.leverageLagEdit))
                     leverageLags = this.lagStr2Num(p.leverageLagEdit,this.LeverageVectorLabel.Text);
                 elseif this.TypeTabGroup.SelectedTab == this.OrderTab
                     leverageLags = archLags;
                 else
                     leverageLags = this.lagStr2Num(this.LeverageVectorEdit.Value,this.LeverageVectorLabel.Text);
                 end
                 
                 if this.TypeTabGroup.SelectedTab == this.OrderTab
                     offset = this.OrderOffsetCheckBox.Value;
                 else
                     offset = this.VectorOffsetCheckBox.Value;
                 end
                 
                 str = "$$y_{t} = ";
                 if offset
                     str = str + "\mu + ";
                 end
                 str = str + "\varepsilon_{t}$$" + newline;
                 str = str + "$$\varepsilon_{t} = \sigma_{t}z_{t}$$" + newline;
                 
                 str = str + "$$";
                 if ~isempty(garchLags)
                     str = str + "(1-";
                     if length(garchLags) > 3
                         str = str + "\gamma_{" + num2str(min(garchLags)) + "}L";
                         if min(garchLags) ~= 1
                             str = str + "^{" + num2str(min(garchLags)) + "}";
                         end
                         str = str + "-...-\gamma_{" + num2str(max(garchLags)) + "}L^{" + num2str(max(garchLags)) + "})";
                     else
                         for n = 1:length(garchLags)
                             str = str + "\gamma_{" + num2str(garchLags(n)) + "}L";
                             if garchLags(n) ~= 1
                                 str = str + "^{" + num2str(garchLags(n)) + "}";
                             end
                             if n ~= length(garchLags)
                                 str = str+"-";
                             end
                         end
                         str = str + ")";
                     end
                 end
                 
                 str = str + "\sigma_{t}^{2} = \kappa";
                 
                 if ~isempty(archLags)
                     str = str + " + (";
                     if length(archLags) > 3
                         str = str + "\alpha_{" + num2str(min(archLags)) + "}L";
                         if min(archLags) ~= 1
                             str = str + "^{" + num2str(min(archLags)) + "}";
                         end
                         str = str + "+...+\alpha_{" + num2str(max(archLags)) + "}L^{" + num2str(max(archLags)) + "})";
                     else
                         for n = 1:length(archLags)
                             str = str + "\alpha_{" + num2str(archLags(n)) + "}L";
                             if archLags(n) ~= 1
                                 str = str + "^{" + num2str(archLags(n)) + "}";
                             end
                             if n ~= length(archLags)
                                 str = str+"+";
                             end
                         end
                         str = str + ")";
                     end
                     str = str + "\varepsilon_{t}^{2}";
                 end
                 
                 if ~isempty(leverageLags)
                     str = str + " + (";
                     if length(leverageLags) > 3
                         str = str + "\xi_{" + num2str(min(leverageLags)) + "}L";
                         if min(leverageLags) ~= 1
                             str = str + "^{" + num2str(min(leverageLags)) + "}";
                         end
                         str = str + "+...+\xi_{" + num2str(max(leverageLags)) + "}L^{" + num2str(max(leverageLags)) + "})";
                     else
                         for n = 1:length(leverageLags)
                             str = str + "\xi_{" + num2str(leverageLags(n)) + "}L";
                             if leverageLags(n) ~= 1
                                 str = str + "^{" + num2str(leverageLags(n)) + "}";
                             end
                             if n ~= length(leverageLags)
                                 str = str+"+";
                             end
                         end
                         str = str + ")";
                     end
                     str = str + "I[\varepsilon_{t}<0]\varepsilon_{t}^{2}";
                 end
                 
                 str = str + "$$";
             catch
                 %Display message if this fails
                 str = getString(message('econ:econModeler:InvalidEquation'));
             end
         end
         
         function launchHelp(~,~,~)
             helpview('econ','gjr_topic');
         end
    end
end

