classdef GroupsFrameConfig < matlab.mixin.CustomDisplay
%GROUPSFRAMECONFIG Configuration for frames of the Groups ZigBee cluster
% FRAMECONFIG = GROUPSFRAMECONFIG creates a configuration object for frames
% of the Groups ZigBee cluster.
%
% FRAMECONFIG = GROUPSFRAMECONFIG(Name, Value) creates a ZigBee Groups
% cluster frame configuration object with the specified property Name set
% to the specified Value. You can specify additional name-value pair
% arguments in any order as (Name1, Value1, ..., NameN, ValueN).
%
% GroupsFrameConfig properties:
%
% CommandType   - Command type
% GroupID       - Group identifier
% GroupName     - Group name
% GroupCount    - Size of group list
% GroupList     - List of group identifiers
% Status        - Status of Add/View/Remove Group commands
% Capacity      - Number of free group slots
%
% See also zigbee.GroupsFrameGenerator, zigbee.GroupsFrameDecoder.

% Copyright 2017-2023 The MathWorks, Inc.

properties
  %CommandType Command type
  % Specify CommandType as one of  'Add group' | 'View group' |
  % 'Get group membership' | 'Remove group' | 'Remove all groups' |
  % 'Add group if identifying' | 'Add group response' | 'Remove group response' |
  % 'View group response' | 'Get group membership response'.
  % The default is 'Add group'.
  CommandType = 'Add group';

  %GroupID Group identifier
  % Specify GroupID as a 4-character hexadecimal row vector expressing the
  % 16-bit group ID. The default is '0000'.
  GroupID = '0000';

  %GroupName Group name
  % Specify GroupName as a character vector expressing the group name.
  % The default is ''.
  GroupName = '';

  %GroupList List of group identifiers
  % Specify GroupList as an Nx4 matrix; each row must be a 4-character
  % hexadecimal vector expressing a 16-bit group ID. The default is [].
  GroupList = [];

  %Status Status of Add/View/Remove Group commands
  % Specify Status as one of 'Success' | 'Duplicate exists' | 'No space' |
  % 'Not found'. The default is 'Success'.
  Status = 'Success';

  %Capacity Number of free group slots
  % Specify Capacity as a scalar non-negative integer lesser than 256. The
  % default is 0.
  Capacity = 0;
end

properties (Dependent)
	%GroupCount Size of group list
  % The number of groups in the GroupList property.
  GroupCount;
end

properties(Constant, Hidden)
  CommandTypeValues = {'Add group', 'View group', 'Get group membership', ...
                       'Remove group', 'Remove all groups', ...
                       'Add group if identifying', 'Add group response', ...
                       'View group response', 'Remove group response', ...
                       'Get group membership response'};
  StatusValues = {'Success', 'Duplicate exists', 'No space', 'Not found'};
end

methods
  function obj = GroupsFrameConfig(varargin)
    % Apply constructor name value pairs:
    for i = 1:2:nargin
      obj.(varargin{i}) = varargin{i+1};
    end
  end

  % For auto-completion:
  function v = set(obj, prop)
    v = obj.([prop, 'Values']);
  end

  function obj = set.CommandType(obj, value)
    obj.CommandType = validatestring(value, obj.CommandTypeValues, '', 'CommandType');
  end

  function obj = set.GroupID(obj, value)
    value = convertStringsToChars(value);
    validateattributes(value, {'char'}, {'row', 'numel', 4}, '', 'GroupID');
    obj.GroupID = value;
  end

  function obj = set.GroupName(obj, value)
    value = convertStringsToChars(value);
    validateattributes(value, {'char'}, {'row'}, '', 'GroupName');
    if numel(obj.GroupName) > 16
      error(getString(message('lrwpan:ZigBee:ZCLNameLengthExceeded', 'Group name')));
    end
    obj.GroupName = value;
  end

  function obj = get.GroupCount(obj)
    obj.GroupCount = size(obj.GroupList, 1);
  end

  function obj = set.Capacity(obj, value)
    validateattributes(value, {'numeric'}, {'scalar', 'integer', 'nonnegative', 'real', '<', 256}, '', 'Capacity');
    obj.Capacity = value;
  end

  function obj = set.Status(obj, value)
    obj.Status = validatestring(value, obj.StatusValues, '', 'Status');
  end

  function obj = set.GroupList(obj, value)
    if isstring(value)
        value = char(value);
    end
    validateattributes(value, {'char'}, {'2d', 'ncols', 4}, '', 'GroupList');
    obj.GroupList = value;
  end
end

methods (Access = protected)
  function groups = getPropertyGroups(obj)
    propList = properties(obj);
    activeIdx1 = true(size(propList));

    for n = 1:numel(propList)
      if  isInactiveProperty(obj, propList{n})
        activeIdx1(n) = false;
      end
    end
    groups = matlab.mixin.util.PropertyGroup(propList(activeIdx1));
  end

  function flag = isInactiveProperty(obj, prop)
    flag = false;
    if strcmp(prop, 'GroupID')
      flag = any(strcmp(obj.CommandType, {'Get group membership', 'Get group membership response', ...
                                          'Remove all groups'}));
                                        
    elseif strcmp(prop, 'GroupName')
      flag = ~any(strcmp(obj.CommandType, {'Add group', 'Add group if identifying', ...
                                           'View group response'}));
                                
    elseif any(strcmp(prop, {'GroupCount', 'GroupList'}))
      flag = ~any(strcmp(obj.CommandType, {'Get group membership', 'Get group membership response'}));

    elseif strcmp(prop, 'Capacity')
      flag = ~strcmp(obj.CommandType, 'Get group membership response');
        
    elseif strcmp(prop, 'Status')
      flag = ~any(strcmp(obj.CommandType, {'Remove group response', 'View group response', ...
                                      'Add group response'}));
    end
  end
end

end
