classdef (Hidden) PoleZeroSimplificationData < mrtool.data.AbstractToolData
    % Pole/Zero Simplification Data Class for Pole/Zero Simplification Tool
    
    % Author(s): Suat Gumussoy
    % Copyright 2015 The MathWorks, Inc. 
    
    properties(Access = private, SetObservable = true, AbortSet = true)
        Tolerance = 1e-5;
    end
    methods (Access = public)
        %% Constructor
        function this = PoleZeroSimplificationData(Target,TargetList)
            this = this@mrtool.data.AbstractToolData(Target,TargetList);
            setDirty(this,false);
        end
        function setToolTarget(this,ToolTarget)
            Target = mrtool.util.setSingleTarget(ToolTarget);
            setTarget(this,Target);
        end        
        %% Update the tab with new target
        function update(this)
            computeReducedSystem(this);
        end 
        %% Get/Set functions for data
        %% Pole/Zero Simplificaton Settings
        function Tol = getTolerance(this)
            Tol = this.Tolerance;
        end        
        function setTolerance(this,Tol)
            if (isnumeric(Tol) && isreal(Tol) && isscalar(Tol) && isfinite(Tol) && all(Tol>0) && (Tol<=1)) 
                    if ~isequal(getTolerance(this),Tol)
                        this.Tolerance = Tol;
                        computeReducedSystem(this);
                    end               
            else
                error(message('Control:mrtool:ErrorTol'));
            end
        end       
        % Options
        function setOptions(this,~)
            % no options for pole/zero simplification
            this.Options=[];
        end
        %% Load/Save Session
        function loadSessionToolData(this,SessionData)
            this.Tolerance = SessionData.Tolerance; 
            setVisualizations(this,SessionData.Visualizations)
            computeReducedSystem(this,true);
        end        
        function SessionData = saveSessionToolData(this,SessionData)
            SessionData.ToolType = 'PoleZeroSimplification';
            SessionData.Tolerance = getTolerance(this);
        end        
    end
    methods (Access = protected)        
        %% Reduced System
        function ReducedSystem = localComputeReducedSystem(this)
            TargetSystem = getTargetSystem(this);
            Options = getOptions(this);            
            % REVISIT: send the message from minreal to status bar
            ReducedSystem = minreal(TargetSystem,this.Tolerance,false);
        end
    end
    methods (Static)
        function Result = isCutoffValid(Cutoff)
            Result = ~isempty(Cutoff) && (isnumeric(Cutoff) && isscalar(Cutoff) && isreal(Cutoff) ... 
                    && Cutoff>0 && Cutoff<Inf);
        end
    end
    methods(Hidden=true)
        function Text = generateMATLABCode(this)
            Text = cell(0,1);            
            Text = controllib.internal.codegen.appendMATLABCode(Text,['%% ' getString(message('Control:mrtool:CodegenPZTitle'))]); 
            SystemName = sprintf('System = prescale(%s);',ltipack.createVarName(getTargetName(this)));
            Text = controllib.internal.codegen.appendMATLABCode(Text,SystemName,[],getString(message('Control:mrtool:CodegenSystem')));
            Text = controllib.internal.codegen.appendMATLABCode(Text,getTolerance(this),'Tol',getString(message('Control:mrtool:CodegenPZTolerance')));
            Text = controllib.internal.codegen.appendMATLABCode(Text,' ');
            Text = controllib.internal.codegen.appendMATLABCode(Text,['% ' getString(message('Control:mrtool:CodegenPZReduceCommand'))]);
            Text = controllib.internal.codegen.appendMATLABCode(Text,'ReducedSystem = minreal(System,Tol);');
            Text = controllib.internal.codegen.appendMATLABCode(Text,' ');
            Text = controllib.internal.codegen.appendMATLABCode(Text,['% ' getString(message('Control:mrtool:CodegenCreatePlot'))]);
            Text = controllib.internal.codegen.appendMATLABCode(Text,'bode(System,ReducedSystem);');
            controllib.internal.codegen.showGeneratedMATLABCode(Text,false);            
        end        
    end
end