classdef helpProcess < handle
    
    properties (Access=public)
        wsVariables     = struct('name', {}, 'class', {});
        topic           = '';
        inputTopic      = '';
        isAtCommandLine = false;
        justChecking    = false;
    end
    
    properties (SetAccess=private, GetAccess=public)
        displayBanner = false;
        
        helpStr  = '';
        docLinks (1,1) matlab.internal.language.introspective.docLinks;
        helpOnInstance = false;
        
        command          = '';
        fullTopic        = '';
        objectSystemName = '';
        elementKeyword   = '';
        
        isBuiltin                = false;
        isDir                    = false;
        isContents               = false;
        isOperator               = false;
        isMCOSClassOrConstructor = false;
        isMCOSClass              = false;
        isInaccessible           = false;
        isTypo                   = false;
        
        imports         = {};
        callingFunction = '';
        
        suppressDisplay    = false;
        suppressedImplicit = false;
        suppressedFolders  = false;
        commandIsHelp      = true;
        fixTypos           = true;
        needsHotlinking    = false;
        noDefault          = false;
    end
    
    properties (Dependent = true, Access = private)
        wantHyperlinks;
    end
    
    methods
        function value = get.wantHyperlinks(hp)
            value = hp.command ~= "";
        end
    end
    
    methods
        function hp = helpProcess(nlhs, nrhs, prhs)
            hp.suppressDisplay = (nlhs ~= 0);
            if ~hp.suppressDisplay
                if matlab.internal.display.isHot
                    hp.command = 'help';
                end
            end
            
            commandSpecified = false;
            
            try
                for i = 1:nrhs
                    arg = prhs{i};
                    if isstring(arg)
                        if ~isscalar(arg)
                            error(message('MATLAB:help:MustBeSingleString'));
                        end
                        commandSpecified = processTextInput(hp, char(arg), commandSpecified);
                    elseif ischar(arg)
                        if ~isvector(arg) && ~isempty(arg)
                            error(message('MATLAB:help:MustBeCharVector'));
                        end
                        commandSpecified = processTextInput(hp, arg, commandSpecified);
                    else
                        hp.specifyTopic(class(arg));
                        hp.inputTopic = i;
                        hp.displayBanner = true;
                        hp.helpOnInstance = true;
                    end
                end
                
                if isstring(hp.topic)
                    if matlab.internal.display.isHot && ~any(contains(hp.topic, '"'))
                        searchArgs = string(join(cellfun(@mat2str, hp.topic, 'UniformOutput', false), ', '));
                        error(message('MATLAB:help:TooManyInputsWithLinks', sprintf('docsearch(%s)', searchArgs)));
                    else
                        error(message('MATLAB:help:TooManyInputsNoLinks'));
                    end
                end
            catch Ex
                hp.suppressDisplay = true;
                throwAsCaller(Ex);
            end
        end
        
        function delete(hp)
            if ~hp.suppressDisplay
                disp(hp.displayHelp);
            end
        end
        
        function specifyCommand(hp, command)
            hp.command = command;
            hp.commandIsHelp = strcmp(hp.command, 'help');
        end
    end
    
    methods (Access=private)
        function commandSpecified = processTextInput(hp, arg, commandSpecified)
            switch arg
                case '-noDefault'
                    hp.noDefault = true;
                case {'-help', '-helpwin', '-doc', '-updateHelpPopup'}
                    if commandSpecified
                        error(message('MATLAB:help:TooManyCommands'));
                    end
                    hp.specifyCommand(arg(2:end))
                    hp.fixTypos = hp.commandIsHelp;
                    commandSpecified = true;
                otherwise
                    hp.specifyTopic(arg);
                    hp.inputTopic = arg;
            end
        end
        
        function specifyTopic(hp, topic)
            if ~isempty(hp.topic)
                hp.topic = [hp.topic, string(topic)];
            else
                hp.topic = topic;
            end
        end
        
        function topic = getTopic(hp)
            if isempty(hp.objectSystemName)
                topic = hp.topic;
            else
                topic = hp.objectSystemName;
            end
        end
        
        link = getReferenceLink(hp);
        link = getOverloadsLink(hp);
        link = getFoldersLink(hp);
        link = getOtherNamesLink(hp, topic, linkTopic, linkID, linkFcn);
        
        getDocLinks(hp);
        getBuiltinHelp(hp, justH1);
        getDefaultHelpFromSource(hp);
        
        extractFromClassInfo(hp, classInfo);
        found = getHelpTextFromDoc(hp, classInfo, fallthrough);
        found = getHelpFromClassInfo(hp, classInfo, justH1);
        
        demoTopic = getDemoTopic(hp);
        [qualifyingPath, pathItem] = getPathItem(hp);
        
        getFolderHelp(hp, justH1);
        found = getHelpForTopics(hp, topics, isOperator, forceContents);
        hotlinkHelp(hp);
    end
    
    methods
        appendBanner(hp);
        getHelpText(hp);
        prepareHelpForDisplay(hp);
        
        getNoInputHelp(hp, historyFile);
        getTopicHelpText(hp, justH1);
        getHelpOnExpression(hp, expression);
        displayStr = displayHelp(hp);
    end
end

%   Copyright 2007-2020 The MathWorks, Inc.
