classdef CSDPortID < modelpack.PortID
    %modelpack.CSDPortID class
    %   modelpack.CSDPortID extends modelpack.PortID.
    %

%   Copyright 2023 The MathWorks, Inc.

    %    modelpack.CSDPortID properties:
    %       Description - Property is of type 'ustring'
    %
    %    modelpack.CSDPortID methods:
    %       getDimensions -  method to return Port dimension
    %       getFullName -  method to return Port full name. The full name is a
    %       getName -  method to return Port name
    %       getPath -  method to return Port path
    %       getType -  method to return Port type
    %       update -  method to set SISOTOOL model state object's


    properties (Access=protected, SetObservable)
        %DIMENSION Property is of type 'MATLAB array'
        Dimension = [];
        %NAME Property is of type 'string'
        Name = '';
        %PATH Property is of type 'ustring'
        Path = '';
        %PORTNUMBER Property is of type 'double'
        PortNumber = 1;
        %TYPE Property is of type 'string'
        Type = '';
    end


    methods  % constructor block
        function this = CSDPortID(Name,Dimension,Path,Type)
            % CSDPortID  constructor for SISOTOOL port object
            %
            % h = modelpack.CSDPortID(Name,Dimension,[Path],[Type])
            %
            % Inputs:
            %   Name      - string with port name
            %   Dimension - double vector with port dimensions
            %   Path      - string with path to port
            %   Type      - string with port type, valid types {'Input'|'Output'}
            %

            %Instantiate object

            % No argument constructor call
            if nargin == 0, return, end

            %Check number of arguments
            if nargin < 2 || nargin > 4
                error(message('SLControllib:modelpack:errNumArguments','5'))
            end

            %Default arguments
            if nargin < 3 || isempty(Path), Path = ''; end
            if nargin < 4 || isempty(Type), Type = 'Output'; end

            %Check input argument types
            if ~any(strcmpi({'Input','Output'},Type))
                error(message('SLControllib:modelpack:errArgumentType','Type','{''Input''|''Output''}'));
            end

            %Set properties
            this.Version    = 1.0;
            this.Name       = Name;
            this.Path       = Path;
            this.PortNumber = 1;
            this.Dimension  = Dimension;
            this.Type       = Type;

        end  % CSDPortID

    end  % constructor block

    methods
        function set.Name(obj,value)
            % DataType = 'string'
            validateattributes(value,{'char'}, {'row'},'','Name')
            obj.Name = value;
        end

        function set.Path(obj,value)
            % DataType = 'ustring'
            % no cell string checks yet'
            obj.Path = value;
        end

        function set.PortNumber(obj,value)
            % DataType = 'double'
            validateattributes(value,{'numeric'}, {'scalar'},'','PortNumber')
            value = double(value); %  convert to double
            obj.PortNumber = value;
        end

        function set.Type(obj,value)
            % DataType = 'string'
            validateattributes(value,{'char'}, {'row'},'','Type')
            obj.Type = value;
        end

    end   % set and get functions

    methods  % public methods
        function Dim = getDimensions(this)
            % GETDIMENSIONS  method to return Port dimension
            %

            if numel(this) == 1
                Dim = this.Dimension;
            else
                Dim = {this.Dimension};
                Dim = reshape(Dim,size(this));
            end

        end  % getDimensions

        function FullName = getFullName(this)
            % GETFULLNAME  method to return Port full name. The full name is a
            % concatenation of the Port path and Port name
            %

            name = this.getName;      %Use method as name is constructed
            %Check whether path is empty, if not tag a '/' on end to separate path and
            %name
            if numel(this) == 1
                path = this.Path;
                if ~isempty(path)
                    path = strcat(path,'/');
                end
            else
                path = {this.Path};
                path = reshape(path,size(this));
                idx = ~cellfun('isempty',path);
                if any(idx)
                    %Path is not empty, append path separator
                    tmp = strcat(path(idx),'/');
                    [path{idx}] = deal(tmp{:});
                end
            end
            
            %Form full name
            FullName = strcat(path,name);

        end  % getFullName

        function Name = getName(this)
            % GETNAME  method to return Port name
            %

            if numel(this) == 1
                Name = this.Name;
            else
                Name = {this.Name};
                Name = reshape(Name,size(this));
            end

            Name = strcat(Name,':');
            if numel(this) > 1
                pnum = {this.PortNumber};
                pnum = reshape(pnum,size(this));
                Name = strcat(Name,cellfun(@num2str,pnum,'UniformOutput',false));
            else
                Name = sprintf('%s%d',Name,this.PortNumber);
            end

        end  % getName

        function Path = getPath(this)
            % GETPATH  method to return Port path
            %

            if numel(this) == 1
                Path = this.Path;
            else
                Path = {this.Path};
                Path = reshape(Path,size(this));
            end

        end  % getPath

        function Type = getType(this)
            % GETTYPE  method to return Port type
            %

            if numel(this) == 1
                Type = this.Type;
            else
                Type = {this.Type};
                Type = reshape(Type,size(this));
            end

        end  % getType

        function update(~,Model,varargin)
            % UPDATE  method to set SISOTOOL model state object's
            % properties.
            %
            % this.update(Model,'varargin')
            %
            % Input:
            %   Model    - a SISOTOOL model object that contains the parameter being
            %              updated
            %   varargin - a variable list of property value pairs or structure with
            %              fields to set
            %
            % As SISOTOOL ports cannot be changed this method
            % is a no-op, but is required for consistency with the model API.
            %

            %Check input argument types
            if ~isa(Model,'modelpack.CSDModel')
                error(message('SLControllib:modelpack:errArgumentType','Model','modelpack.CSDModel'))
            end

        end  % update

    end  % public methods

end  % classdef

% LocalWords:  PORTNUMBER GETDIMENSIONS
