function h = createFromTemplate(templatename,varargin)
% createFromTemplate - Create model or project from template
%
% Simulink.createFromTemplate(templatename) creates a model or a
% project from the specified template.  templatename is a string and can
% optionally include the template's path and .sltx extension.
%
% h = Simulink.createFromTemplate(templatename) creates a model or a
% project from the template file and returns h, either a numeric model
% handle or a simulinkproject object.
% 
% h = Simulink.createFromTemplate(templatename,Name,Value) specifies
% additional options as one or more Name, Value pair arguments. Options
% are:  
%  Folder: the project root if creating a new project
%  Name: the name of the new model or project
%
% See also: Simulink.findTemplates

%   Copyright 2015-2021 The MathWorks, Inc.

has_opts = nargin>1;
if has_opts
    p = inputParser;
    p.StructExpand = true;
    p.addParameter('Name','',@isscalarstring);
    p.addParameter('Folder','',@isscalarstring);
    p.parse(varargin{:});
    opts = p.Results;
else
    opts.Name = '';
    opts.Folder = '';
end

function b = isscalarstring(v)
    b = ischar(v) || (isstring(v) && numel(v)==1);
end

if isstring(templatename)
    templatename = char(templatename);
end

% If the supplied name is in a form that we can find using resolveFile
% then we'll use that.
filename = Simulink.loadsave.resolveFile(templatename,'.sltx');

info = [];
if ~isempty(filename)
    % We found a matching template file.  Get the template info from it.
    try %#ok<TRYNC>
        info = sltemplate.TemplateInfo(filename);
    end
end
if isempty(info)
    % Didn't manage to get any info this way.  Try to find a
    % matching template file using findMatchingTemplate, which has support
    % for wildcards and partial matches.
    try
        [filename,info] = sltemplate.internal.findMatchingTemplate(templatename);
    catch E
        if ~isempty(filename)
            % We resolved a file, but it is not a valid template file.
            DAStudio.error('sltemplate:Registry:InvalidTemplate',filename);
        else
            rethrow(E);
        end
    end
end
assert(~isempty(info)); % otherwise we'll have had an error

if strcmp(info.Type,'Model') || strcmp(info.Type,'Library') || strcmp(info.Type,'Subsystem')
    % A default name is chosen by new_system if none was supplied.
    h = new_system(opts.Name,'FromTemplate',filename);
else
    if isempty(opts.Name)
        [~,opts.Name] = slfileparts(filename);
    end
    if isempty(opts.Folder)
        opts.Folder = slfullfile( ...
            matlab.internal.project.creation.getDefaultFolder(), ...
            opts.Name);
    else
        opts.Folder = Simulink.loadsave.resolveNew(opts.Folder);
    end
    if ~exist(opts.Folder,'dir')
        mkdir(opts.Folder);
    end
    h = sltemplate.internal.invokeProjectTemplate(filename,opts.Folder,opts.Name);
end

end
