classdef (Hidden) BalancedTruncationTabMLOnline < mrtool.tabs.AbstractToolTabMLOnline
    % Balanced Truncation Tab of Model Reduction App
    % compatible with MATLAB Online    
    
    % Author(s): Suat Gumussoy
    % Copyright 2016 The MathWorks, Inc.    
    
    properties (Access=protected)
        OptionsDialog        
    end
    
    methods
        function this = BalancedTruncationTabMLOnline(ToolData,ToolPlot,ParentToolGroup)
            TabName = 'BalancedTruncationTab';
            TabTitle = getString(message('Control:mrtool:BalancedTruncationTab'));
            this = this@mrtool.tabs.AbstractToolTabMLOnline(ToolData,ToolPlot,ParentToolGroup,TabName,TabTitle);
            update(this);
        end
        function update(this)
            update@mrtool.tabs.AbstractToolTabMLOnline(this);
            %% Balanced truncation
            % textfield reduced order
            Widgets = this.Widgets.BalancedTruncationSection;
            Widgets.OrderTextField.Value = mrtool.util.convertNum2Str(this.ToolData.getReducedOrder);
            % checkbox dc gain
            Widgets.DCGainCheckBox.Value = this.ToolData.getPreserveDCGain;
            % checkbox freq range
            Widgets.FreqRangeCheckBox.Value = this.ToolData.isFrequencyRangeSelected;
            % textfield freq range
            Widgets.FreqRangeTextField.Enabled = this.ToolData.isFrequencyRangeSelected;
            Widgets.FreqRangeTextField.Editable = this.ToolData.isFrequencyRangeSelected;
            Widgets.FreqRangeTextField.Value = mrtool.util.convertNum2Str(this.ToolData.getFrequencyRange); 
        end
    end
    methods (Access=protected)
        function createWidgets(this)
            import matlab.ui.internal.toolstrip.*
            createWidgets@mrtool.tabs.AbstractToolTabMLOnline(this,'BT');            
            %% BALANCED TRUNCATION SECTION
            % Strings
            BalancedTruncationSectionStr = getString(message('Control:mrtool:BalancedTruncationSection'));
            OrderStr = sprintf('%s:',getString(message('Control:mrtool:OrderLabel')));
            OrderTooltip = getString(message('Control:mrtool:OrderTooltip'));
            DCGainStr = getString(message('Control:mrtool:DCGainLabel'));
            DCGainTooltip = getString(message('Control:mrtool:DCGainTooltip'));
            FreqRangeStr = sprintf('%s:',getString(message('Control:mrtool:FreqRangeLabel')));
            FreqRangeCheckTooltip = getString(message('Control:mrtool:FreqRangeCheckTooltip'));
            FreqRangeTooltip = getString(message('Control:mrtool:FreqRangeTooltip'));
            
            %% Section
            BalancedTruncationSection = Section(BalancedTruncationSectionStr);
            BalancedTruncationSection.Tag = 'BalancedTruncationSection';
            % Column1
            column1 = Column('HorizontalAlignment','right');
            add(BalancedTruncationSection,column1);
            % order label                                                                                   
            OrderLabel = Label(OrderStr);
            add(column1,OrderLabel);  
            % dc checkbox
            DCGainCheckBox = CheckBox(DCGainStr,true);            
            DCGainCheckBox.Description = DCGainTooltip;
            add(column1,DCGainCheckBox);
            % freq checkbox
            FreqRangeCheckBox = CheckBox(FreqRangeStr,false);
            FreqRangeCheckBox.Description = FreqRangeCheckTooltip;
            add(column1,FreqRangeCheckBox);            
            % Column2
            column2 = Column('Width',60);
            add(BalancedTruncationSection,column2);
            % order textfield
            OrderTextField = EditField('5:10');
            OrderTextField.Description = OrderTooltip; 
            add(column2,OrderTextField); 
            % empty
            column2.addEmptyControl();
            % freq textfield
            FreqRangeTextField = EditField('[1 100]');
            FreqRangeTextField.Editable = false;
            FreqRangeTextField.Enabled = false;
            FreqRangeTextField.Description = FreqRangeTooltip;
            add(column2,FreqRangeTextField);
            
            % Store widgets
            this.Widgets.BalancedTruncationSection =  struct(...
                'OrderLabel',OrderLabel,...
                'OrderTextField',OrderTextField,...
                'DCGainCheckBox',DCGainCheckBox,...
                'FreqRangeCheckBox',FreqRangeCheckBox,...
                'FreqRangeTextField',FreqRangeTextField, ...
                'Section',BalancedTruncationSection);                                                                                                    
            
            %% OPTIONS SECTION
            % Strings
            OptionsSectionStr = getString(message('Control:mrtool:OptionsSection'));
            OptionsStr = getString(message('Control:mrtool:Options'));
            OptionsTooltip = getString(message('Control:mrtool:BalancedTruncationOptionsTooltip'));
            % Icon
            OptionsIcon = Icon.SETTINGS_24;
            
            % Section and column
            OptionsSection = Section(OptionsSectionStr);
            OptionsSection.Tag = 'OptionsSection';
            column = Column();
            add(OptionsSection,column);
            % Button                        
            OptionsButton = Button(OptionsStr,OptionsIcon);
            OptionsButton.Description = OptionsTooltip;
            add(column,OptionsButton);
            
            this.Widgets.OptionsSection =  struct(...
                'OptionsButton',OptionsButton,...
                'Section', OptionsSection);   
            
            %% ADD SECTIONS
            add(this.Tab,this.Widgets.SystemSection.Section);
            add(this.Tab,this.Widgets.BalancedTruncationSection.Section);
            add(this.Tab,this.Widgets.VisualizationsSection.Section);  
            add(this.Tab,this.Widgets.OptionsSection.Section);
            add(this.Tab,this.Widgets.CreateSection.Section);
        end
        function addListeners(this)
            addListeners@mrtool.tabs.AbstractToolTabMLOnline(this);
            %% Balanced truncation
            Widgets = this.Widgets.BalancedTruncationSection;
            addlistener(Widgets.OrderTextField, ...
                'ValueChanged', @(es,ed) mrtool.util.setTextFieldValue(this,this.ToolData,@(x,y) setReducedOrder(x,y),@(x) update(x),ed.EventData.NewValue,this.ParentToolGroup));
            addlistener(Widgets.DCGainCheckBox, ...
                'ValueChanged', @(es,ed) setPreserveDCGain(this.ToolData,ed.EventData.NewValue));
            addlistener(Widgets.FreqRangeCheckBox, ...
                'ValueChanged', @(es,ed) setFrequencyRangeSelected(this,ed.EventData.NewValue));             
            addlistener(Widgets.FreqRangeTextField, ...
                'ValueChanged', @(es,ed) mrtool.util.setTextFieldValue(this,this.ToolData,@(x,y) setFrequencyRange(x,y),@(x) update(x),ed.EventData.NewValue,this.ParentToolGroup));
            %% Options
            addlistener(this.Widgets.OptionsSection.OptionsButton,'ButtonPushed', @(es,ed) openOptionsDialog(this));                                             
        end     
        %% Callback functions 
        % balanced truncation widgets     
        function setFrequencyRangeSelected(this,Selection)
            this.ToolData.setFrequencyRangeSelected(Selection)
            Widgets = this.Widgets.BalancedTruncationSection;
            Widgets.FreqRangeTextField.Enabled = Selection;
            Widgets.FreqRangeTextField.Editable = Selection;
        end
        % options button
        function openOptionsDialog(this)
            if isempty(this.OptionsDialog) || ~isvalid(this.OptionsDialog)
                this.OptionsDialog = mrtool.dialogs.BalancedTruncationOptionsDialog(this.ToolData,this.Widgets.OptionsSection.OptionsButton,this.ParentToolGroup);
                this.Widgets.OptionsSection.OptionsDialog = this.OptionsDialog;
            end
            showTearOffDialog(this.Widgets.OptionsSection.OptionsButton,getDialog(this.OptionsDialog),true);
            updateUI(this.OptionsDialog);
        end 
        function cbSelectorMoved(this,~,ed)
            switch ed.Data.Status
                case 'InProgress'
                    this.Widgets.BalancedTruncationSection.FreqRangeTextField.Editable = false;
                    this.Widgets.BalancedTruncationSection.FreqRangeTextField.Value = mrtool.util.convertNum2Str(ed.Data.Range);                     
                case 'Finished'
                    this.Widgets.BalancedTruncationSection.FreqRangeTextField.Editable = true;
                    this.Widgets.BalancedTruncationSection.FreqRangeTextField.Value = mrtool.util.convertNum2Str(ed.Data.Range);                                         
            end                       
        end
    end
end

