function GUI = lims_gui(h)
%LIMS_GUI  GUI for editing limit stack properties of h

%   Author(s): A. DiVergilio
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.7 $  $Date: 2000/08/31 06:40:27 $

%---Get Toolbox Preferences
 Prefs = cstprefs.tbxprefs;

%---Top-level panel (MWGroupbox)
 s.Main = com.mathworks.mwt.MWGroupbox(sprintf('Limit Stack'));
 s.Main.setLayout(com.mathworks.mwt.MWBorderLayout(8,8));
 s.Main.setFont(Prefs.JavaFontB);

%---Info label along bottom
 InfoStr = sprintf('Use the limit stack to store & retrieve axes limits');
 s.Status = com.mathworks.mwt.MWLabel(sprintf('%s',InfoStr),com.mathworks.mwt.MWLabel.LEFT);
 s.Status.setFont(Prefs.JavaFontP);
 s.Main.add(s.Status,com.mathworks.mwt.MWBorderLayout.SOUTH);

%---West panel for buttons
 s.W = com.mathworks.mwt.MWPanel(java.awt.GridLayout(1,4,10,0));
 s.Main.add(s.W,com.mathworks.mwt.MWBorderLayout.WEST);

%---Image files for buttons
 filebase = matlabroot;
 file1 = fullfile(filebase,'toolbox','control','ctrlguis','@cstprefs','@sisoprops','button1.gif');
 file2 = fullfile(filebase,'toolbox','control','ctrlguis','@cstprefs','@sisoprops','button2.gif');
 file3 = fullfile(filebase,'toolbox','control','ctrlguis','@cstprefs','@sisoprops','button3.gif');
 file4 = fullfile(filebase,'toolbox','control','ctrlguis','@cstprefs','@sisoprops','button4.gif');

%---Buttons
 s.Add = com.mathworks.mwt.MWButton(com.mathworks.mwt.MWImageResource(file1)); s.W.add(s.Add);
 set(s.Add,'Name','Add','MouseEnteredCallback',{@localEnter,s.Status},'MouseExitedCallback',{@localExit,s.Status});
 s.Prev = com.mathworks.mwt.MWButton(com.mathworks.mwt.MWImageResource(file2)); s.W.add(s.Prev);
 set(s.Prev,'Name','Prev','MouseEnteredCallback',{@localEnter,s.Status},'MouseExitedCallback',{@localExit,s.Status});
 s.Next = com.mathworks.mwt.MWButton(com.mathworks.mwt.MWImageResource(file3)); s.W.add(s.Next);
 set(s.Next,'Name','Next','MouseEnteredCallback',{@localEnter,s.Status},'MouseExitedCallback',{@localExit,s.Status});
 s.Remove = com.mathworks.mwt.MWButton(com.mathworks.mwt.MWImageResource(file4)); s.W.add(s.Remove);
 set(s.Remove,'Name','Remove','MouseEnteredCallback',{@localEnter,s.Status},'MouseExitedCallback',{@localExit,s.Status});

%---Install GUI callbacks
 GUICallback = {@localWriteProp,s.Main};
 set(s.Add,   'ActionPerformedCallback',GUICallback);
 set(s.Prev,  'ActionPerformedCallback',GUICallback);
 set(s.Next,  'ActionPerformedCallback',GUICallback);
 set(s.Remove,'ActionPerformedCallback',GUICallback);

%---Use s.Index to keep track of current stack location
 s.Index = 0;

%---Install listner for target change
 s.TargetListener = handle.listener(h,findprop(h,'Target'),'PropertyPreSet',@localTargetPreSet);
 s.TargetListener.CallbackTarget = s.Main;

%---Store java handles
 set(s.Main,'UserData',s);

%---Return handle of top-level GUI
 GUI = s.Main;


%%%%%%%%%%%%%%
% localEnter %
%%%%%%%%%%%%%%
function localEnter(eventSrc,eventData,Status)
% Mouse entered
 h = cstprefs.sisoprops;
 Name = get(eventSrc,'Name');
 switch Name
 case 'Add'
    Str = sprintf('Add current limits to stack');
 otherwise
    StackLength = size(h.Target.LimitStack,1);
    if StackLength>0
       switch Name
       case 'Prev'
           Str = sprintf('Retrieve previous stack entry');
       case 'Next'
           Str = sprintf('Retrieve next stack entry');
       case 'Remove'
           Str = sprintf('Remove current limits from stack');
       end
    else
       Str = sprintf('No action (stack is empty)');
    end
 end
 Status.setText(Str);


%%%%%%%%%%%%%
% localExit %
%%%%%%%%%%%%%
function localExit(eventSrc,eventData,Status)
% Mouse exited
 Status.setText(sprintf('Use the limit stack to store & retrieve axes limits'));


%%%%%%%%%%%%%%%%%%
% localWriteProp %
%%%%%%%%%%%%%%%%%%
function localWriteProp(eventSrc,eventData,Main)
% GUI -> Target
 h = cstprefs.sisoprops;
 s = get(Main,'UserData');
 pos = s.Index;
 Name = get(eventSrc,'Name');
 StackLength = size(h.Target.LimitStack,1);
 switch Name
 case 'Add'
    new = [get(h.Target.HG.PlotAxes,'Xlim') get(h.Target.HG.PlotAxes,'Ylim')];
    if isempty(h.Target.LimitStack)
       h.Target.LimitStack = new;
    else
       h.Target.LimitStack = [h.Target.LimitStack(1:pos,:) ; new ; h.Target.LimitStack(pos+1:StackLength,:)];
    end
    s.Index = pos+1;
 case 'Prev'
    if StackLength>0
       pos = (pos==1)*StackLength + (pos>1)*(pos-1);
       new = h.Target.LimitStack(pos,:);
       LimitStack = h.Target.LimitStack;
       LimitStack(pos,:) = setlims(h.Target,new(1:2),new(3:4));
       h.Target.LimitStack = LimitStack;
       s.Index = pos;
    end
 case 'Next'
    if StackLength>0
       pos = (pos==StackLength)*1 + (pos<StackLength)*(pos+1);
       new = h.Target.LimitStack(pos,:);
       LimitStack = h.Target.LimitStack;
       LimitStack(pos,:) = setlims(h.Target,new(1:2),new(3:4));
       h.Target.LimitStack = LimitStack;
       s.Index = pos;
    end
 case 'Remove'
    if StackLength>0
       lims = [get(h.Target.HG.PlotAxes,'Xlim') get(h.Target.HG.PlotAxes,'Ylim')];
       if isequal(lims,h.Target.LimitStack(pos,:))
          h.Target.LimitStack = [h.Target.LimitStack(1:pos-1,:);h.Target.LimitStack(pos+1:StackLength,:)];
          newpos = min(pos,StackLength-1);
          localEnter(eventSrc,eventData,s.Status);
          if newpos>0
             new = h.Target.LimitStack(newpos,:);
             LimitStack = h.Target.LimitStack;
             LimitStack(newpos,:) = setlims(h.Target,new(1:2),new(3:4));
             h.Target.LimitStack = LimitStack;
          else
             zoomout(h.Target);
          end
          s.Index = newpos;
       end
    end
 end
 set(Main,'UserData',s);


%%%%%%%%%%%%%%%%%%%%%
% localTargetPreSet %
%%%%%%%%%%%%%%%%%%%%%
function localTargetPreSet(eventSrc,eventData)
% Update listeners when Target changes
 %---New target
  t = eventData.NewValue;
 %---Get structure
  s = get(eventSrc,'UserData');
 %---Only show for rleditor
  if isa(t,'sisogui.rleditor')
     s.Index = size(t.LimitStack,1);
     s.Main.setVisible(1);
  else
     s.Index = 0;
     s.Main.setVisible(0);
  end
 %---Save structure
  set(eventSrc,'UserData',s);
