classdef StandaloneApplicationOptions < compiler.internal.build.DependencyOptions
%COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS   Create a standalone options object
%
%    OPTS = COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS(APPFILE) creates a
%        default STANDALONEAPPLICATIONOPTIONS object OPTS with a MATLAB
%        function specified by APPFILE. The STANDALONEAPPLICATIONOPTIONS
%        object is passed as an input to the
%        compiler.build.standaloneApplication and
%        compiler.build.standaloneWindowsApplication functions.
%
%    OPTS = COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS(APPFILE,NAME,VALUE)
%        creates a STANDALONEAPPLICATIONOPTIONS object OPTS with a MATLAB
%        function specified by APPFILE and additional customizations
%        specified by name-value pairs. The STANDALONEAPPLICATIONOPTIONS
%        object is passed as an input to the
%        compiler.build.standaloneApplication and
%        compiler.build.standaloneWindowsApplication functions.
%
%    INPUT ARGUMENTS:
%
%    - APPFILE (A row char vector or a string scalar)
%        Path to a MATLAB function, MATLAB class, or MATLAB app. The file
%        must have one of the following extensions: .m, .p, .mlx, .mlapp,
%        or any valid MEX file.
%
%    OUTPUT ARGUMENTS:
%
%    - OPTS (A scalar compiler.build.StandaloneApplicationOptions object)
%        Standalone options, specified as a StandaloneApplicationOptions
%        object.
%
%    NAME-VALUE PAIR ARGUMENTS:
%
%    - AdditionalFiles (A row char vector, a string vector, or a cellstr vector)
%        A list of files and folders to be included within the standalone
%        application.
%
%    - AutoDetectDataFiles ('on'/'off', true/false, or 1/0)
%        Binary value controlling whether data files that are provided as
%        inputs to certain functions (such as load) are automatically
%        included with the standalone application. This is set to 'on' by
%        default. If it is set to false/'off'/0, all data files must be
%        added to the application using the AdditionalFiles property.
%
%    - CustomHelpTextFile (A row char vector or a string scalar)
%        Path to a text file containing help text for the end user of the
%        application.
%
%    - EmbedArchive ('on'/'off', true/false, or 1/0)
%        Binary value controlling whether the standalone archive is
%        embedded into the standalone executable, or if it is generated as
%        a separate file. This is set to 'on' by default.
%
%    - ExecutableIcon (A row char vector or a string scalar)
%        Path to an image file used as the icon for the standalone
%        application.
%
%    - ExecutableName (A row char vector or a string scalar)
%        Name of the generated executable.
%
%    - ExecutableSplashScreen (A row char vector or a string scalar)
%        Path to an image file used as the splash screen for the standalone
%        application. The splash screen will be resized to 400 pixels by
%        400 pixels.
%
%    - ExecutableVersion (A row char vector or a string scalar)
%        Version of the generated executable. Not used on Linux.
%
%    - ObfuscateArchive ('on'/'off', true/false, or 1/0)
%        Binary value controlling whether to obfuscate the folder structures, 
%        file names and .m files in the deployable archive (.ctf file). 
%        This is set to 'off' by default.
%
%    - OutputDir (A row char vector or a string scalar)
%        Path to folder where the build files are saved.
%
%    - SupportPackages (A row char vector, a string vector, or a cellstr vector)
%        'autodetect' (default) - The required support packages are
%        detected and included automatically.
%
%        'none' - No support packages are included in the standalone
%        application.
%
%        Otherwise, a specific list of support packages may be specified
%        for inclusion.
%
%    - TreatInputsAsNumeric ('on'/'off', true/false, or 1/0)
%        Binary value controlling how the application treats command line
%        inputs. This is set to 'off' by default. By setting the value to
%        true/'on'/1, command line inputs will be treated as numeric
%        values.
%
%    - Verbose ('on'/'off', true/false, or 1/0)
%        Binary value controlling build verbosity. It is 'off' by default.
%
%    EXAMPLES:
%
%    % Create a STANDALONEAPPLICATIONOPTIONS object with a MATLAB function.
%    opts = COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS('exampleFcn.m');
%
%    % Create a STANDALONEAPPLICATIONOPTIONS object with a MATLAB function and
%    % additional options specified as name-value pairs.
%    opts = COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS('exampleFcn.m', ...
%        'ExecutableName','usefulApp','Verbose','on');
%
%    % Create a STANDALONEAPPLICATIONOPTIONS object with a MATLAB function and
%    % additional options specified using dot notation.
%    opts = COMPILER.BUILD.STANDALONEAPPLICATIONOPTIONS('exampleFcn.m');
%    opts.CustomHelpTextFile = 'C:\Path\To\My\Help.txt';
%    opts.Verbose = 'on';
%
%    See also compiler.build.standaloneApplication, compiler.build.standaloneWindowsApplication

%   Copyright 2020-2022 The MathWorks, Inc.

    % public
    properties
        CustomHelpTextFile = ''
        EmbedArchive matlab.lang.OnOffSwitchState = 'on'
        ExecutableIcon {mustBeNonempty} = fullfile(compiler.build.StandaloneApplicationOptions.DefaultImageDir,'default_icon_48.png')
        ExecutableName = ''
        ExecutableSplashScreen {mustBeNonempty} = fullfile(compiler.build.StandaloneApplicationOptions.DefaultImageDir,'default_splash.png')
        ExecutableVersion {mustBeNonzeroLengthText} = '1.0.0.0' % Not used on Linux
        AppFile
        TreatInputsAsNumeric matlab.lang.OnOffSwitchState = 'off'
    end

    % This should probably move elsewhere eventually
    properties(Constant,Hidden)
        DefaultImageDir = fullfile(matlabroot,'toolbox','compiler','packagingResources')
    end

    % constructor
    methods
        function obj = StandaloneApplicationOptions(main,varargin)

            narginchk(1,2*numel(properties(compiler.build.StandaloneApplicationOptions.empty))-1)

            obj = obj@compiler.internal.build.DependencyOptions;

            obj.AppFile = main;

            p = inputParser;
            allprops = properties(obj);
            for n = 1:numel(allprops)
                addParameter(p,allprops{n},obj.(allprops{n}))
            end
            parse(p,varargin{:})
            changedprops = setdiff(allprops,p.UsingDefaults);

            for n = 1:numel(changedprops)
                obj.(changedprops{n}) = p.Results.(changedprops{n});
            end
        end
    end

    % set
    methods
        function obj = set.ExecutableVersion(obj,newVersion)
            compiler.internal.validate.propertyIsScalarText(newVersion,'ExecutableVersion')
            obj.ExecutableVersion = char(newVersion);
        end

        function obj = set.AppFile(obj,appFile)
            compiler.internal.validate.propertyIsScalarText(appFile,'AppFile')
            mustBeNonempty(appFile)
            compiler.internal.validate.fileMustExist(appFile)
            [~,~,ext] = fileparts(appFile);
            allowed = matlab.depfun.internal.requirementsConstants.executableMatlabFileExt;
            if ~any(strcmp(ext,allowed))
                extlist = allowed{1};
                for n = 2:numel(allowed)
                    extlist = sprintf('%s\n%s',extlist,allowed{n});
                end
                error(message('Compiler:clishared:badExtension','AppFile',extlist))
            end

            obj.AppFile = compiler.internal.validate.makePathAbsolute(appFile);
            obj.throwPFileWarning({obj.AppFile})
        end

        function obj = set.ExecutableIcon(obj,newIcon)
            compiler.internal.validate.propertyIsScalarText(newIcon,'ExecutableIcon')
            compiler.internal.validate.fileMustExist(newIcon)
            newIcon = compiler.internal.validate.makePathAbsolute(newIcon);
            compiler.internal.image.rejectAnimatedGIFs(newIcon)
            obj.ExecutableIcon = newIcon;
        end

        function obj = set.ExecutableSplashScreen(obj,newSplash)
            compiler.internal.validate.propertyIsScalarText(newSplash,'ExecutableSplashScreen')
            compiler.internal.validate.fileMustExist(newSplash)
            newSplash = compiler.internal.validate.makePathAbsolute(newSplash);
            compiler.internal.image.rejectAnimatedGIFs(newSplash)
            obj.ExecutableSplashScreen = newSplash;
        end

        function obj = set.CustomHelpTextFile(obj,newTextFile)
            compiler.internal.validate.propertyIsScalarText(newTextFile,'CustomHelpTextFile')
            compiler.internal.validate.fileMustExist(newTextFile)
            obj.CustomHelpTextFile = compiler.internal.validate.makePathAbsolute(newTextFile);
        end

        function obj = set.ExecutableName(obj,newName)
            compiler.internal.validate.cliName(newName,'ExecutableName')
            obj.ExecutableName = char(newName);
        end
    end

    % get
    methods
        function name = get.ExecutableName(obj)
            name = obj.ExecutableName;
            if isempty(name)
                [~,name] = fileparts(obj.AppFile);
                name = compiler.internal.validate.defaultOutputFilename(name);
            end
        end
    end

    % define abstract
    methods(Hidden)
        function name = getName(obj)
            name = obj.ExecutableName;
        end
    end
    properties(Access = protected,Constant)
        OutputDirTag = char(compiler.internal.build.BuildTypes.standaloneApplication)
    end
end
