function varargout=ma_interactive(varargin)
% Setup and callback functions for Interactive window
% FORMAT varargout=ma_figure(varargin)
%       - An embedded callback, multi-function function
%       - For detailed programmers comments, see format specifications
%         in main body of code
%_______________________________________________________________________
%
% ma_interactive creates and manages the 'Interactive' window. This window and
% these facilities may be used independently of SPM, and any number of
% Graphics windows my be used within the same MatLab session. (Though
% only one SPM 'Graphics' 'Tag'ed window is permitted.
%
% The Graphics window is provided with a menu bar at the top that
% facilitates editing and printing of the current graphic display,
% enabling interactive editing of graphic output prior to printing
% (e.g. selection of color maps, deleting, moving and editing graphics
% objects or adding text). (This menu is also provided as a figure
% background "ContextMenu" - right-clicking on the figure background
% should bring up the menu.)
%
% Print: Creates a footnote (detailing the SPM version, user & date)
% and evaluates defaults.printstr (see spm_defaults.m). Graphics windows with
% multi-page axes are printed page by page.
%
% Clear: Clears the Graphics window. If in SPM usage (figure 'Tag'ed as
% 'Graphics') then all SPM windows are cleared and reset.
%
% Colormap options:
% * gray, hot, pink: Sets the colormap to its default values and loads
%                 either a grayscale, 'hot metal' or color map.
% * gray-hot, etc: Creates a 'split' colormap {128 x 3 matrix}.
%          The lower half is a gray scale and the upper half
%          is 'hot metal' or 'pink'.  This color map is used for
% 	   viewing 'rendered' SPMs on a PET, MRI or other background images
%
% Colormap effects:
% * Invert: Inverts (flips) the current color map.
% * Brighten and Darken: Brighten and Darken the current colourmap
% 	   using the MatLab BRIGHTEN command, with  beta's of +0.2 and -0.2
% 	   respectively.
%
% Editing: Right button ('alt' button) cancels operations
% * Cut  : Deletes the graphics object next selected (if deletable)
%          Select with middle mouse button to delete blocks of text,
%          or to delete individual elements from a plot.
% * Move : To re-position a text, uicontrol or axis object using a
%          'drag and drop' implementation (i.e. depress - move - release)
%          Using the middle 'extend' mouse button on a text object moves
%          the axes containing the text - i.e. blocks of text.
% * Size : Re-sizes the text, uicontrol or axis object next selected
%          {left button - decrease, middle button  - increase} by a factor
%          of 1.24 (or increase/decrease FontSize by 2 dpi)
% * Text : Creates an editable text widget that produces a text object as
%          its CallBack.
%          The text object is provided with a ContextMenu, obtained by
%          right-clicking ('alt') on the text, allowing text attributes
%          to be changed. Alternatively, the edit facilities on the window
%          menu bar or ContextMenu can be used.
% * Edit : To edit text, select a text object with the circle cursor,
%          and edit the text in the editable text widget that appears.
%          A middle 'extend' mouse click places a context menu on the text
%          object, facilitating easy modification of text atributes.
%
% For SPM usage, the figure should be 'Tag'ed as 'Graphics'.
%
% For SPM power users, and programmers, ma_figure provides utility
% routines for using the SPM graphics interface. Of particular use are
% the GetWin, FindWin and Clear functions See the embedded callback
% reference in the main body of ma_figure, below the help text.
%
% See also: spm_print, spm_clf
%
%_______________________________________________________________________
% @(#)ma_figure.m	2.39 Andrew Holmes 03/05/16
% this code is borrowed from spm2 and modified by Antonia Hamilton

%=======================================================================
% - 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: `ma_figure Create` is           )
%( equivalent to `ma_figure('Create')`.                               )
%
% FORMAT F = ma_figure
% [ShortCut] Defaults to Action 'Create'
%
% FORMAT F = ma_figure(F) - numeric F
% [ShortCut] Defaults to ma_figure('CreateBar',F)
%
% FORMAT F = ma_figure('Create',Tag,Name,Visible)
% Create a full length WhiteBg figure 'Tag'ed Tag (if specified),
% with a ToolBar and background context menu.
% Equivalent to ma_figure('CreateWin','Tag') and ma_figure('CreateBar')
% Tag	  - 'Tag' string for figure.
% Name    - Name for window
% Visible - 'on' or 'off'
% F	  - Figure used
%
% FORMAT F = ma_figure('FindWin',F)
% Finds window with 'Tag' or figure numnber F - returns empty F if not found
% F	- (Input)  Figure to use [Optional] - 'Tag' string or figure number.
%	- Defaults to 'Graphics'
% F	- (Output) Figure number (if found) or empty (if not).
%
% FORMAT F = ma_figure('GetWin',Tag)
% Like ma_figure('FindWin',Tag), except that if 'Tag' is 'Graphics' or
% 'Interactive' and no such 'Tag'ged figure is found, one is created. Further,
% the "got" window is made current.
% Tag	- Figure 'Tag' to get, defaults to 'Graphics'
% F	- Figure number (if found/created) or empty (if not).
%
% FORMAT F = ma_figure('ParentFig',h)
% Finds window containing the object whose handle is specified
% h	- Handle of object whose parent figure is required
%	- If a vector, then first object handle is used
% F	- Number or parent figure
%
% FORMAT ma_figure('Clear',F,Tags)
% Clears figure, leaving ToolBar (& other objects with invisible handles)
% Optional third argument specifies 'Tag's of objects to delete.
% If figure F is 'Tag'ged 'Interactive' (SPM usage), then the window
% name and pointer are reset.
% F	- 'Tag' string or figure number of figure to clear, defaults to gcf
% Tags  - 'Tag's (string matrix or cell array of strings) of objects to delete
%         *regardless* of 'HandleVisibility'. Only these objects are deleted.
%         '!all' denotes all objects
%
% FORMAT str = ma_figure('DefPrintCmd')
% Returns default print command for SPM, as a string
%
% FORMAT ma_figure('Print',F)
% SPM print function: Appends footnote & executes PRINTSTR
% F	- [Optional] Figure to print. ('Tag' or figure number)
%	  Defaults to figure 'Tag'ed as 'Graphics'.
%	  If none found, uses CurrentFigure if avaliable.
% defaults.printstr - global variable holding print command to be evaluated
%	  Defaults to 'print -dps2 fig.ps'
% If objects 'Tag'ed 'NextPage' and 'PrevPage' are found, then the
% pages are shown and printed in order. In breif, pages are held as
% seperate axes, with ony one 'Visible' at any one time. The handles of
% the "page" axes are stored in the 'UserData' of the 'NextPage'
% object, while the 'PrevPage' object holds the current page number.
% See spm_help('!Disp') for details on setting up paging axes.
%
% FORMAT [hNextPage, hPrevPage, hPageNo] = ma_figure('NewPage',hPage)
% SPM pagination function: Makes objects with handles hPage paginated
% Creates pagination buttons if necessary.
% hPage	                        - Handles of objects to stick to this page
% hNextPage, hPrevPage, hPageNo - Handles of pagination controls
%
% FORMAT ma_figure('TurnPage',move,F)
% SPM pagination function: Turn to specified page
%
% FORMAT ma_figure('DeletePageControls',F)
% SPM pagination function: Deletes page controls
% F	- [Optional] Figure in which to attempt to turn the page
%         Defaults to 'Graphics' 'Tag'ged window
%
% FORMAT n = ma_figure('#page')
% Returns the current page number.
%
% FORMAT ma_figure('WaterMark',F,str,Tag,Angle,Perm)
% Adds watermark to figure windows.
% F	- Figure for watermark. Defaults to gcf
% str   - Watermark string. Defaults (missing or empty) to SPM
% Tag   - Tag for watermark axes. Defaults to ''
% Angle - Angle for watermark. Defaults to -45
% Perm  - If specified, then watermark is permanent (HandleVisibility 'off')
%
% FORMAT F = ma_figure('CreateWin',Tag,Name,Visible)
% Creates a full length WhiteBg figure 'Tag'ged Tag (if specified).
% F	  - Figure created
% Tag	  - Tag for window
% Name    - Name for window
% Visible - 'on' or 'off'
%
% FORMAT WS = ma_figure('GetWinScale')
% Returns ratios of current display dimensions to that of a 1152 x 900
% Sun display. WS=[Xratio,Yratio,Xratio,Yratio]. Used for scaling other
% GUI elements.
% (Function duplicated in spm.m, repeated to reduce inter-dependencies.)
%
% FORMAT FS = ma_figure('FontSizes',FS)
% Returns fontsizes FS scaled for the current display.
% FS     - (vector of) Font sizes to scale
%          [default [08,09,11,13,14,6:36]]
%
% FORMAT ma_figure('CreateBar',F)
% Creates toolbar in figure F (defaults to gcf). F can be a 'Tag'
% If the figure is 'Tag'ed as 'Graphics' (SPM usage), then the Print button
% callback is set to attempt to clear an 'Interactive' figure too.
%
% FORMAT ma_figure('ColorMap')
% Callback for "ColorMap" buttons
%
% FORMAT h = ma_figure('GraphicsHandle',F)
% GUI choose object for handle identification. LeftMouse 'normal' returns
% handle, MiddleMouse 'extend' returns parents handle, RightMouse 'alt' cancels.
% F - figure to do a GUI "handle ID" in [Default gcbf]
%_______________________________________________________________________

Colour = [0.8,0.8,1];
global search yn

%-Condition arguments
%-----------------------------------------------------------------------
if (nargin==0), Action = 'Create'; else, Action = varargin{1}; end

switch lower(Action), 
    
    case 'findwin'
        %=======================================================================
        % F=ma_figure('FindWin',F)
        % F=ma_figure('FindWin',Tag)
        %-Find window: Find window with FigureNumber# / 'Tag' attribute
        %-Returns empty if window cannot be found - deletes multiple tagged
        %figs.
        
        F = findobj(get(0,'Children'),'Flat','Tag','Interactive');
        if length(F) > 1
            % Multiple Interactive windows - close all but most recent
            close(F(2:end))
            F = F(1);
        end
        varargout = {F};
        
    case 'getwin'
        %=======================================================================
        % F=ma_figure('GetWin',Tag)
        
        F = ma_interactive('FindWin');
        
        if isempty(F)
            F = ma_interactive('Create');
        else
            set(0,'CurrentFigure',F);
        end
        varargout = {F};
        
    case 'parentfig'
        %=======================================================================
        % F=ma_interactive('ParentFig',h)
        if nargin<2, error('No object specified'), else, h=varargin{2}; end
        F = get(h(1),'Parent');
        while ~strcmp(get(F,'Type'),'figure'), F=get(F,'Parent'); end
        varargout = {F};
        
        
    case 'clear'
        %=======================================================================
        % ma_interactive('Clear',F,Tags)
        
        %-Sort out arguments
        %-----------------------------------------------------------------------
        F = ma_interactive('FindWin');
        if isempty(F), return, end
        
        %-Clear figure
        %-----------------------------------------------------------------------
        %-Clear figure of objects with 'HandleVisibility' 'on'
        pos = get(F,'Position');
        delete(findobj(get(F,'Children'),'flat','HandleVisibility','on'));
        drawnow
        set(F,'Position',pos);
        
        %-Reset figures callback functions
        set(F,'KeyPressFcn','',...
            'WindowButtonDownFcn','',...
            'WindowButtonMotionFcn','',...
            'WindowButtonUpFcn','')
        
        set(F,'Name','AMAT: ','UserData',[])
        set(F,'Pointer','Arrow')
        
        
%     case 'defprintcmd'
%         %=======================================================================
%         % ma_interactive('DefPrintCmd')
%         varargout = {'print -dpsc2 -painters -append -noui '};
%         
%         
%     case 'print'
%         %=======================================================================
%         % ma_interactive('Print',F)
%         
%         %-Find window to print, default to gcf if specified figure not found
%         % Return if no figures
%         F=ma_interactive('FindWin');
%         if isempty(F), F = get(0,'CurrentFigure'); end
%         if isempty(F), return, end
%         
%         %-Note current figure, & switch to figure to print
%         cF = get(0,'CurrentFigure');
%         set(0,'CurrentFigure',F)
%         
%         %-Construct print command
%         %-----------------------------------------------------------------------
%         global defaults
%         if ~isempty(defaults),
%             PRINTSTR = defaults.printstr;
%         else,
%             PRINTSTR = [ma_interactive('DefPrintCmd'),'amat.ps'];
%         end
%         
%         %-Temporarily change all units to normalized prior to printing
%         % (Fixes bizzarre problem with stuff jumping around!)
%         %-----------------------------------------------------------------------
%         H  = findobj(get(F,'Children'),'flat','Type','axes');
%         un = cellstr(get(H,'Units'));
%         set(H,'Units','normalized')
%         
%         %-Print
%         %-----------------------------------------------------------------------
%         err = 0;
%         if ~iPaged
%             printstr = clean_PRINTSTR(PRINTSTR);
%             try, eval(printstr), catch, err=1; end
%         else
%             hPg       = get(hNextPage,'UserData');
%             Cpage     = get(hPageNo,  'UserData');
%             nPages    = size(hPg,1);
%             
%             set([hNextPage,hPrevPage,hPageNo],'Visible','off')
%             if Cpage~=1
%                 set(hPg{Cpage,1},'Visible','off'), end
%             for p = 1:nPages
%                 set(hPg{p,1},'Visible','on');
%                 printstr = clean_PRINTSTR(PRINTSTR);
%                 try, eval(printstr), catch, err=1; end
%                 set(hPg{p,1},'Visible','off')
%             end
%             set(hPg{Cpage,1},'Visible','on')
%             set([hNextPage,hPrevPage,hPageNo],'Visible','on')
%         end
%         
%         if err
%             errstr = lasterr;
%             tmp = [find(abs(errstr)==10),length(errstr)+1];
%             str = {errstr(1:tmp(1)-1)};
%             for i = 1:length(tmp)-1
%                 if tmp(i)+1 < tmp(i+1) 
%                     str = [str, {errstr(tmp(i)+1:tmp(i+1)-1)}];
%                 end
%             end
%             str = {str{:},	'','- print command is:',['    ',printstr],...
%                     '','- current directory is:',['    ',pwd],...
%                     '','            * nothing has been printed *'};
%             spm('alert!',str,'printing problem...',sqrt(-1));
%         end
%         
%         set(H,{'Units'},un)
%         set(0,'CurrentFigure',cF)
        
        
    case {'create','createwin'}
        %=======================================================================
        % F=ma_interactive('CreateWin',Tag,Name,Visible)
        
        Visible = 'on';
        Name = 'Interactive';
        Tag = 'Interactive';
        
        %-Condition arguments
        %-----------------------------------------------------------------------
        % if nargin<4 | isempty(varargin{4}), Visible='on'; else, Visible=varargin{4}; end
        % if nargin<3, Name=''; else, Name = varargin{3}; end
        % if nargin<2, Tag='';  else, Tag  = varargin{2}; end
        
        S0   = get(0,'ScreenSize');
        WS = [S0(3)/1152 (S0(4)-50)/900 S0(3)/1152 (S0(4)-50)/900];  % window scale
        FS = ceil( (1:36)* (1 + 0.85*(min(WS)-1)) );  %% font size
        Rect = [155   465   435   465].*WS;
        PF   = spm_platform('fonts');			%-Font names (for this platform)
        
        F    = figure(...
            'Tag',Tag,...
            'Position',Rect,...
            'Resize','off',...
            'Color',Colour,...
            'ColorMap',gray(64),...
            'DefaultTextColor','k',...
            'DefaultTextInterpreter','none',...
            'DefaultTextFontName',PF.helvetica,...
            'DefaultTextFontSize',FS(12),...
            'DefaultAxesColor','w',...
            'DefaultAxesXColor','k',...
            'DefaultAxesYColor','k',...
            'DefaultAxesZColor','k',...
            'DefaultAxesFontName',PF.helvetica,...
            'DefaultPatchFaceColor','k',...
            'DefaultPatchEdgeColor','k',...
            'DefaultSurfaceEdgeColor','k',...
            'DefaultLineColor','k',...
            'DefaultUicontrolFontName',PF.helvetica,...
            'DefaultUicontrolFontSize',FS(10),...
            'DefaultUicontrolInterruptible','on',...
            'MenuBar','none',...
            'PaperType','A4',...
            'PaperUnits','normalized',...
            'PaperPosition',[.0726 .0644 .854 .870],...
            'InvertHardcopy','off',...
            'Renderer','zbuffer',...
            'NumberTitle','off',...
            'Name','AMAT: Interactive',...
            'Visible','off');
        
        set(F,'Visible',Visible)
        varargout = {F};
        %------------------------------------------------------------------
        
    case 'disp_text'
        %%%%%%%%%%%%%%%%%%
        %% display several lines of text
        %% from a cell array
        
        if(nargin<2)
            return;
        else
            info = varargin{2};
        end
        
        Finter = ma_interactive('GetWin');
        ma_interactive('clear');
        set(Finter,'Name','AMAT: Message')
        drawnow;
        
        hA = axes('Parent',Finter,'Visible','off',...
            'XLim',[0,10],'YLim',[0,15],'YDir','Reverse');
        
        for i=1:length(info)
            text(0,i,info{i},'Parent',hA);
        end    
        %------------------------------------------------------------------
        
    case 'yesno'
        
        if(nargin>1)
            qu = varargin{2};
        else
            return;
        end
        
        F = ma_interactive('GetWin');
        ma_interactive('clear');
        set(F,'Name','AMAT: Question')
        sz = get(F,'Position');
        
        wdth = sz(3)/4;
        pos1 = sz(3)/3-wdth/2;
        pos2 = 2*sz(3)/3-wdth/2;
        
        uicontrol(F,'Style','Text',...
            'String',qu,...
            'Tag',['Label_title'],...
            'UserData','',...
            'HorizontalAlignment','Center',...
            'Position',[sz(3)*0.1,sz(4)*0.75,sz(3)*0.8,30], ...
            'FontSize',spm('Fontsize',14),...
            'BackgroundColor',Colour);
        
        varargout{1} = [];
        yn = [];
        %% yes button
        uicontrol(F,'String','Yes', ...
            'TooltipString','Yes', ...
            'Position',[pos1,sz(4)/4,wdth,30],...
            'FontSize',spm('Fontsize',14),...
            'CallBack',['ma_interactive(''yes'')'],...
            'ForegroundColor',[1 0 0]);
        
        %% no button
        uicontrol(F,'String','No', ...
            'TooltipString','No', ...
            'Position',[pos2,sz(4)/4,wdth,30],...
            'CallBack',['ma_interactive(''no'')'],...
            'FontSize',spm('Fontsize',14),...
            'ForegroundColor',[1 0 0]);
        %------------------------------------------------------------------
        uiwait
        varargout{1} = yn;
        clear yn
        
    case 'yes'
        ma_interactive('clear');
        yn = 1;
        uiresume
%         %------------------------------------------------------------------
    case 'no'
        ma_interactive('clear');
        yn = 0;
        uiresume
%         %------------------------------------------------------------------
        
    case 'progress'
        if(nargin>1)
            prog = varargin{2}*100;  %% this should be a fraction
        else
            return;
        end
        if(nargin>2)
            ttl = varargin{3};
        else
            ttl = '';
        end
        
        ma_interactive('clear');
        if(prog>-1 & prog <101)
            prog = round(prog);
            ang = fliplr(linspace(pi/2,2.5*pi,100));
            cx = cos(ang);
            cy = sin(ang);
            
            F = ma_interactive('GetWin');
            axes('Parent',F,'XLim',[-1.5,1.5],'YLim',[-1.5,1.5],'Visible','off')
            h=patch(cx,cy,[1,1,1],'EdgeColor',[1,1,1]);
            hold on
            patch([0,cx(1:prog)],[0,cy(1:prog)],[0.3 0.3 0.6],'EdgeColor',[0.3 0.3 0.6])
            text(0,1.4,ttl,'FontSize',spm('FontSize',12), ...
                'HorizontalAlignment','Center')
            if(prog<100)
                text(0,1.2,'Working ...','FontSize',spm('FontSize',12), ...
                    'HorizontalAlignment','Center')
            else
                text(0,1.2,'Done','FontSize',spm('FontSize',12), ...
                    'HorizontalAlignment','Center')
            end
            drawnow;
        end
        

    otherwise
        %=======================================================================
        warning(['Illegal Action string: ',Action])
end
return;
%=======================================================================



%=======================================================================
function copy_menu(F,G)
%=======================================================================
handles = findobj(get(F,'Children'),'Flat','Type','uimenu','Visible','on');
if length(handles)==0, return; end;
for F1=handles',
    if ~strcmp(get(F1,'Label'),'&Window'),
        G1 = uimenu(G,'Label',get(F1,'Label'),...
            'CallBack',get(F1,'CallBack'),...
            'Position',get(F1,'Position'),...
            'Separator',get(F1,'Separator'));
        copy_menu(F1,G1);
    end;
end;
return;
%=======================================================================


%=======================================================================
function PRINTSTR = clean_PRINTSTR(PRINTSTR)
%=======================================================================
% Matlab 6.5 printing doesn't like the -append option if the file does
% not already exist
%-----------------------------------------------------------------------
off = findstr('-append',PRINTSTR);
if ~isempty(off),
    bl = [0 find(isspace(PRINTSTR)) (length(PRINTSTR)+1)];
    for i=1:(length(bl)-1),
        ca{i} = PRINTSTR((bl(i)+1):(bl(i+1)-1));
    end;
    ca = strvcat(ca);
    off1 = find(ca(:,1)~='-'); % either 'print' or a filename
    if length(off1)>1,
        fname = deblank(ca(off1(end),:));
        
        % If there is no path to the file, then make it the
        % current directory
        [pth,nam,ext] = fileparts(fname);
        if isempty(pth), fname = ['.' filesep nam ext]; end;
        
        fd = fopen(fname,'r');
        if fd~=-1,
            % File exists, so -append can be used
            fclose(fd);
        else,
            % File does not exist, so remove -append option
            PRINTSTR(off:(off+7))='';
        end;
    end;
end;
