function out1 = wshowdrv(option,in2,in3,in4);
%WSHOWDRV A slide show shell.
%   WSHOWDRV works with the helper functions, 
%   to build a graphical user interface around a linear, page by page
%   demo. 

%   M. Misiti, Y. Misiti, G. Oppenheim, J.M. Poggi 12-Mar-96.
%   Last Revision: 17-Apr-1998.
%   Copyright (c) 1995-98 by The MathWorks, Inc.
% $Revision: 1.6 $

% UserData usage:
% The figure UserData contains a list of all uicontrol handles.
% The Console frame UserData holds the pause status for the demos.
% The text window UserData holds the name of the current script.

% Possible options :
%-------------------
% stop
% pause
% setactfig
% getactfig
% init
% disp
% set_axes
% get_axes
% put
% get
%
% startreset
% info
%-------------------

if strcmp(option,'stop'),
    figNumber = in2;
    stopFlag = 0;
    if figNumber
        wait = 0;
        stop = -1;
        if ~ishandle(figNumber) , out1 = 1; return;end
        figure(figNumber);
        hndlList  = get(figNumber,'UserData');
        startHndl = hndlList(2);
        contHndl  = hndlList(3);
        stopHndl  = hndlList(4);
        autoHndl  = hndlList(5);
        helpHndl  = hndlList(6);
        closeHndl = hndlList(7);
        cfraHndl  = hndlList(8);
        if get(cfraHndl,'Userdata')==stop,
                set([startHndl helpHndl closeHndl],'Enable','on');
                set([stopHndl contHndl],'Enable','off');
                stopFlag = 1;
        else
                stopFlag = 0;
        end;
    end
    out1 = stopFlag;
    return
end

if strcmp(option,'pause'),
    figNumber = in2;
    if figNumber==0,
        stopFlag = 0;
        if nargin==3
            if in3==1
                disp(' ');
                disp(' Press any key to continue');
                pause
                clc; disp('                  ')
            else
                pause(3);               
            end
        else
            pause(in4);
        end
    else
        wait = 0;
        stop = -1;
        if ~ishandle(figNumber) , out1 = 1; return;end
        figure(figNumber);
        hndlList  = get(figNumber,'UserData');
        startHndl = hndlList(2);
        contHndl  = hndlList(3);
        stopHndl  = hndlList(4);
        autoHndl  = hndlList(5);
        helpHndl  = hndlList(6);
        closeHndl = hndlList(7);
        cfraHndl  = hndlList(8);

        % ====== Start Wait Loop
        % Strangely enough, we want to turn off the watch pointer
        set(figNumber,'Pointer','arrow');
        if get(autoHndl,'Value'),
        % If the autoHndl flag is set, don't wait for the user, just
        % pause a little and then continue.
            if nargin<4
                pause(2);
            else
                set(cfraHndl,'Userdata',wait);
                continu = 1 & (in4>0);
                while continu
                    % holding loop can be exited w/Cont or Stop button.
                    if ~ishandle(figNumber) , out1 = 1; return; end
                    continu = get(cfraHndl,'Userdata')==wait & (in4>0);
                    pause(1); in4 = in4-1; 
                    drawnow
                end;
            end
        else
            set(cfraHndl,'Userdata',wait);
            continu = 1;
            while continu
                % holding loop can be exited w/Cont or Stop button.
                if ~ishandle(figNumber) , out1 = 1; return; end
                continu = get(cfraHndl,'Userdata')==wait;
                drawnow
            end;
        end;

        if ~ishandle(figNumber) , out1 = 1; return; end
        if get(cfraHndl,'Userdata')==stop,
            set([startHndl helpHndl closeHndl],'Enable','on');
            set([stopHndl contHndl],'Enable','off');
            stopFlag = 1;
        else
            stopFlag = 0;
        end;

        % Now turn the watch back on
        set(figNumber,'Pointer','watch');
        % ====== End Wait Loop

    end
    out1 = stopFlag;
    return;
end

if strcmp(option,'setactfig'),
    % figNumber = in2;
    if in2==0 , return; end
    wmemtool('wmb',in2,'Activefig',1,in3);
    return
end

if strcmp(option,'getactfig'),
    % figNumber = in2;
    if in2==0 , return; end
    out1 = wmemtool('rmb',in2,'Activefig',1);
    return
end

if strcmp(option,'init'),
    figNumber = in2;
    % If figNumber is zero, the demo will run without the GUI shell.
    if figNumber==0,
        % The stopFlag must be set to one even though in this case the demo
        % will NOT stop. This allows the first screen to plot properly when
        % running the demo from the command line.
        stopFlag = 1;
    else
        figure(figNumber);
        if ~ishandle(figNumber) , return; end
        hndlList  = get(figNumber,'UserData');
        startHndl = hndlList(2);
        % The UserData for the Start button is the Init Flag.
        % If it is high, then we SHOULD set stopFlag to high (and thus
        % exit the demo script early).

        if get(startHndl,'UserData'),
            % Set the UserData of the start button.
            set(startHndl,'UserData',0,'String','Start','Interruptible','On');
            stopFlag = 1;
        else
            % If the initialization screen has already been placed,
            % then keep executing the script.
            stopFlag = 0;
            % Once we start the slide show, the Start button should
            % change to a "Reset" button. Also, set its "interruptible"
            % property to off so we don't cause problems later on with
            % user double-clicks.
            set(startHndl,'String','Reset','Interruptible','Off');
        end;
    end
    out1 = stopFlag;
    return
end

if strcmp(option,'disp'),
    figNumber = in2;
    string = in3;
    if figNumber==0
        Intxt = 0;
    else
        if ~ishandle(figNumber) , return; end
        hndlList = get(figNumber,'UserData');
        txtHndl  = hndlList(1);
        vis = get(txtHndl,'Visible');
        Intxt = strcmp(vis(1:2),'on');  
    end 
    if Intxt==0
        clc
        disp(' ');
        disp(string);
        disp(' ');
    else
        set(txtHndl,'String',string);
    end
    return
end

if strcmp(option,'set_axes'), 
    % in2 = fig (gcf if in2 = 0 and figNumber otherwise)   
    figNumber = in2;
    axes_mat  = in3;
    if figNumber
        if ~ishandle(figNumber) , return; end
        hndlList = get(figNumber,'UserData');
        delete(findobj(figNumber,'type','axes'))
        set(figNumber,'UserData',hndlList(1:8));
    else
        delete(findobj(gcf,'type','axes'))
    end
    if length(axes_mat)==0 , return; end
    nb_axes = prod(axes_mat);
    out1 = zeros(1,nb_axes);
    if length(axes_mat)==1 , axes_mat = [axes_mat 1]; end
    left_a = 0;    right_a = 1;
    bottom_a = 0;  top_a   = 1;
    dy_axe = 0.08; dx_axe  = 0.1;
    if figNumber
       right_a = 0.85;
       txtHndl   = hndlList(1);
       vis = get(txtHndl,'Visible');
       if strcmp(vis,'on')
          pos_t = get(txtHndl,'Position');
          bottom_a = pos_t(2)+pos_t(4);
       end
    end
    if figNumber , figure(figNumber); end
    h_axe = (top_a-bottom_a-(axes_mat(1)+1)*dy_axe)/axes_mat(1);
    w_axe = (right_a-left_a-(axes_mat(2)+1)*dx_axe)/axes_mat(2);
    num = 1;
    y_axe = top_a;
    for r = 1:axes_mat(1)
        y_axe = y_axe-h_axe-dy_axe;
        x_axe = left_a+dx_axe;
        for c = 1:axes_mat(2)
            pos_a = [x_axe y_axe w_axe h_axe];
            out1(num) = axes('Visible','off','Position',pos_a,'Userdata',num);
            num = num+1;
            x_axe = x_axe+w_axe+dx_axe;
        end
    end
    if figNumber
        set(figNumber,'UserData',[hndlList(1:8) out1]);
    end
    return
end

if strcmp(option,'get_axes'),
    % figNumber = in2;
    hndlList = get(in2,'UserData');
    ll = length(hndlList);
    if ll>8 , out1 = hndlList(9:ll); else , out1 = []; end
    return 
end

if strcmp(option,'put'),
    % figNumber = in2;
    wmemtool('wmb',in2,in3,1,in4);
    return 
end

if strcmp(option,'get'),
    % figNumber = in2;
    out1 = wmemtool('rmb',in2,in3,1);
    return 
end

% wshowdrv will automatically assume that the argument it is passed 
% is the name of a demo script if it is NOT EQUAL to either
% the reserved words "start" or "info".

% Information regarding the play status will be held in
% the axis user data according to the following table:
play =  1;
wait =  0;
stop = -1;

% The variable DRVShowGUIFlag is used to let the demo script know that
% it is being called from within the GUI shell of wshowdrv. Otherwise, the
% demo script will echo text to the command window.
DRVShowGUIFlag = 1;

if strcmp(option,'startreset'),
    figNumber = in2;
    hndlList  = get(figNumber,'Userdata');
    txtHndl   = hndlList(1);
    startHndl = hndlList(2);
    if strcmp(get(startHndl,'String'),'Start'),
         wshowdrv('start',figNumber);
    else
        % We must be resetting the demo ...
        scriptName = get(txtHndl,'UserData');
        % Reset the Init Flag to force redrawing the initial screen.
        %-----------------------------------------------------------
        txtHndl   = hndlList(1);
        set(txtHndl,'string','');
        active_fig = wshowdrv('getactfig',figNumber);
        axesinfig = findobj(active_fig,'type','axes');
        if active_fig~=figNumber
                set(findobj(axesinfig),'Visible','off');
        else
                delete(axesinfig)
                set(figNumber,'UserData',hndlList(1:8));
        end
        %----------------------------------------------------------
        set(startHndl,'UserData',1);
        eval(scriptName);
    end

elseif strcmp(option,'start'),
    figNumber = in2;
    hndlList  = get(figNumber,'Userdata');
    txtHndl   = hndlList(1);
    startHndl = hndlList(2);
    contHndl  = hndlList(3);
    stopHndl  = hndlList(4);
    autoHndl  = hndlList(5);
    infoHndl  = hndlList(6);
    closeHndl = hndlList(7);
    cfraHndl  = hndlList(8);
    set(cfraHndl,'Userdata',wait);
    set([startHndl infoHndl closeHndl contHndl],'Enable','off');
    set([contHndl stopHndl],'Enable','on');

    % ====== Start of Demo
    
    set(figNumber,'Pointer','watch');
    scriptName = get(txtHndl,'UserData');
    eval(scriptName);
    if ~ishandle(figNumber) , return; end
    set(figNumber,'Pointer','arrow');

    % ====== End of Demo
    set([startHndl infoHndl closeHndl contHndl],'Enable','on');
    set([stopHndl contHndl],'Enable','off');

elseif strcmp(option,'info'),
    figNumber = in2;
    active_fig = wshowdrv('getactfig',figNumber);
    hndlList = get(figNumber,'Userdata');
    txtHndl  = hndlList(1);
    ttlStr   = 'Slide Show Info';
    if active_fig==figNumber
       hlpStr1 = ...                                                       
        ['                                                '  
         ' This window is a Slide Show Driver.            '  
         '                                                '  
         ' The actions of the buttons are summarized      '
         ' below:                                         '  
         '                                                '  
         ' "Start" begins the slide show.                 '  
         ' "Next" proceeds to the next slide.             '  
         ' "Stop" halts the slide show.                   '  
         ' "Autoplay" lets the show play automatically.   '
         '                                                '];
     else
       hlpStr1 = ...                                                       
        ['                                                '  
         ' This window is a Slide Show Driver.            '  
         '                                                '  
         ' The actions of the buttons are summarized      '
         ' below:                                         '  
         '                                                '  
         ' "Start" begins the slide show.                 '  
         ' "Next" proceeds to the next slide.             '  
         ' "Stop" halts the slide show.                   '  
         ' "Autoplay" lets the show play automatically.   '
         '                                                '  
         '                ***  CAUTION ***                '  
         ' There is a normal way to go through the demo.  '  
         ' If ever you follow another path, which is      '
         ' always possible, when over, the best is to     '
         ' Stop, Reset and Start again.                   '  
         '                                                '  
         '                                                '];
    end
    hlpStr2 = ...                                                
        ['                                                  '  
         ' You should be aware that when you are            '  
         ' running a slide show (from the time after you    '  
         ' press the "Start" button until either the slide  '  
         ' show is complete or you end the slide show       '  
         ' with the "Stop" button) you will NOT be able     '  
         ' to execute commands from the command line,       '  
         ' since MATLAB will be busy executing a            '  
         ' demo script.                                     '  
         '                                                  '  
         ' For this reason it is strongly recommended       '  
         ' that you finish the slide show or end it by      '  
         ' pushing the "Stop" button before you begin       '  
         ' any other demos.                                 '];

    scriptName = get(txtHndl,'UserData');
    hlpStr1 = str2mat(hlpStr1,[' Now playing: ',scriptName,'.m']);
    whelpdem(ttlStr,hlpStr1,hlpStr2);                                           

else
    % in2 = showType
    % in3 = add close callback (optional)
    % in4 = add reset callback (optional)
    %------------------------------------
    % Turn the watch on for the old figure
    oldFigNumber = watchon;

    % Since the variable "option" is neither the word "start" nor the
    % word "info", it must be the name of a demo script.
    scriptName = option;

    showType   = in2;
    if strcmp(showType,'command')
        no_output = 1;
    else
        no_output = 0;
    end

    clc;
    %===================================
    % Now initialize the whole figure...
    pos_win = depOfMachine(no_output);

    [Def_DefColor,Def_FigColor] = ...
        mextglob('get','Def_DefColor','Def_FigColor');
    figNumber = colordef('new',Def_DefColor);
    set(figNumber,                              ...
        'Menubar','none',                       ...
        'Name','Slide Show Driver',             ...
        'NumberTitle','off',                    ...
        'Position',pos_win,                     ...
        'Color',Def_FigColor,                   ...
        'DefaultUicontrolFontWeight','bold',    ...
        'DefaultAxesFontWeight','bold',         ...
        'DefaultTextFontWeight','bold',         ...
        'Visible','off');

    %====================================
    % Display mixed, text, or graphics only based on showType
    % If the figure is to be text only, hide the axis.
    % If it is to be graphics only, hide the comment window.
    % Otherwise, we'll assume that figure is mixed
    defaultTextFontsize = wdfigutl('fontsize');
    switch showType
        case 'text'
            axesVisStatus  = 'off';
            textVisStatus  = 'on';
            textBoxTop     = 0.97;
            defaultAxesPos = [0.45 0.45 0.1 0.1];

        case 'graphic'
            axesVisStatus  = 'on';
            textVisStatus  = 'off';
            textBoxTop     = 0.35;
            defaultAxesPos = [0.10 0.10 0.65 0.8];

        case 'mixed'  
            axesVisStatus  = 'on';
            textVisStatus  = 'on';
            textBoxTop     = 0.40;
            defaultAxesPos = [0.10 0.50 0.65 0.43];

        case 'manual'
            axesVisStatus  = 'off';
            textVisStatus  = 'off';
            textBoxTop     = 0.40;
            defaultAxesPos = [0.10 0.10 0.65 0.8];

        case 'command'
            axesVisStatus  = 'off';
            textVisStatus  = 'off';
            textBoxTop     = 0.40;
            defaultAxesPos = [0.10 0.10 0.65 0.8];

        otherwise
            if strcmp(showType(1:3),'mix'), 
                nb =  showType(4:length(showType));
                nb = wstr2num(nb);
                if      isempty(nb) , nb = 1;
                elseif  nb<1 ,  nb = 1;
                elseif  nb>20 , nb = 20;
                end
                nb = (nb-11);
                linh = (0.40-0.03)/11;
                axesVisStatus  = 'on';
                textVisStatus  = 'on';
                dy             = nb*linh;
                textBoxTop     = 0.40+dy;
                defaultAxesPos = [0.10 0.50+dy 0.65 0.43-dy];
            else % mixed
                axesVisStatus  = 'on';
                textVisStatus  = 'on';
                textBoxTop     = 0.40;
                defaultAxesPos = [0.10 0.50 0.65 0.43];
            end
    end;

    set(figNumber,'DefaultAxesPosition',defaultAxesPos, ...
                  'DefaultTextFontsize',defaultTextFontsize, ...
                  'DefaultAxesFontsize',defaultTextFontsize);

    %===================================
    % Set up the axes
    axHndl = axes( ...
        'Units','normalized', ...
        'Userdata',stop, ...
        'Visible','off');

    %===================================
    % Set up the Comment Window
    top   = textBoxTop; bottom = 0.03;
    left  = 0.03;       right = 0.77; 
    labelHt = 0.00;
    spacing = 0.005;

    % First, the MiniCommand Window frame
    frmBorder = 0.015;
    frmPos = [left-frmBorder bottom-frmBorder ...
        (right-left)+2*frmBorder (top-bottom)+2*frmBorder];
    frmHndl = uicontrol( ...
        'Style','frame', ...
        'Units','normalized', ...
        'Position',frmPos, ...
        'Visible',textVisStatus, ...
        'BackgroundColor',[0.5 0.5 0.5]);
    % Then the editable text field
    txtPos  = [left bottom (right-left) top-bottom-labelHt-spacing];
    txtHndl = uicontrol( ...
        'Style','edit', ...
        'Units','normalized', ...
        'Max',10, ...
        'BackgroundColor',[1 1 1], ...
        'Visible',textVisStatus, ...
        'Position',txtPos,...
        'HorizontalAlignment','left');
    % Save the name of the file for future use
    set(txtHndl,'UserData',scriptName);

    %====================================
    % Information for all buttons
    labelColor = [0.8 0.8 0.8];
    if no_output
        bottom = 0.08; top  = 0.92;
        left = 0.1; right = 0.9; frmBorder = 0.05;
    else
        bottom = 0.03; top  = 0.97;
        left = 0.82; right = 0.97; frmBorder = 0.015;
    end
    btnWid = right-left;
    btnHt = 0.08;
    % Spacing between the button and the next command's label
    spacing = 0.04;
    
    %====================================
    % The CONSOLE frame
    yPos = bottom-frmBorder;
    frmPos = [left-frmBorder yPos btnWid+2*frmBorder (top-bottom)+2*frmBorder];
    cfraHndl = uicontrol( ...
        'Style','frame', ...
        'Units','normalized', ...
        'Position',frmPos, ...
        'UserData',stop, ...
        'BackgroundColor',[0.5 0.5 0.5]);

    %====================================
    % The START/RESET button
    btnNumber = 1;
    yPos = top-(btnNumber-1)*(btnHt+spacing);
    labelStr = 'Start';
    callbackStr = ['wshowdrv(''startreset'',' int2str(figNumber) ');'];
    if nargin==4
       callbackStr = [callbackStr in4];
    end

    % Generic button information
    btnPos = [left yPos-btnHt btnWid btnHt];
    startHndl = uicontrol( ...
        'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Interruptible','On', ...
        'UserData',1, ...
        'Callback',callbackStr);

    %====================================
    % The NEXT button
    btnNumber = 2;
    yPos = top-(btnNumber-1)*(btnHt+spacing);
    labelStr = 'Next';
    % Setting userdata to 1 (=play) will continue the demo.
    callbackStr = ['set(' num2mstr(cfraHndl) ',''Userdata'',1);'];
  
    % Generic button information
    btnPos = [left yPos-btnHt btnWid btnHt];
    contHndl = uicontrol( ...
        'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'Enable','off', ...
        'String',labelStr, ...
        'Callback',callbackStr);

    %====================================
    % The STOP button
    btnNumber = 3;
    yPos = top-(btnNumber-1)*(btnHt+spacing);
    labelStr = 'Stop';
    % Setting userdata to -1 (=stop) will stop the demo.
    callbackStr = ['set(' num2mstr(cfraHndl) ',''Userdata'',-1);'];
    
    % Generic button information
    btnPos = [left yPos-btnHt btnWid btnHt];
    stopHndl = uicontrol( ...
        'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'Enable','off', ...
        'String',labelStr, ...
        'Callback',callbackStr);

    %====================================
    % The AUTOPLAY button
    btnNumber = 4;
    yPos = top-(btnNumber-1)*(btnHt+spacing);
    labelStr = 'AutoPlay';
    % Setting this checkbox will run demo w/o stopping.
    
    % Generic button information
    btnPos = [left yPos-btnHt btnWid btnHt];
    autoHndl = uicontrol( ...
        'Style','checkbox', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'Enable','on', ...
        'String',labelStr);

    %====================================
    % The INFO button
    labelStr = 'Info';
    callbackStr = ['wshowdrv(''info'',' int2str(figNumber) ');'];
    infoHndl = uicontrol( ...
        'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',[left bottom+btnHt+spacing btnWid btnHt], ...
        'String',labelStr, ...
        'Callback',callbackStr);

    %====================================
    % The CLOSE button
    labelStr = 'Close';
    callbackStr = ['clc; delete(' int2str(figNumber) ');'];
    if nargin==3
       callbackStr = [callbackStr in3];
    end
    closeHndl = uicontrol( ...
        'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',[left bottom btnWid btnHt], ...
        'String',labelStr, ...
        'Callback',callbackStr);

    % The next line is a workaround for a Windows bug
    set([contHndl stopHndl],'Enable','off');
    hndlList = [txtHndl startHndl contHndl stopHndl ...
         autoHndl infoHndl closeHndl cfraHndl];
    set(figNumber, ...
        'HandleVisibility','Callback',...
        'CloseRequestFcn',callbackStr,...
        'Visible','on', ...
        'UserData',hndlList);

    % Executing the demo script is required now in order to initialize
    % the info text and the initial prompting text
    set(figNumber,'Pointer','watch');
    eval(scriptName);
    set(figNumber,'Pointer','arrow');
    watchoff(oldFigNumber);
    figure(figNumber);
    out1 = figNumber;
end

%-----------------------------------------------------------------
function varargout = depOfMachine(varargin)

no_output = varargin{1};
ShiftTop_Fig = mextglob('get','ShiftTop_Fig');
screen = get(0,'ScreenSize');
if no_output,
    height = 420; width = 240;
    if screen(4)<800
        height = height/2;
        width = 140;
    else
        height = height/1.5;
        width = 160;
    end
    left   = screen(3)*0.01;
    bottom = screen(4)-height-ShiftTop_Fig;
else
    height = 500; width  = 560;
    if screen(4)<height+ShiftTop_Fig , height = screen(4)-ShiftTop_Fig; end
    pos    = get(0,'DefaultFigurePosition');
    left   = (screen(3)-width)/2;
    bottom = screen(4)-height-ShiftTop_Fig;
end
varargout{1} = [left bottom width height];
%------------------------------------------------------------------
