function varargout = extract(obj, block, varargin)
%
%

%   Copyright 2010-2021 The MathWorks, Inc.

    nargs = nargin - 2;
    showModel = varargin{1};
    opts = [];
       
    if nargs==1
        showUI = false;
        isValid = false;
    elseif nargs==2
        showUI = varargin{2};
        isValid = false;
    elseif nargs==3            
        showUI = varargin{2};
        isValid = varargin{3};        
    elseif nargs==4             
        showUI = varargin{2};
        isValid = varargin{3};        
        opts = varargin{4};
    else % For Model Slicer
        showUI = varargin{2};
        isValid = varargin{3};        
        opts = varargin{4};
        obj.IsModelSlicer = varargin{5};
    end
    
    if ~islogical(showModel)
        obj.handleMsg('error', message('Sldv:SubSysExtract:InvalidShowModel', obj.UtilityName));
    end
    obj.ShowModel = showModel;
    
    if ~islogical(showUI)
        obj.handleMsg('error', message('Sldv:SubSysExtract:InvalidShowUI', obj.UtilityName));
    end
    obj.ShowUI = showUI;
    
    if ~islogical(isValid)
        obj.handleMsg('error', message('Sldv:SubSysExtract:InvalidIsValid', obj.UtilityName));
    end
    obj.IsValid = isValid;        

    if obj.IsValid
        obj.SubSystemH = Sldv.utils.getObjH(block);     
        obj.IsAtomicSubchart = Sldv.utils.isAtomicSubchartSubsystem(obj.SubSystemH);
    else    
        blockH = Sldv.utils.getObjH(block, true);
        msg = getString(message('Sldv:SubSysExtract:InvalidFirstArg', obj.UtilityName));
        msg_id = 'Sldv:SubSysExtract:InvalidFirstArg';
        if isempty(blockH)           
            obj.Status = false;
            obj.deriveSsError(msg, msg_id, blockH);
        elseif  strcmp(get_param(bdroot(blockH), 'BlockDiagramType'), 'library')
            msg2 = getString(message('Sldv:SubSysExtract:AtomicSubsystemOrSubchart'));
            obj.Status = false;
            obj.deriveSsError([msg ' ' msg2], msg_id, blockH);
        else            
            obj.Status = ...
                Sldv.SubSystemExtract.checkPortConfiguration(blockH);
            if obj.Status
                isAtomicSubchart = Sldv.utils.isAtomicSubchartSubsystem(blockH);
                [status, msg2] = Sldv.SubSystemExtract.checkPorts(blockH);
                if ~status
                    obj.deriveSsError([msg ' ' msg2], msg_id, blockH);
                    obj.Status = false;                                        
                else
                    obj.SubSystemH = blockH;
                    obj.IsAtomicSubchart = isAtomicSubchart;
                end
            end                                    
        end
    end
    
    
    if obj.Status
        blockH = Sldv.utils.getObjH(block, true);
        if ~Sldv.Extract.checkIsActive(blockH)
            obj.Status = false;
            msg2 = getString(message('Sldv:EXTRACT:ContentForExtractionMustNotBe'));
            obj.deriveSsError([msg ' ' msg2], msg_id, blockH);
        else
            obj.Opts = opts;
            obj.invokess2mdl;
            if ~obj.Status
                obj.deriveSs2mdlError;
            else
                obj.fixSubsystemName;               
                if sldvshareprivate('util_is_analyzing_for_fixpt_tool')
                    % DataStores already added.  If analyzing for fixpt
                    % need to set the storage class for referenced
                    % simulink signal vars
                    obj.addInportsForDSRW;
                end
                
                if ~obj.IsModelSlicer
                    obj.setFixedStepSolver;
                end
                obj.fixSubsystemRelativeSettings;
                obj.copySFDebugSettings;
                obj.saveExtractedModel;
                if ~obj.Status
                    msg_id = 'Sldv:SubSysExtract:ErrExtSubSys';
                    msg = getString(message(msg_id));
                    obj.deriveSsError(msg, msg_id, blockH);
                elseif obj.ExtractionMode==0 
                    [solverChanged, msg] = ...
                        Sldv.SubSystemExtract.createForcessDiscreteMsg(obj.ModelH, obj.OrigModelH);
                    if solverChanged && ~obj.IsValid
                        sldvshareprivate('util_gen_warning_notrace', ...
                            'Sldv:SubSysExtract:ForceDiscrete', msg);                                   
                    end 
                end
            end
        end
    end
    
    varargout{1} = obj.Status;
    varargout{2} = obj.ModelH;
    varargout{3} = obj.ErrMsg;
end

% LocalWords:  UI notrace
