classdef (Hidden) AbstractData < handle
    % Abstract Data Class for Model Reduction App
    
    % Author(s): Suat Gumussoy
    % Copyright 2015 The MathWorks, Inc. 
    
    properties(Access = protected, SetObservable = true, AbortSet = true)
        % struct with fieldnames System and Name
        Target
        TargetFrequencyRange
        % struct array with fieldnames System and Name
        TargetList
    end   
    methods (Access = public)        
        %% Constructor
        function this = AbstractData(Target,TargetList)
            setTarget(this,Target);
            setTargetList(this,TargetList);     
        end
        %% Targets
        function setTarget(this,Target)
            if ~isequal(this.Target,Target)
                if isa(Target,'mrtool.data.ModelWrapper')
                    % single target is accepted
                    Target = mrtool.util.setSingleTarget(Target);
                    % prescale the system
                    Target.LTI = prescale(ss(Target.LTI));
                    % for tab and plots, frequency range is required
                    this.TargetFrequencyRange = mrtool.data.AbstractData.computeTargetFrequencyRange(Target.System);
                    if isempty(this.Target)
                        this.Target = Target;
                    else
                        this.Target = Target;
                        if ~this.isUsedInEmbeddedApps()
                            update(this);
                        end
                    end
                else
                    error(message('Control:mrtool:ErrorTarget'));
                end                
            end
        end
        function setTargetList(this,TargetList)
            if ~( isa(TargetList,'mrtool.data.ModelWrapper') && isvector(TargetList) )
                error(message('Control:mrtool:ErrorTargetList'));
            end            
            this.TargetList = TargetList;
        end
        function Target = getTarget(this)
            Target = this.Target;
        end            
        function TargetList = getTargetList(this)
            TargetList = this.TargetList;
        end
        function TargetListSystem = getTargetListSystem(this)
            TargetListSystem = {this.getTargetList.System};            
        end
        function TargetSystem = getTargetSystem(this)
            TargetSystem = this.Target.System;
        end           
        function Name = getTargetName(this)
            Name = this.getTarget.Name;
        end
        function Names = getTargetListName(this)
            Names = {this.getTargetList.Name};
        end
        function Range = getTargetFrequencyRange(this)
            Range = this.TargetFrequencyRange;
        end
    end
    methods (Static)
        function Range = computeTargetFrequencyRange(Target)
            [~,~,w] = bode(Target);
            Range = [w(1) w(end)];
        end        
    end
end
