classdef ControllerDesignPanelBasic < pidtool.AbstractControllerDesignPanel
    % @ControllerDesignPanelBasic subclass

    % Author(s): R. Chen
    % Copyright 2009-2010 The MathWorks, Inc.
    
    methods
        
        %% Constructor
        function this = ControllerDesignPanelBasic(varargin)
            this = this@pidtool.AbstractControllerDesignPanel(varargin{:});
        end
        
        %% Update GUI components without firing event
        % set crossover spinner value without firing event
        function setWCSpinnerValue(this)
            newRT = this.getRTFromWC;
            this.localSetWCSpinnerValue(newRT);
        end

        % set crossover text field value without firing event
        function setWCTextFieldValue(this)
            newRT = this.getRTFromWC;
            this.Handles.CrossoverTextField.setText(sprintf('%0.3g %s',newRT,this.TimeUnitString));    
            javaMethodEDT('setDot',this.Handles.CrossoverTextField.getCaret(),0); % reset cursor to left
        end
        
        % set phase margin spinner value without firing event
        function setPMSpinnerValue(this)
            newWeight = this.getWeightFromPM;
            this.localSetPMSpinnerValue(newWeight);
        end
        
        % set phase margin text field value without firing event
        function setPMTextFieldValue(this)
            newWeight = this.getWeightFromPM;
            this.Handles.PhaseMarginTextField.setText(sprintf('%0.2g',newWeight));    
            javaMethodEDT('setDot',this.Handles.PhaseMarginTextField.getCaret(),0); % reset cursor to left
        end
        
        % refresh crossover slider labels
        function refreshCrossoverSliderLabel(this) %#ok<MANU>
            % no op for time domain
        end
        
        % compute response time from current crossover
        function RT = getRTFromWC(this)
            % response time = 2/WC
            RT = 2/this.WC;
        end
        
        % compute crossover from current response time
        function WC = getWCFromRT(this, RT) %#ok<INUSL>
            % WC = 2/response time
            WC = 2/RT;
        end
        
        % compute weight from current phase margin
        function Weight = getWeightFromPM(this)
            % 0 <-- 0 deg, 0.9 <-- 90 deg, with 0.01 increment
            Weight = this.PM/100; 
        end
        
        % compute phase margin from current weight
        function PM = getPMFromWeight(this, Weight) %#ok<INUSL>
            % 0 deg <-- 0, 90 deg <-- 0.9, with 1 increment
            PM = round(Weight*100);
        end
        
    end

    methods (Access = protected)

        %% Build
        function build(this)
            % super
            build@pidtool.AbstractControllerDesignPanel(this);
            % row 1 - WC label
            this.Handles.CrossoverLabel.setName('PIDTUNER_RESPTIMELABEL');
            this.Handles.CrossoverLabel.setText(pidtool.utPIDgetStrings('cst','tunerdlg_respslider'));
            pidtool.utPIDaddCSH('control',this.Handles.CrossoverLabel,'pidtuner_responsespeed');
            % row 2 - WC slider
            this.Handles.SlowButton.setName('PIDTUNER_SLOWBUTTON');
            this.Handles.SlowButton.setToolTipText(pidtool.utPIDgetStrings('cst','slowbutton_tooltip'));
            this.Handles.FastButton.setName('PIDTUNER_FASTBUTTON');            
            this.Handles.FastButton.setToolTipText(pidtool.utPIDgetStrings('cst','fastbutton_tooltip'));            
            this.Handles.CrossoverSlider.setName('PIDTUNER_RESPTIMESLIDER');
            LabelSlower = javaObjectEDT('com.mathworks.mwswing.MJLabel',pidtool.utPIDgetStrings('cst','tunerdlg_respslider_left'));
            LabelFaster = javaObjectEDT('com.mathworks.mwswing.MJLabel',pidtool.utPIDgetStrings('cst','tunerdlg_respslider_right'));
            labelTableCrossover = java.util.Hashtable;
            labelTableCrossover.put(java.lang.Integer(0),LabelSlower);
            labelTableCrossover.put(java.lang.Integer(100),LabelFaster);
            this.Handles.CrossoverSlider.setLabelTable(labelTableCrossover);
            this.Handles.CrossoverSlider.setPaintLabels(true);
            % row 4 - WC spinner and text field
            this.Handles.CrossoverTextField.setName('PIDTUNER_RESPTIMETEXTFIELD');
            this.Handles.CrossoverSpinner.setName('PIDTUNER_RESPTIMESPINNER');
            % row 3 - PM label
            this.Handles.PhaseMarginLabel.setText(pidtool.utPIDgetStrings('cst','tunerdlg_transientslider'));
            this.Handles.PhaseMarginLabel.setName('PIDTUNER_TRANSIENTLABEL');
            pidtool.utPIDaddCSH('control',this.Handles.PhaseMarginLabel,'pidtuner_transient');
            % row 4 - PM slider
            this.Handles.PhaseMarginSlider.setName('PIDTUNER_TRANSIENTSLIDER');
            LabelAggressive = javaObjectEDT('com.mathworks.mwswing.MJLabel',pidtool.utPIDgetStrings('cst','tunerdlg_transientslider_left'),javax.swing.SwingConstants.RIGHT);
            LabelConservative = javaObjectEDT('com.mathworks.mwswing.MJLabel',pidtool.utPIDgetStrings('cst','tunerdlg_transientslider_right'));
            labelTablePhaseMargin = java.util.Hashtable;
            labelTablePhaseMargin.put(java.lang.Integer(0),LabelAggressive);
            labelTablePhaseMargin.put(java.lang.Integer(90),LabelConservative);
            this.Handles.PhaseMarginSlider.setLabelTable(labelTablePhaseMargin);
            this.Handles.PhaseMarginSlider.setPaintLabels(true);
            % row 4 - PM spinner and text field
            this.Handles.PhaseMarginSpinnerModel.setMinimum(java.lang.Double(0));
            this.Handles.PhaseMarginSpinnerModel.setMaximum(java.lang.Double(0.9));
            this.Handles.PhaseMarginSpinnerModel.setStepSize(java.lang.Double(0.01));
            this.Handles.PhaseMarginTextField.setName('PIDTUNER_TRANSIENTTEXTFIELD');
            this.Handles.PhaseMarginSpinner.setName('PIDTUNER_TRANSIENTSPINNER');
        end

        %% Callbacks
        % WC spinner
        function CrossoverSpinnerCallback(this)
            % get WC
            newWC = this.getWCFromRT(this.Handles.CrossoverSpinner.getValue);
            % update WC
            this.Property_Listeners(2).Enabled = false;
            this.WC = newWC;
            this.Property_Listeners(2).Enabled = true;
        end

        % WC editor
        function CrossoverEditorCallback(this)
            % get WC
            Editor = this.Handles.CrossoverTextField;
            newRT = str2double(strrep(char(Editor.getText),sprintf('%s',this.TimeUnitString),''));
            newWC = this.getWCFromRT(newRT);
            if isnan(newWC) || ~isscalar(newWC) || ~isreal(newWC) || newWC<this.MinWC || newWC>this.MaxWC || ~isfinite(newWC)
                this.setWCTextFieldValue;
                return
            end
            % update WC (need to send event to refresh unit)
            this.WC = newWC;
        end

        % PM spinner
        function PhaseMarginSpinnerCallback(this)
            % get PM 
            newPM = this.getPMFromWeight(this.Handles.PhaseMarginSpinner.getValue);
            % update PM
            this.Property_Listeners(5).Enabled = false;
            this.PM = newPM;    
            this.Property_Listeners(5).Enabled = true;
        end

        % PM editor
        function PhaseMarginEditorCallback(this)
            % get PM 
            Editor = this.Handles.PhaseMarginTextField;
            newPM = this.getPMFromWeight(str2double(char(Editor.getText))); 
            if isnan(newPM) || ~isscalar(newPM) || ~isreal(newPM) || newPM<0 || newPM>90 || ~isfinite(newPM)
                this.setPMTextFieldValue;
                return
            end
            % update PM (need to send event to refresh unit)
            this.PM = newPM;    
        end
        
    end
    
end
    
