function varargout=spm_help(varargin)
% SPM help and manual facilities
% FORMAT spm_help
%_______________________________________________________________________
%  ___  ____  __  __
% / __)(  _ \(  \/  )  
% \__ \ )___/ )    (   Statistical Parametric Mapping
% (___/(__)  (_/\/\_)  SPM - http://www.fil.ion.ucl.ac.uk/spm/
%
%_______________________________________________________________________
%
% SEE ALSO:   spm.man      - "About SPM"
%
% The "Help" facilities are about software and implementation. The
% underlying mathematics, concepts and operational equations have been
% (or will be) published in the peer reviewed literature and the
% interested user is referred to these sources. An intermediate
% theoretical exposition is given in the SPM course notes. This and
% other resources are available via the SPM Web site. Visit
% http://www.fil.ion.ucl.ac.uk/spm/, or press the "SPMweb" button on the
% spm_help toolbar.
%
%-----------------------------------------------------------------------
%
% spm_help sets up a GUI help system for the SPM package.
% `spm_help('Topic')` or `spm_help Topic` displays the help for a
% particular topic in the SPM help window.
%
% Help topics are displayed in a special help window. Initially, a
% representation of the SPM Menu window is drawn. Clicking buttons in
% this representation leads to the help pages for the appropriate
% topic.
% 
% The SPM Help ToolBar contains controls for the help system.
%
%  ---  Routines and manual pages (generically referred to as help
%       "topics") referenced by the currently displayed help file are
%       listed in the "Referenced Topics..." pull-down menu on the help
%       interface. Selecting a routine there displays it's help
%       information.
%
%  ---  Alternatively, a specific function name can be entered into
%       the lilac editable text widget in the help window toolbar.
%       Its help will be displayed.
%
%  ---  As the tree of routines is explored, the "Previous Topics"
%       pulldown menu keeps track of recently visited help topics,
%       allowing easy backtracking and exploration of the "tree" of SPM
%       functions and dependencies.
%
% Special topic buttons lead to "About SPM", "Menu", and "Help" topics.
% "About SPM" displays the introduction file for this version of SPM.
% "Menu" displays the help representation of the SPM Menu window.
% "Help" displays this file.
%
% Multi-page help files are displayed by the help facility with pagination
% controls at the bottom right of the Graphics window.
%
% The print button enables printing to the specified Print device. This
% is set in the Defaults area, initially to a PostScript file
% "spm*.ps" in the current directory. Multi page topics are paged on
% screen, and printed page by page.
%
%
%-----------------------------------------------------------------------
% The SPM package provides help at three levels, the first two being
% available via the SPM graphical help system:
%
% (i)   Manual pages on specific topics.
%       These give an overview of specific components or topics its
%       relation to other components, the inputs and outputs and
%       references to further information.
%
%       Many of the buttons in the help menu window lead to such "man"
%       pages.  These are contained in ASCII files named spm_*.man.
%       These can be viewed on the MATLAB command line with the `help`
%       command, e.g. `help spm_help` prints out this manual file in
%       the MATLAB command window.
%
% (ii)  Help information for each routine within SPM (E.g. This is the).
%       help information for spm_help.m - the help function.)
%       This help information is the help header of the actual MATLAB
%       function, and can be displayed on the command line with the
%       `help` command, e.g. `help spm_help`.
%
%       Commented header text from that spm_*.m file is displayed in the 
%       following format:
%
%        A one line description
%        FORMAT [outputs] = spm_routine(inputs);
%        inputs  -  the input arguments
%        outputs -  the output arguments
%        A short paragraph detailing what the routine does and other
%        pertinent information
%        ref:  citations
%
% (iii) SPM is (mainly) implemented as MATLAB functions and scripts.
%       These are ASCII files named spm_*.m, which can be viewed in the
%       MATLAB command window with the `type` command, e.g. `type
%       spm_help`, or read in a text editor.
%
%  ---  MATLAB syntax is very similar to standard matrix notation that
%       would be found in much of the literature on matrices. In this
%       sense the SPM routines can be used (with MATLAB) for data
%       analysis, or they can be regarded as the ultimate pseudocode
%       specification of the underlying ideas.
%
%  ---  The coding is concise but clear, and annotated with comments
%       where necessary.
%
% In addition, the MATLAB help system provides keyword searching
% through the H1 lines (the first comment line) of the help entries of
% *all* M-files found on MATLABPATH. This can be used to identify
% routines from keywords. Type `help lookfor` in the MATLAB command
% window for further details.
%
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Andrew Holmes, Karl Friston
% $Id: spm_help.m 8776 2013-11-14 09:04:48Z roboos $


%=======================================================================
% - FORMAT specifications for embedded CallBack functions
%=======================================================================
%( This is a multi function function, the first argument is an action  )
%( string, specifying the particular action function to take. Recall   )
%( MATLAB's command-function duality: `spm_help MenuWin` is equivalent )
%( to `spm_help('MenuWin')`.                                           )
%
% FORMAT spm_help
% Makes Help window visible if there is one around. Otherwise
% defaults to spm_help('!Topic','MenuWin').
%
% FORMAT spm_help('Topic')
% Defaults to spm_help('!Topic','Topic').
%
% FORMAT spm_help('!Quit')
% Hides the Help window.
% (Re)Shows the welcome splash screen if it exists.
%
% FORMAT spm_help('!DrawMenuWin')
% Draws representation of Menu window in help window, with button
% CallBacks for the appropriate help topics.
%
% FORMAT [S,Err] = spm_help('!ShortTopics',Topic)
% Returns help text (as a string) for special topics. If the topic is
% not found then S contains an error topic, and Err is true.
% Topic     - Special internal help topic
% S         - String vector containing help topic
% Err       - True if the topic is not found
%
% FORMAT spm_help('!Topic',Topic)
% Topic     - Help topic: Either name of file from which to display help,
%             or name of an internal help topic
%             Defaults to the "MenuWin" topic. (See '!ShortTopics')
% Loads file Topic (which must be on the MATLABPATH), parses it for
% references to other spm_* routines, puts these in the Help ToolBars
% "Referenced routines" pulldown (with callbacks to display their
% help), and sets up the "Previous topics" pulldown. Puts Topic in the
% editable topic window on the ToolBar. Then calls spm_help('!Disp') to
% display the help portion of the file.
% Special internal topics are tried if Topic file doesn't exist.
% "MenuWin" Topic prints a short message and displays the help
% representation of the Menu window.
%
% FORMAT spm_help('!Disp',Fname,S,F)
% Fname     - Name of file from which to display help
% S         - [Optional] String vector containing a previously read in
%             contents of file Fname
% F         - Figure to use
% Displays the help for the given file in the Help window (creating
% one if required). Paginates and provides paging buttons if necessary.
%
% FORMAT F = spm_help('!Create')
% F        - Handle of figure created
% Creates central Help window 'Tag'ged 'Help', with Help ToolBar
%
% FORMAT F = spm_help('!CreateHelpWin')
% F        - Handle of figure created
% Creates central Help window 'Tag'ged 'Help'. If one already exists
% then it's handle is returned.
%
% FORMAT spm_help('!CreateBar',F)
% F        - Handle (or 'Tag') of window to use. Defaults to 'Help'.
% Creates Help ToolBar.
%
% spm_help('!Clear',F)
% F        - Handle (or 'Tag') of window to use. Defaults to 'Help'.
% Clears help window, leaving ToolBar intact. Any 'HelpMenu' objects
% (with 'UserData' 'HelpMenu') are merely hidden, to speed up
% subsequent use.
%
% FORMAT h = spm_help('!ContextHelp',Topic)
% Sets up a small green "?" help symbol in the bottom right corner of
% the SPM Interactive window with callback to spm_help('Topic'). If SPM
% is in CommandLine mode then an appropriate message is printed in the
% MATLAB command window.
% Topic     - Help topic [defaults to name of calling function]
% h         - handle of "?" text (or 0 if CmdLine)
%_______________________________________________________________________

%-Condition arguments
%-----------------------------------------------------------------------
%-All actions begin '!' - Other (string) actions are topics
if nargin==0 || isempty(varargin{1})
    Fhelp = spm_figure('FindWin','Help');
    if ~isempty(Fhelp), set(Fhelp,'Visible','on')
    else spm_help('!Topic','MenuWin'), end
    return
elseif varargin{1}(1)~='!'
    spm_help('!Topic',varargin{:}), return
end



switch lower(varargin{1}), case '!quit'
%=======================================================================
Fhelp   = spm_figure('FindWin','Help');
set(Fhelp,'Visible','off')



case '!drawmenuwin'
%=======================================================================
% Fhelp = spm_help('!DrawMenuWin');

%-Find help window
%-----------------------------------------------------------------------
Fhelp = spm_figure('FindWin','Help');
if isempty(Fhelp), error('No Help window'), end

%-If there's already a HelpMenu then show it and return
H = findobj(Fhelp,'Tag','HelpMenu');
if ~isempty(H), set(H,'Visible','on'), return, end

%-Create window frame
%-----------------------------------------------------------------------
S      = get(Fhelp,'Position');       %-Help window position
WS     = [S(3)/600 S(4)/865 S(3)/600 S(4)/865];  %-Window scaling factors
%FS    = spm('FontSizes');            %-Scaled font sizes
PF     = spm_platform('fonts');       %-Font names (for this platform)
SPMver = spm('Ver');                  %-SPM version
O      = [170 050 000 000].*WS;       %-Offset for MenuWin plot

%-Button to emulate window title bar, frames to emulate window
%-----------------------------------------------------------------------
uicontrol(Fhelp,'Style','PushButton','String',['About ',SPMver],...
    'ForegroundColor',[0 0 0.9],...
    'ToolTipString','about this release of SPM [spm.man]',...
    'CallBack','spm_help(''spm.man'')',...
    'Position',[-4,447,406,30].*WS+O,...
    'Tag','HelpMenu')

uicontrol(Fhelp,'Style','Frame',...
    'Position',[-2,-3,404,450].*WS+O,...
    'Tag','HelpMenu')
uicontrol(Fhelp,'Style','Frame',...
    'Position',[0,0,400,445].*WS+O,...
    'Tag','HelpMenu',...
    'BackgroundColor',[1,1,1]*.8)

%-Frames & text
%-----------------------------------------------------------------------
Fmenu  = spm_figure('Findwin','Menu');
C      = get(Fmenu,'Children');
modality = spm('CheckModality');
for i = length(C):-1:1
    units = get(C(i),'Units');
    funits = get(C(i),'FontUnits');
    set(C(i),'Units','pixels');
    set(C(i),'FontUnits','points');
    c = get(C(i));
    set(C(i),'Units',units);
    set(C(i),'FontUnits',funits);

    % modality-specific help
    if isempty(c.Tag) || strcmp(c.Tag, 'frame') || ~isempty(strfind(c.Tag, modality))
        if strcmp(c.Type,'uicontrol')

            if ischar(c.UserData)
                Callback = sprintf('spm_help(''%s'')',c.UserData);
            else
                Callback = '';
            end

            uicontrol(Fhelp,...
                'BackgroundColor',c.BackgroundColor,...
                'Callback',  Callback,...
                'Enable',c.Enable,...
                'FontAngle',c.FontAngle,...
                'FontName',c.FontName,...
                'FontSize',c.FontSize,...
                'ForegroundColor',c.ForegroundColor,...
                'HorizontalAlignment',c.HorizontalAlignment,...
                'Units',c.Units,...
                'Position',c.Position + O,...
                'String',c.String,...
                'Style',c.Style,...
                'Tag', 'HelpMenu',...
                'TooltipString',c.TooltipString,...
                'Visible','on',...
                'Interruptible','on');
        end
    end
end

%-Special topics
%-----------------------------------------------------------------------
uicontrol(Fhelp,'Style','Frame','Position',[-145-2,-3,132+4,474+5].*WS+O,...
    'Tag','HelpMenu')
uicontrol(Fhelp,'Style','Frame','Position',[-145,0,132,474].*WS+O,...
    'Tag','HelpMenu',...
    'BackgroundColor',[1,1,1]*.8)
uicontrol(Fhelp,'Style','Text','String','special topics...',...
    'ForegroundColor','w','BackGroundColor',[1,1,1]*.8,...
    'FontName',PF.times,'FontAngle','Italic','FontWeight','Bold',...
    'HorizontalAlignment','Center',...
    'Position',[-133-5 447-10 110+10 30].*WS+O,...
    'Tag','HelpMenu')
uicontrol(Fhelp,'String','Data format','ForegroundColor','b',...
    'ToolTipString',...
    'about the image format used by SPM [spm_format.man]',...
    'Position',[-133 410 110 30].*WS+O,...
    'CallBack','spm_help(''spm_format.man'')',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','Templates','ForegroundColor','b',...
    'ToolTipString',...
    'templates and other data [spm_templates.man]',...
    'Position',[-133 370 110 30].*WS+O,...
    'CallBack','spm_help(''spm_templates.man'')',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 330 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 290 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 250 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 210 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 170 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 130 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','Random FX','ForegroundColor','b',...
    'ToolTipString','about implementing random effects analyses in SPM [spm_RandFX.man]',...
    'Position',[-133 090 110 30].*WS+O,...
    'CallBack','spm_help(''spm_RandFX.man'')',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','','ForegroundColor','b',...
    'ToolTipString','',...
    'Position',[-133 050 110 30].*WS+O,...
    'CallBack','',...
    'Enable','off',...
    'Tag','HelpMenu','Interruptible','on')
uicontrol(Fhelp,'String','SPM motd','ForegroundColor','b',...
    'ToolTipString','SPM startup "message of the day"',...
    'Position',[-133 010 110 30].*WS+O,...
    'CallBack','spm_help(''spm_motd.man'')',...
    'Tag','HelpMenu','Interruptible','on')

uicontrol(Fhelp,'String','Copyright (c) Wellcome Trust Centre for NeuroImaging',...
    'ForegroundColor',[1 1 1]*.6,'BackgroundColor','w',...
    'ToolTipString','Copyleft information',...
    'FontName',PF.times,'FontSize',8,...
    'Position',[-145 -030 549 015].*WS+O,...
    'CallBack','spm_help(''spm_LICENCE.man'')',...
    'Tag','HelpMenu','Interruptible','on')


case '!shorttopics'
%=======================================================================
% [S,Err] = spm_help('!ShortTopics',Topic)
if nargin<2, Topic='!Topics'; else Topic=varargin{2}; end

Usep = sprintf('%%%s',repmat('_',1,71));
Err = 0;

if strcmp(Topic,'!Topics')
    S = 'MenuWin';
elseif strcmp(Topic,'spm_motd.man')
    S = sprintf([...
        '\n%% %s : Message of the Day\n',...
        '%s\n%%\n',...
        '%% No message of the day has been set.\n',...
        '%%\n',...
        '%% File spm_motd.man can contain the message, which is',...
            ' displayed at startup\n',...
        '%% if it exists.\n',...
        '%s\n%%\n%% The FIL methods group\n'],...
        spm('Ver'),Usep,Usep);
elseif strcmp(Topic,'MenuWin')
    S = sprintf([...
        '\n%% %s : Statistical Parametric Mapping\n',...
        '%s\n%%\n',...
        '%% SPM functions are called from the main SPM Menu ',...
            'window.\n',...
        '%% Click the buttons in the representation below ',...
            'for help on that topic...\n',...
        '%%\n',...
        '%% Click on "Help" for information on SPM documentation, ',...
            'and instructions\n',...
        '%% on using the SPM help system.\n',...
        '%s\n%%\n%% The FIL methods group\n'],...
        spm('Ver'),Usep,Usep);
elseif strcmp(Topic,'SPM_Modality')
    S = sprintf([...
        '\n%% SPM Modality switch\n',...
        '%s\n%%\n',...
        '%% The modality switch on the SPM Menu interface ',...
            'allows switching\n',...
        '%% between PET/SPECT and fMRI modalities on the fly,',...
            'without re-starting SPM\n',...
        '%%\n',...
        '%% Operating the switch sets the MODALITY global ',...
            'variable,\n',...
        '%% sets the package defaults to those specified for ',...
            'the current modality\n',...
        '%% and changes the interface so that the appropriate ',...
            'routines\n',...
        '%% lie behind the buttons.\n',...
        '%%\n',...
        '%% See also: spm.m spm_defaults.m\n',...
        '%s\n%%\n%% Andrew Holmes\n'],Usep,Usep);
elseif strcmp(Topic,'MenuWin_Toolboxes_PullDown')
    S = sprintf([...
        '\n%% SPM Menu window: Toolboxes button\n',...
        '%s\n%%\n',...
        '%% The Toolboxes pulldown provides access to SPM ',...
            'toolboxes installed in\n',...
        '%% the toolbox subdirectory of the SPM installation ',...
            'directory.\n',...
        '%%\n',...
        '%% SPM toolboxes are defined as the contents of sub-',...
            'directories of\n',...
        '%% fullfile(spm(''Dir''),''toolbox'') - the ''toolbox'' ',...
            'subdirectory of the SPM\n',...
        '%% directory. For SPM to pick a toolbox up, there must be ',...
            'a single mfile\n',...
        '%% in the directory whose name ends with the toolbox ',...
            'directory name. (I.e.\n',...
        '%% A toolbox called "test" would be in the "test" ',...
            'subdirectory of\n',...
        '%% spm(''Dir''), with a single file named *test.m.) This ',...
            'M-file is\n',...
        '%% regarded as the launch file for the toolbox.\n',...
        '%%\n',...
        '%% On selecting the toolbox from the pulldown menu, the ',...
            'toolbox directory\n',...
        '%% is prepended to the MATLAB path (unless it is already ',...
            'on the path), and\n',...
        '%% the toolbox launch program executed (with no ',...
            'arguments).\n',...
        '%%\n',...
        '%% For help on specific toolboxes, refer to the toolbox ',...
            'itself.\n',...
        '%%\n',...
        '%% The toolbox directory for this installation of SPM is:\n',...
        '%%     %s\n',...
        '%%\n',...
        '%% SPM toolboxes are only identified at SPM startup.\n',...
        '%%\n',...
        '%% If there are no toolboxes installed, then the button ',...
            'is disabled.\n',...
        '%%\n',...
        '%% See spm.m for programmers help with toolbox handling.\n',...
        '%s\n%%\n%% Andrew Holmes\n'],...
        Usep,fullfile(spm('Dir'),'toolbox'),Usep);
elseif strcmp(Topic,'MenuWin_Utils_PullDown')
    S = sprintf([...
        '\n%% SPM Menu window: PullDown menu of utilities...\n',...
        '%s\n%%\n',...
        '%% 1) CD:        Calls spm_get prompting for a directory,\n',...
        '%%               and changes directory to it.\n',...
        '%% 2) PWD:       Reports the present working directory.\n',...
        '%%               \n',...
        '%% 3) delete:    GUI file deletion utility:\n',...
        '%%               Prompts for files to delete using',...
            ' spm_get.\n',...
        '%%               Seeks confirmation before deleting\n.',...
        '%%               List of deleted files reported in MATLAB',...
            ' command window.\n',...
        '%% 4) Show SPM:  Pops up all the figures for this SPM',...
            ' session.\n',...
        '%%               Typing "spm show" in the MATLAB command',...
            ' window has the\n',...
        '%%               same effect.\n',...
        '%% 5) Run mFile: Prompts for selection of a MATLAB M-file',...
            ' (script or function with\n',...
        '%%               no arguments), which is then run in the',...
            ' base workspace.\n',...
        '%% 6) SPMweb:    Opens http://www.fil.ion.ucl.ac.uk/spm/',...
            ' in your web browser.\n',...
        '%%               See MATLAB `web` command for details.\n',...
        '%s\n%%\n%% Andrew Holmes\n'],Usep,Usep);
elseif strcmp(Topic,'QuitSPM')
    S = sprintf([...
        '\n%% Quit SPM and cleanup the MATLAB workspace\n',...
        '%s\n%%\n',...
        '%% Closes all windows, clears workspace variables,',...
            ' global variables\n',...
        '%% compiled functions and MEX links. This leaves',...
            ' MATLAB in "startup" condition\n',...
        '%% except that it doesn''t release the memory claimed',...
            ' during the session.\n',...
        '%% You need to `quit` MATLAB to release it''s memory.',...
            ' It is advisable to do.\n',...
        '%% reasonably frequently, especially after large',...
            ' analyses.\n',...
        '%%\n',...
        '%% It is *not* necessary to quit SPM after an SPM error.',...
            ' Simply `clear` the \n',...
        '%% workspace (type `clear` in the MATLAB command window)',...
            ' and clear the\n',...
        '%% "Results" and "Interactive" with the `clear` button',...
            ' in the "Results" window.\n',...
        '%% (SPMs defaults are held as global variables.)\n',...
        '%%\n',...
        '%% The `Close` button in the "Help" window merely hides',...
            ' the SPMhelp window.\n',...
        '%%\n',...
        '%s\n%%\n%% The FIL methods group\n'],Usep,Usep);
else
    doc = spm_jobman('help',Topic);
    if ~isempty(doc),
        doc = char(doc{:});
        doc = [repmat('% ',size(doc,1),1) doc repmat(sprintf('\n'),size(doc,1),1)]';
        S   = doc(:)';
    else
        S = sprintf([...
            '\n%% ! - Topic not found\n',...
            '%s\n%%\n',...
            '%% This topic is not recognised by the help system.\n',...
            '%s\n%%\n'],Usep,Usep);
        Err = 1;
    end
end
varargout = {S,Err};


case '!topic'
%=======================================================================
% spm_help('!Topic',Topic)
if nargin<2, Topic='MenuWin'; else Topic=varargin{2}; end

%-Find (or create) help window.
%-----------------------------------------------------------------------
Fhelp = spm_figure('FindWin','Help');
if isempty(Fhelp)
    Fhelp = spm_help('!Create');
else
    set(Fhelp,'Visible','on')
end
set(Fhelp,'Pointer','Watch')
HD = get(Fhelp,'UserData');

%-Sort out integer Topic parameters from uicontrol CallBacks
%-----------------------------------------------------------------------
%-PrevTopics passes Topic as PullDown value, Back button passes -1
if ~ischar(Topic)
    PrevTopics = get(HD.hPrevTopics,'String');
    if Topic<0
        %-Go back to last topic - find PrevTopics pulldown
        if isempty(get(HD.hTopic,'String'))
            %-Topic string is empty - no topic displayed
            % go to last displayed topic (if there was one)
            Topic = min(size(PrevTopics,1),2);
        else
            %-Current topic is second, previous is third
            Topic = min(size(PrevTopics,1),3);
        end
    end
    if Topic==1, set(Fhelp,'Pointer','Arrow'), return, end
    if Topic>2, PrevTopics(2:Topic-1,:)=[]; end
    Topic = deblank(PrevTopics(2,:));
    bDonePrevTopics = 1;
else
    bDonePrevTopics = 0;
end
bMenuWin = strcmp(Topic,'MenuWin');

%-Load text file or get text from 'ShortTopics'
%-----------------------------------------------------------------------
Fname = which(Topic);           %-Try to find file on MATLABPATH
if isempty(Fname) || ...        %-No such file
    exist(Fname,'file')==3      %-Watch out for MEX files!
    Fname = which([Topic,'.m']);    %-if MEX, try *.m file
end
fid = fopen(Fname,'rt');            %-Try to open file

if fid<0                %-No file - try 'ShortTopics'
    [S,Err] = spm_help('!ShortTopics',Topic);
else                    %-Read help text from file
    S = fread(fid,'*char')';
    Err = 0;
    fclose(fid);
end

%-Display the current help comments
%-----------------------------------------------------------------------
spm_help('!Disp',Topic,S,Fhelp);

%-Display MenuWin graphic if required
%-----------------------------------------------------------------------
if bMenuWin
    spm_help('!DrawMenuWin')
end

%-Sort out control objects
%-----------------------------------------------------------------------
set(HD.hTopic,'String',Topic);

%-If unknown topic then return
%-----------------------------------------------------------------------
if Err, set(Fhelp,'Pointer','Arrow'), return, end

%-Sort out previous topics pulldown
%-For "PrevTopics" & "Back" buttons we did this above
%-----------------------------------------------------------------------
if ~bDonePrevTopics
    PrevTopics = get(HD.hPrevTopics,'String');
    Prompt     = PrevTopics(1,:); PrevTopics(1,:)=[];
    %-Add current topic to previous topics if not same as one before
    if ~strcmp(Topic,deblank(PrevTopics(1,:)))
        PrevTopics = char(Topic,PrevTopics);
    end
    % %-Delete any replications of Topic within PrevTopics
    % if size(PrevTopics,1)>1
    %   IDRows = 1+find(all( PrevTopics(2:size(PrevTopics,1),:) ==...
    %       repmat(PrevTopics(1,:),size(PrevTopics,1)-1,1),2));
    %   PrevTopics(IDRows,:)=[];
    % end
    %-Truncate to 20 items max
    if size(PrevTopics,1)>20, PrevTopics(21:size(PrevTopics,1),:)=[]; end
    PrevTopics=char(Prompt,PrevTopics);
end
%-Update popup
set(HD.hPrevTopics,'String',PrevTopics,'Value',1)

%-Find referenced topics
%-----------------------------------------------------------------------
RefdTopics = cellstr(get(HD.hRefdTopics,'String'));
RefdTopics = {RefdTopics{1};Topic}; %-Add current topic at top of references
q     = findstr(S,'spm_');      %-Find 'spm_' strings
for i = 1:length(q)
    d = (0:31) + q(i);          %-32 is max "spm_*" length considered
    Q = S(d(d <= length(S)));       %-string (len<=32) starting "spm_"
    d = find(Q==';'|Q=='('|Q==')'|Q==10|Q=='.'|Q==','|Q==' ');
    if length(d)            %-Look for filename extensions
    if any(strncmp(Q(min(d):end),{'.man','.txt'},4))
        Q = Q(1:min(d)+3);
    elseif any(strncmp(Q(min(d):end),{'.c','.h'},2))
        Q = Q(1:min(d)+1);
    else
        Q = Q(1:min(d)-1);
    end
    if exist(Q,'file') == 2 && ~any(strcmp(RefdTopics,Q))
        RefdTopics = [RefdTopics;{Q}]; end
    else
    warning('spm_* string end not found - neglecting reference')
    end
end
RefdTopics(2)=[];           %-Delete current Topic from references
%-Update popup
set(HD.hRefdTopics,'String',RefdTopics,'Value',1)

set(Fhelp,'Pointer','Arrow')



case '!disp'
%=======================================================================
% spm_help('!Disp',Fname,S,F,TTitle)
if nargin<5, TTitle=''; else TTitle=varargin{5}; end
if nargin<4, F='Help'; else F=varargin{4}; end
if nargin<3, S=''; else S=varargin{3}; end
if nargin<2, Fname='spm.man'; else Fname=varargin{2}; end
if isempty(TTitle), TTitle=Fname; end


%-Find (or create) window to print in
Fhelp = spm_figure('FindWin',F);
if isempty(Fhelp)
    Fhelp = spm_help('!CreateHelpWin');
else
    set(Fhelp,'Visible','on');
end
FS = spm('FontSizes');
PF = spm_platform('fonts');
set(Fhelp,'Pointer','Watch')
spm_help('!Clear',Fhelp)

%-Parse text file/string
%-----------------------------------------------------------------------
if isempty(S)
    %-Load text file or get text from 'ShortTopics'
    fid = fopen(Fname,'rt');
    if fid<0
        [S,Err] = spm_help('!ShortTopics',Fname);
    else
        S = fread(fid,'*char')';
        % Err = 0;
        fclose(fid);
    end
end
q     = min([length(S),findstr(S,char([10 10]))]);  % find empty lines
q     = find(S(1:q(1)) == 10);              % find line breaks

figure(Fhelp)
hAxes = axes('Position',[0.028,0.05,0.85,0.85],...
        'DefaultTextInterpreter','none',...
        'Units','Points','Visible','off');
AxPos = get(hAxes,'Position'); set(hAxes,'YLim',[0,AxPos(4)])

dy = FS(10)*1.2; y0 = floor(AxPos(4)) -dy;

text(-0.03,y0,TTitle,'FontSize',FS(14),'FontWeight','bold');
y     = y0 - FS(14);


%-Loop over pages & lines of text
%-----------------------------------------------------------------------
FmtLine = 1;
for i = 1:(length(q) - 1)
    d = S((q(i) + 1):(q(i + 1) - 1));

    %-Display help text lines
    if d(1) == abs('%');
        %-For some reason, '|' characters cause a CR.
        d = strrep(d,'|','I');
        h = text(0,y,d(2:length(d)),...
            'FontName',PF.courier,'FontSize',FS(9));
        if FmtLine
            set(h,'FontWeight','bold',...
                'FontName',PF.times,'FontSize',FS(10));
            y = y - FS(8);
            FmtLine=0;
        end
        y = y - dy;
    end

    %-Paginate if necessary
    if y<0
        text(0.5,-10,['Page ',num2str(length(hAxes))],...
            'FontSize',FS(8),'FontAngle','Italic')
        spm_figure('NewPage',[hAxes(end);get(hAxes(end),'Children')])
        hAxes = [hAxes,axes('Units','Points','Position',AxPos,...
                'DefaultTextInterpreter','none',...
                'YLim',[0,AxPos(4)],'Visible','off')];
        y     = y0;
    end
end

%-Register last page if paginated
if length(hAxes)>1
    text(0.5,-10,sprintf('Page %d/%d',length(hAxes)*[1,1]),...
        'FontSize',FS(8),'FontAngle','italic')
    spm_figure('NewPage',[hAxes(end);get(hAxes(end),'Children')])
end

set(Fhelp,'Pointer','Arrow')



case '!create'
%=======================================================================
% F = spm_help('!Create')
%-Condition arguments

F = spm_help('!CreateHelpWin');
spm_help('!CreateBar',F)
spm_figure('WaterMark',F,spm('Ver'),'WaterMark',-45,1)
varargout = {F};



case '!createhelpwin'
%=======================================================================
% F = spm_help('!CreateHelpWin')

F = spm_figure('FindWin','Help');
if any(F), return, end

%-Draw window
%-----------------------------------------------------------------------
WS     = spm('WinScale');           %-Window scaling factors
FS     = spm('FontSizes');          %-Scaled font sizes
PF     = spm_platform('fonts');     %-Font names (for this platform)
S0     = spm('WinSize','0',1);      %-Screen size (of the current monitor)


F      = figure('IntegerHandle','off',...
    'Position',[S0(1)+S0(3)/2,S0(2),0,0] + [-300 008 600 865].*WS,...
    'Resize','off',...
    'Name',sprintf('%s%s: SPMhelp',spm('ver'),spm('GetUser',' (%s)')),...
    'NumberTitle','off',...
    'Tag','Help',...
    'MenuBar','none',...
    'Units','Pixels',...
    'DefaultTextInterpreter','none',...
    'DefaultTextFontName',PF.helvetica,...
    'DefaultTextFontSize',FS(12),...
    'DefaultUicontrolFontName',PF.helvetica,...
    'DefaultUicontrolFontSize',FS(12),...
    'DefaultUicontrolInterruptible','on',...
    'Color','w',...
    'ColorMap',gray(64),...
    'DefaultTextColor','k',...
    'DefaultAxesColor','w',...
    'DefaultAxesXColor','k',...
    'DefaultAxesYColor','k',...
    'DefaultAxesZColor','k',...
    'DefaultAxesFontName',PF.helvetica,...
    'DefaultPatchFaceColor','k',...
    'DefaultPatchEdgeColor','k',...
    'DefaultSurfaceEdgeColor','k',...
    'DefaultLineColor','k',...
    'PaperType','A4',...
    'PaperUnits','normalized',...
    'PaperPosition',[.0726 .0644 .854 .870],...
    'InvertHardcopy','off',...
    'Visible','on');
varargout = {F};



case '!createbar'
%=======================================================================
% spm_help('!CreateBar',F)
%-----------------------------------------------------------------------
% Print | Clear | Current Topic     | Back | Menu | Help | SPMweb
% About SPMver  | Referenced Topics |   Previous Topics  | Close
%-----------------------------------------------------------------------

% if nargin<2, F='Help'; else F=varargin{2}; end
F = spm_figure('FindWin','Help');
if isempty(F)
    error('Help figure not found')
elseif ~strcmp(get(F,'Tag'),'Help')
    error('Specified figure is not an SPM Help window')
end

%-Get position and size parameters
%-----------------------------------------------------------------------
cF    = get(0,'CurrentFigure');
set(0,'CurrentFigure',F)
set(F,'Units','Pixels');
P     = get(F,'Position'); P = P(3:4);      % Figure dimensions {pixels}
S_Gra = P./[600,865];               % x & y scaling coefs

nBut  = 11;
nGap  = 4;
sx    = floor(P(1)./(nBut+(nGap+2)/6));     % uicontrol object width
dx    = floor(2*sx/6);              % inter-uicontrol gap
sy    = floor(20*S_Gra(1));         % uicontrol object height
x0    = dx/2;                   % initial x position
x     = dx/2;                   % uicontrol x position
y     = P(2) - sy;              % uicontrol y position
y2    = P(2) - 2.25*sy;             % uicontrol y position
FS    = round(10*min(S_Gra));            % uicontrol font size

%-Delete any existing HelpBar objects
%-----------------------------------------------------------------------
spm_figure('Clear',F,'HelpBar')

%-Create Frame for controls
%-----------------------------------------------------------------------
uicontrol(F,'Style', 'Frame',...
    'Position',[-4 (P(2) - 2.50*sy) P(1)+8 2.50*sy+4],...
    'Tag','HelpBar','HandleVisibility','callback');

%-Create uicontrol objects
%-----------------------------------------------------------------------
uicontrol(F,'String','Print' ,'Position',[x y sx sy],...
    'ToolTipString','print topic',...
    'FontSize',FS,...
    'CallBack','spm_figure(''Print'',[])',...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor','b'); x = x+sx;

uicontrol(F,'String','Clear' ,'Position',[x y sx sy],...
    'ToolTipString','clear topic',...
    'FontSize',FS,...
    'CallBack','spm_help(''!Clear'',gcf)',...
    'Interruptible','off','BusyAction','cancel',...
        'Tag','HelpBar','HandleVisibility','callback',...
        'ForegroundColor','b'); x = x+sx+dx;

uicontrol(F,'String',sprintf('About %s',spm('Ver')),...
    'ToolTipString','about this release of SPM',...
    'FontSize',FS,...
    'Position',[x0 y2 2*sx sy],...
    'HorizontalAlignment','Center',...
    'CallBack','spm_help(''spm.man'')',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor',[0 0.5 0])

uicontrol(F,'Style','Text','String','Topic ',...
    'FontSize',FS,...
    'Position',[x y sx sy],...
    'HorizontalAlignment','Right',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor','k')

hRefdTopics = uicontrol(F,'Style','PopUp',...
    'ToolTipString','topics referenced by the current topic',...
    'FontSize',FS,...
    'Position',[x-1,y2-1,4*sx+1,sy],...
    'String',{'Referenced Topics...'},...
    'CallBack',...
        'spm_help(''!PullDownTopic'')',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'HorizontalAlignment','Left',...
    'ForegroundColor','k'); x = x+sx;

hTopic = uicontrol(F,'Style','Edit','String','',...
    'ToolTipString','type/edit topic name here & press RETURN',...
    'FontSize',FS,...
    'Position',[x y 3*sx sy],...
    'CallBack','spm_help(get(gco,''String''))',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor','k','BackgroundColor',[.8,.8,1],...
    'HorizontalAlignment','Center'); x = x+3*sx+dx;

uicontrol(F,'String','Back',   'Position',[x y sx sy],...
    'ToolTipString','return to last topic',...
    'FontSize',FS,...
    'CallBack','spm_help(''!Topic'',-1)',...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback')

hPrevTopics = uicontrol(F,'Style','PopUp',...
    'ToolTipString','return to a previous topic',...
    'FontSize',FS,...
    'Position',[x-1,y2-1,3*sx+2*dx+1,sy],...
    'String',char('Previous Topics...','MenuWin'),...
    'CallBack',...
    'if get(gcbo,''Value'')~=1,spm_help(get(gcbo,''Value'')),end',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'HorizontalAlignment','Left',...
    'ForegroundColor','k'); x = x+sx+dx;

uicontrol(F,'String','Menu',   'Position',[x y sx sy],...
    'ToolTipString','draw SPMmenu for exploring help',...
    'FontSize',FS,...
    'CallBack','spm_help(''MenuWin'')',...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor',[0 0.5 0]), x = x+sx+dx;

uicontrol(F,'String','Help',   'Position',[x y sx sy],...
    'ToolTipString','help on using the SPMhelp browser',...
    'FontSize',FS,...
    'CallBack','spm_help(''spm_help.m'')',...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor',[0 0.5 0]), x = x+sx+dx;

uicontrol(F,'String','SPMweb', 'Position',[x y sx+dx/2 sy],...
    'ToolTipString',...
    'launch web browser - http://www.fil.ion.ucl.ac.uk/spm/',...
    'FontSize',FS,...
    'FontWeight','Bold','FontName',spm_platform('font','courier'),...
    'CallBack',['set(gcbf,''Pointer'',''Watch''),',...
            'web(''http://www.fil.ion.ucl.ac.uk/spm'');',...
            'set(gcbf,''Pointer'',''Arrow'')'],...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor','k')

uicontrol(F,'String','Close',   'Position',[x y2 sx+dx/2 sy],...
    'ToolTipString','close the SPMhelp browser',...
    'FontSize',FS,...
    'CallBack','spm_help(''!Quit'')',...
    'Interruptible','off','BusyAction','cancel',...
    'Tag','HelpBar','HandleVisibility','callback',...
    'ForegroundColor','r')


%-Store useful handles in UserData of Help figure
%-----------------------------------------------------------------------
set(F,'UserData',struct(...
    'hTopic',hTopic,...
    'hPrevTopics',hPrevTopics,...
    'hRefdTopics',hRefdTopics) )


%-Create FigureKeyPressFcn to edit Topic widget
%-----------------------------------------------------------------------
set(F,'KeyPressFcn',[...
    'spm_help(''!FigKeyPressFcn'',',...
        'getfield(get(gcbf,''UserData''),''hTopic''),',...
        'get(gcbf,''CurrentCharacter''))'] )

%-Reset CurrentFigure
set(0,'CurrentFigure',cF);


case '!pulldowntopic'
%=======================================================================
% spm_help('!PullDownTopic')
Topic = get(gcbo,'Value');
if Topic==1, return, end
Topics = get(gcbo,'String');
spm_help('!Topic',Topics{Topic})



case '!figkeypressfcn'
%=======================================================================
% spm_help('!FigKeyPressFcn',h,ch)
if nargin<2, error('Insufficient arguments'); else h=varargin{2};  end
if nargin<3, ch=get(gcf,'CurrentCharacter');  else ch=varargin{3}; end

tmp = get(h,'String');

if isempty(ch)
    %- shift / control / &c. pressed
    return
elseif abs(ch)==13
    %-Goto topic
    spm_help(tmp)
    return
elseif any(abs(ch)==32:126)
    tmp = [tmp, ch];
elseif abs(ch)==21
    %- ^U - kill
    tmp = '';
elseif any(abs(ch)==[8,127])
    %-BackSpace or Delete
    if ~isempty(tmp), tmp(length(tmp))=''; end
else
    %-Illegal character
    return
end
set(h,'String',tmp)



case '!clear'
%=======================================================================
% spm_help('!Clear',F)
%-Clear window, leaving 'ToolBar' 'Tag'ed objects, hiding 'HelpMenu'
% 'Tag'ged objects. Clear "Topic" widget.
%-Note: spm_help('!Disp') calls spm_help('!Clear'), so we might be
% working in the 'Graphics' window.

%-Sort out arguments
%-----------------------------------------------------------------------
if nargin<2, F='Help'; else F = varargin{2}; end
F=spm_figure('FindWin',F);
if isempty(F), return, end

%-If not 'Help' window, then just do a normal clear.
if ~strcmp(get(F,'Tag'),'Help'), spm_figure('Clear',F), return, end
HD = get(F,'UserData');

%-Clear figure & make any 'HelpMenu' objects invisible
%-----------------------------------------------------------------------
for h = findobj(get(F,'Children'),'Flat','HandleVisibility','on')'
    if ~strcmp(get(h,'Tag'),'HelpMenu'), delete(h), end
end
set(findobj(F,'Tag','HelpMenu'),'Visible','off')
try
    set(HD.hTopic,'String','');
    RefdTopics = cellstr(get(HD.hRefdTopics,'String'));
    set(HD.hRefdTopics,'Value',1,'String',RefdTopics{1})
end


case '!contexthelp'
%=======================================================================
% h = spm_help('!ContextHelp',Topic)

%-If no topic specified, use caller function
%-----------------------------------------------------------------------
if nargin<2
    st = dbstack;
    if length(st)>1, Topic=st(2).name; else Topic='MenuWin'; end
else
    Topic=varargin{2};
end


%-----------------------------------------------------------------------
Finter = spm_figure('FindWin','Interactive');
if spm('CmdLine')
    fprintf('\nSPM: Type `help %s` for help on this routine.\n',Topic)
    if nargout>0, varargout = {0}; end
elseif ~isempty(Finter)
    delete(findobj(Finter,'Tag','ContextHelp'))
    S2 = get(Finter,'Position');
    hAx = axes('Parent',Finter,...
        'Units','Pixels',...
        'Position',[S2(3)-23 05 20 25],...
        'Tag','ContextHelp',...
        'Visible','off');
    h = text(0.5,0.5,'?',...
        'Parent',hAx,...
        'Color','g',...
        'FontName',spm_platform('font','helvetica'),...
        'FontSize',spm('FontSize',14),...
        'FontWeight','bold','FontAngle','italic',...
        'HorizontalAlignment','Center',...
        'VerticalAlignment','middle',...
        'ButtonDownFcn',['spm_help(''',Topic,''')']);
    if nargout>0, varargout = {h}; end
end



otherwise
%=======================================================================
error('Unknown action string')

%=======================================================================
end
