classdef BuildInfoFile < RTW.BuildInfoClass & handle & matlab.mixin.SetGet 
%RTW.BuildInfoFile class
%   RTW.BuildInfoFile extends RTW.BuildInfoClass.
%
%    RTW.BuildInfoFile properties:
%       Settings - Property is of type 'handle'  
%       DisplayLabel - Property is of type 'ustring'  
%       Group - Property is of type 'ustring'  
%       FileName - Property is of type 'ustring'  
%       Path - Property is of type 'ustring'  
%       Options - Property is of type 'handle'  

%   Copyright 2017-2020 The MathWorks, Inc.

    properties
        FileName = '';
        Path = '';
        Options = [];
    end

    methods
        function h = BuildInfoFile(varargin)
        %  when the object is read in from a mat file, this is called with no args to
        %  load the class
            if (nargin == 0)
                return;
            end
            
            %check the args to make sure they all conform to the expected format
            [args_ok,args] = locCheckArgs(varargin{:});
            if ~(args_ok)
                DAStudio.error('RTW:buildInfo:badMethodArguments',...
                               'RTW.BuildInfo.BuildInfoFile');
            end
            
            % Instantiate class
            % override the base class display label. This is not displayed in the
            % DAStudioExplorer, since we want the filename listed instead.  It's
            % being set here for debugging purposes to differentiate the different
            % BuildInfoObjects.
            h.FileName     = args.FileName;
            h.Path         = args.Path;
            h.Group        = args.Group;
            h.DisplayLabel = args.DisplayLabel;
            h.Settings     = args.Settings;
            h.Options      = RTW.BuildInfoOptions;
        end
    end

    methods
        function addCompileFlags(h, varargin)
        %ADDCOMPILEFLAGs - adds one or more options to the CompileFlags vector via the
        %addOptions method.
        %
        % Call the function like this:
        % 
        % h.addCompileFlags(options, groups)
        %
        % args  Optional? description
        % options n - char array or cell array of chars
        %             contains the option(s) to be added
        % Group   y - char array, or cell array of char
        %             The Group;label that should be applied to the option(s)
        %             if this arg is a char array, it is used for all the options
        %             if it is a cell array, length(group) must equal length(options)
            h.Options.addOptions('CompileFlags',varargin{:});
        end
        
        function addDefines(h, varargin)
        %ADDDEFINES - adds one or more options to the Defines vector via the
        %addOptions method.
        %
        % Call the function like this:
        % 
        % h.addDefines(options, groups)
        %
        % args  Optional? description
        % options n - char array or cell array of chars
        %             contains the option(s) to be added
        % Group   y - char array, or cell array of char
        %             The Group;label that should be applied to the option(s)
        %             if this arg is a char array, it is used for all the options
        %             if it is a cell array, length(group) must equal length(options)
            h.Options.addOptions('Defines',varargin{:});
        end
        
        function val = getChildren(h)
        %GETCHILDREN - returns non-hierarchical child properties for DA Studio Explorer
            val = h.getHierarchicalChildren;
        end
        
        function ret = getCompileFlags(h, varargin)
        %GETCOMPILEFLAGS - returns a cell array of Compile Flags. This function is
        % called like this:
        % 
        % options = getCompileFlags(includeGroupIDs, excludeGroupIDs)
        %
        %    includeGroupIDs    This is a cell array of Group IDs.  Only Options that
        %                       have GroupID in this set will be returned.  If this
        %                       is empty, the all Options are included
        %
        %    excludeGroupIDs    This is a cell array of Group IDs. Any Options that
        %                       have one of these Group ID's will be excluded.
        %
        % includeGroupIDs and excludeGroupIDs are optional
            ret = h.Options.getOptions('CompileFlags',varargin{:});
        end

        function [ret, keys, vals] = getDefines(h, varargin)
        %GETDEFINES - returns a cell array of Defines. This function is called
        % like this:
        % 
        % options = getDefines(includeGroupIDs, excludeGroupIDs)
        %
        %    includeGroupIDs    This is a cell array of Group IDs.  Only Options that
        %                       have GroupID in this set will be returned.  If this
        %                       is empty, the all Options are included
        %
        %    excludeGroupIDs    This is a cell array of Group IDs. Any Options that
        %                       have one of these Group ID's will be excluded.
        %
        % includeGroupIDs and excludeGroupIDs are optional
            [ret, keys, vals] = h.Options.getOptions('Defines',varargin{:});
        end
        
        function val = getDisplayLabel(h)
        %GETDISPLAYLABEL - Returns the display label for DAStudio Explorer.  
            val = char(h.FileName);
        end
        
        function val = getHierarchicalChildren(h)
        %GETHIERARCHICALCHILDREN - returns hierarchical child properties for DA Studio
        %explorer
            val = h.Options;
        end
        
        function val = getPreferredProperties(h)
        %GETPREFERREDPROPERTIES - Returns the preferred properties for the DA Studio
        %Explorer
        % the base class has properties which should be in the
        % preferred properties list.  Since there is no way to call a
        % base class method from a derived class, call a surrogate
        % getPreferredProperties from the base class.
            base_props = h.getBaseBuildInfoClassProperties();
            additional_props = {'Path'};
            val = [base_props additional_props];
        end
        
        function val = isHierarchical(~)
        %ISHIERARCHICAL - returns true if this class has hierarchical child properties.
            val = true;
        end
    end
end

function [args_ok,args] = locCheckArgs(varargin)

    args_ok           = true;
    args.FileName     = '';
    args.Path         = '';
    args.Group        = '';
    args.DisplayLabel = 'BuildInfo file';
    args.Settings     = [];

    % First arg is the FileName
    if ~ischar(varargin{1})
        args_ok = false;
        return;
    end
    args.FileName = varargin{1};

    % second arg is the Path
    if (nargin >= 2)
        if ~ischar(varargin{2})
            args_ok = false;
            return;
        end
        args.Path = varargin{2};
    end

    % third arg is the group
    if (nargin >= 3)
        if ~char(varargin{3})
            args_ok = false;
            return;
        end
        args.Group = varargin{3};
    end

    % Fourth arg is the DisplayLabel
    if (nargin >= 4)
        if ~ischar(varargin{4})
            args_ok = false;
            return;
        end
        args.DisplayLabel = varargin{4};
    end

    % final arg is a handle to a settings object, or [].
    if (nargin >= 5)
        if ~isempty(varargin{5}) && ~isa(varargin{5}, 'RTW.BuildInfoSettings')
            args_ok = false;
            return;
        end
        args.Settings = varargin{5};
    end
end
