function sbhndlmsgs(cmd,str,cursor) 
%SBHNDLMSGS Manages the message window.
%
%  SBHNDLMSGS creates a new figure or opens the existing one which
%  has been made invisible.
%  SBHNDLMSGS(CMD) is used internally for managing callback calls.
%
%  See also SBBOXERROR, SBBOXQUERY

% Initial coding by A. S. Bozin, 5-3-97.
% Copyright 1997-2000 The MathWorks, Inc.
% $Revision: 1.7 $ $Date: 2000/06/23 20:27:50 $

   % 
   % Handle input arguments, if any
   % 
   if (nargin == 0)
      cmd = 'create';
   end
   %
   % Everything depends on CMD argument
   %
   switch (cmd)
   case 'write'
      %
      % Write a message
      %
      if (nargin == 2)
	 cursor = 'scroll';
      end
      shh = get(0,'ShowHiddenHandles');
      set(0,'ShowHiddenHandles','on');
      hFig = findobj(get(0,'Children'),'flat','Tag','hndlmsgsTag');
      set(0,'ShowHiddenHandles',shh);
      % 
      % Check whether message window is available.
      % 
      if (length(hFig) == 1)
	 %
	 % Restore counter, handles and mode flag
	 %
	 ud = get(hFig,'UserData');
	 txtbuf = get(ud.slider,'UserData');
	 sldval = get(ud.slider,'Value');
	 if (ud.value ~= sldval)
	    k = 1:ud.ind;
	    set(ud.txtlin(k),{'String'},txtbuf(ud.buflen-ud.ind+k));
	    sldval = ud.value;
	    set(ud.slider,'Value',sldval);
	 end
	 switch (cursor)
	 case 'home'
	    %
	    % Move cursor to the home position
	    %
	    set(ud.txtlin,'String','');
	    set(ud.txtlin(1),'String',str);
	    txtbuf = cell(size(txtbuf));
	    txtbuf{ud.buflen} = str;
	    ud.ind = 1;
	    ud.ptr = 1;
	    ud.appMode = 0;
	    sldval = ud.buflen-ud.nlines-1; 
	 case 'scroll'
	    %
	    % Echo the text and andvance the cursor
	    %
	    ud.ind = min(ud.ind+1,ud.nlines);
	    ud.ptr = min(ud.ptr+1,ud.buflen);
	    if (~isempty(get(ud.txtlin(ud.ind),'String')))
	       k = 1:ud.ind-1;
	       set(ud.txtlin(k),{'String'},get(ud.txtlin(k+1),'String'));
	    end
	    set(ud.txtlin(ud.ind),'String',str);
	    txtbuf(1:ud.buflen-1) = txtbuf(2:ud.buflen);
	    txtbuf{ud.buflen} = str;
	    ud.appMode = 0;
	    sldval = sldval-1;
	 case 'append'
	    %
	    % Just add the text
	    %
	    if (ud.appMode)
	       newstr = [get(ud.txtlin(ud.ind),'String') str];
	       set(ud.txtlin(ud.ind),'String',newstr);
	       txtbuf{ud.buflen} = newstr;
	    else
	       ud.ind = min(ud.ind+1,ud.nlines);
	       ud.ptr = min(ud.ptr+1,ud.buflen);
	       if (~isempty(get(ud.txtlin(ud.ind),'String')))
		  k = 1:ud.ind-1;
		  set(ud.txtlin(k),{'String'},get(ud.txtlin(k+1),'String'));
	       end
	       set(ud.txtlin(ud.ind),'String',str);
	       txtbuf(1:ud.buflen-1) = txtbuf(2:ud.buflen);
	       txtbuf{ud.buflen} = str;
	       ud.appMode = 1;
	    end
	 case 'newline'
	    %
	    % Advance the cursor
	    %
	    newstr = [get(ud.txtlin(ud.ind),'String') str];
	    set(ud.txtlin(ud.ind),'String',newstr);
	    txtbuf{ud.buflen} = newstr;
	    ud.appMode = 0;
	    sldval = sldval-1;
	 otherwise
	    error('sb2sl: sbhndlmsgs called with incorrect option.');
	 end
	 sldval = max(0,sldval);
	 ud.value = sldval;
	 set(hFig,'UserData',ud);	  	   % Save for the next call
	 set(ud.slider,'Value',sldval,'UserData',txtbuf);
	 drawnow;
      end
   case 'scroll'
      %
      % Scroll the message window
      %
      hFig = findobj(get(0,'Children'),'flat','Tag','hndlmsgsTag');
      %
      % Restore counter and handles
      %
      ud = get(hFig,'UserData');
      sldval = round(get(ud.slider,'Value'));
      if (ud.ptr >= sldval+ud.nlines)
	 lb = max(0,ud.buflen-sldval-ud.nlines);
	 txtbuf = get(ud.slider,'UserData');
	 k = 1:ud.nlines;
	 set(ud.txtlin(k),{'String'},txtbuf(lb+k));
      end
      set(hFig,'UserData',ud);
      drawnow;
   case 'delete'
      %
      % Support for the window delete command
      %
      shh = get(0,'ShowHiddenHandles');
      set(0,'ShowHiddenHandles','on');
      kids = get(0,'Children');
      hFig = findobj(kids,'flat','Tag','sb2slTag');
      set(0,'ShowHiddenHandles',shh);
      if (~isempty(hFig))
	 ud = get(hFig,'UserData');
	 set(ud.message,'CallBack','sbhndlmsgs(''create'');',...
			'Checked','off');
      end
   case 'resize'
      %
      %
      %
   case 'close'
      hFig = findobj(get(0,'Children'),'flat','Tag','hndlmsgsTag');
      % 
      % Just in case somebody has deleted the message window
      % 
      if (~isempty(hFig))
	 set(hFig,'Visible','off');
      end
      set(get(0,'CallBackObject'),'CallBack','sbhndlmsgs(''create'');',...
				  'Checked','off');
   case 'create'
      %
      % Create a message window
      %
      shh = get(0,'ShowHiddenHandles');
      set(0,'ShowHiddenHandles','on');
      kids = get(0,'Children');
      hFig = findobj(kids,'flat','Tag','hndlmsgsTag');
      set(0,'ShowHiddenHandles',shh);
      if (length(hFig) > 1)
	 % 
	 % Something wrong (there is another figure with the same tag)
	 % 
	 error('sb2sl: sbhndlmsgs detected more than one window.');
      elseif (length(hFig) == 1)
	 % 
	 % Message window already created
	 % 
	 set(get(0,'CallBackObject'),'CallBack','sbhndlmsgs(''close'');',...
		                     'Checked','on');
	 set(hFig,'Visible','on');
      else
	 %
	 % Get preferences
	 %
	 sFig = findobj(kids,'flat','Tag','sb2slTag');
	 ud = get(sFig,'UserData');
	 winpref = ud.winpref;
	 nlines = winpref.nlines;	   	   % Number of lines
	 buflen = winpref.buflen;	   	   % Buffer size
	 % 
	 % Create a new message window
	 %
	 bgc = get(0,'DefaultUIControlBackGroundColor');
	 vskip = 16;
	 height = vskip*nlines;
	 rect = [100 253-height 380 height+20];
	 hFig = figure('Units','pixels',...
		       'Position',rect,...
		       'Color',bgc,...
		       'Resize','off',...
		       'Tag','hndlmsgsTag',...
		       'IntegerHandle','off',...
		       'HandleVisibility','callback',...
		       'MenuBar','none',...
		       'Name','SB2SL: Message Window',...
		       'NumberTitle','off',...
		       'DeleteFcn','sbhndlmsgs(''delete'');',...
		       'ResizeFcn','sbhndlmsgs(''resize'');');
	 %
	 % Slider object
	 %
	 scrlLen = buflen-nlines;
	 rect = [6 10 16 height];
	 hSld = uicontrol('Parent',hFig,...
			  'Style','slider',...
			  'Units','pixels',...
			  'Position',rect,...
			  'UserData',cell(buflen,1),...
			  'Visible','on',...
			  'HandleVisibility','callback',...
			  'Min',0,...
			  'Max',scrlLen,...
			  'Value',scrlLen,...
			  'SelectionHighlight','off',...
			  'SliderStep',[1 2]/scrlLen);
	 % 
	 % Message object creation
	 %
	 txtlin = zeros(nlines,1);
	 rect = [30 height-8 340 vskip];
	 for (k = 1:nlines)
	    txtlin(k) = uicontrol('Parent',hFig,...
				  'Style','text',...
				  'FontName','Helvetica',...
				  'FontSize',winpref.varSize(2),...
				  'Tag','varNormal',...
				  'HorizontalAlignment','left',...
				  'Units','pixels',...
				  'Position',rect,...
				  'String','',...
				  'Clipping','on',...
				  'HandleVisibility','callback',...
				  'ForeGroundColor',[0 0 0]);
	    rect(2) = rect(2)-vskip;
	 end
	 drawnow;
	 % 
	 % Save meesage pointers and the associated handles
	 %
	 ud = struct('ind',0,...
		     'ptr',0,...
		     'txtlin',txtlin,...
		     'nlines',nlines,...
		     'buflen',buflen,...
		     'slider',hSld,...
		     'value',scrlLen,...
		     'appMode',0);
	 set(hFig,'UserData',ud);
	 %
	 % Set the callback of the slider here. This avoids calling it upon
	 % creation of the slider control. It depends on the userdata being
	 % set above.
	 set(ud.slider,'Callback','sbhndlmsgs(''scroll'');');
	 % 
	 % Install message window driver and check out the message menu item.
	 % 
	 hFig = findobj(kids,'flat','Tag','sb2slTag');
	 ud = get(hFig,'UserData');
	 set(ud.message,'CallBack','sbhndlmsgs(''close'');',...
			'Checked','on');
      end
   otherwise
      error('sb2sl: sbhndlmsgs called with incorrect argument.');
   end 
   return					   % Last card of SBHNDLMSGS
