function GUI = xlim_gui(h)
%XLIM_GUI  GUI for editing x-limits of h

%   Author(s): A. DiVergilio
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.5 $  $Date: 2000/08/02 16:06:07 $

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

%---Definitions
 LCENTER = com.mathworks.mwt.MWLabel.CENTER;
 LRIGHT  = com.mathworks.mwt.MWLabel.RIGHT;
 BCENTER = com.mathworks.mwt.MWBorderLayout.CENTER;
 BWEST   = com.mathworks.mwt.MWBorderLayout.WEST;
 BEAST   = com.mathworks.mwt.MWBorderLayout.EAST;
 GL_21   = java.awt.GridLayout(2,1,0,4);

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

%---Column 1
 s.C1 = com.mathworks.mwt.MWPanel(GL_21); s.Main.add(s.C1,BWEST);
   s.AutoScaleLabel = com.mathworks.mwt.MWLabel(sprintf('Auto-Scale:'),LRIGHT); s.C1.add(s.AutoScaleLabel);
   s.AutoScaleLabel.setFont(Prefs.JavaFontP);
   s.LimitsLabel = com.mathworks.mwt.MWLabel(sprintf('Limits:'),LRIGHT); s.C1.add(s.LimitsLabel);
   s.LimitsLabel.setFont(Prefs.JavaFontP);

%---Column 2
 s.Center = com.mathworks.mwt.MWPanel(com.mathworks.mwt.MWBorderLayout(8,0)); s.Main.add(s.Center,BCENTER);
 s.C2 = com.mathworks.mwt.MWPanel(GL_21); s.Center.add(s.C2,BWEST);
   s.AutoScalePanel = com.mathworks.mwt.MWPanel(com.mathworks.mwt.MWBorderLayout(8,0)); s.C2.add(s.AutoScalePanel);
      s.AutoScale = com.mathworks.mwt.MWCheckbox; s.AutoScalePanel.add(s.AutoScale,BWEST);
      s.AutoScale.setFont(Prefs.JavaFontP);
   s.L1 = com.mathworks.mwt.MWPanel(com.mathworks.mwt.MWBorderLayout(5,0)); s.C2.add(s.L1);
      s.Lim1  = com.mathworks.mwt.MWTextField(7); s.L1.add(s.Lim1,BWEST);
         s.Lim1.setFont(Prefs.JavaFontP);
      s.LimTo = com.mathworks.mwt.MWLabel(sprintf('to'),LCENTER); s.L1.add(s.LimTo,BCENTER);
         s.LimTo.setFont(Prefs.JavaFontP);
      s.Lim2  = com.mathworks.mwt.MWTextField(7); s.L1.add(s.Lim2,BEAST);
         s.Lim2.setFont(Prefs.JavaFontP);

%---Install GUI callbacks
 GUICallback = {@localWriteProp,h,s.Main};
 set(s.AutoScale,'Name','LimMode','ItemStateChangedCallback',GUICallback);
 set(s.Lim1,     'Name','Lim1',   'ActionPerformedCallback', GUICallback,'FocusLostCallback',GUICallback);
 set(s.Lim2,     'Name','Lim2',   'ActionPerformedCallback', GUICallback,'FocusLostCallback',GUICallback);

%---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;


%%%%%%%%%%%%%%%%%
% localReadProp %
%%%%%%%%%%%%%%%%%
function localReadProp(eventSrc,eventData,GUI1,GUI2)
% Target -> GUI
 h = cstprefs.sisoprops;
 if h.ListenerEnable
    switch eventSrc.Name
    case 'XlimMode'
       GUI1.setState(strcmpi(eventData.NewValue{1},'auto'));
    case 'XLim'
       GUI1.setText(num2str(eventData.NewValue(1)));
       GUI2.setText(num2str(eventData.NewValue(2)));
    end
 end


%%%%%%%%%%%%%%%%%%
% localWriteProp %
%%%%%%%%%%%%%%%%%%
function localWriteProp(eventSrc,eventData,h,Main)
% GUI -> Target
 if isempty(h.Target), return; end  %---Prevents error due to FocusLostCallback during window closing
 switch get(eventSrc,'Name')
 case 'LimMode'
    if strcmpi(get(eventSrc,'State'),'on')
       setlims(h.Target,'auto','');
    else
       setlims(h.Target,'manual','');
    end
 case {'Lim1','Lim2'}
    s = get(Main,'UserData');
    a = h.Target.HG.PlotAxes(1);
    oldlim = get(a,'XLim');
    oldval1s = num2str(oldlim(1));
    oldval2s = num2str(oldlim(2));
    newval1s = get(s.Lim1,'Text');
    newval2s = get(s.Lim2,'Text');
    if isequal(oldval1s,newval1s) & isequal(oldval2s,newval2s)
       return;
    else
       newval1 = evalnum(newval1s);
       newval2 = evalnum(newval2s);
       if ~(isempty(newval1) | isempty(newval2)) & (newval2>newval1) & ...
          ~(isa(h.Target,'sisogui.bodeditor') & (newval1<=0))
          setlims(h.Target,[newval1 newval2],[]);
       else
          s.Lim1.setText(num2str(oldval1s));
          s.Lim2.setText(num2str(oldval2s));
       end
    end
 end


%%%%%%%%%%%%%%%%%%%%%
% localTargetPreSet %
%%%%%%%%%%%%%%%%%%%%%
function localTargetPreSet(eventSrc,eventData)
% Update listeners when Target changes
 %---New target
  t = eventData.NewValue;
 %---Get structure
  s = get(eventSrc,'UserData');
 %---Update listener
  if isa(t,'sisogui.grapheditor')
     a = t.HG.PlotAxes(1);
     s.LimModeListener = handle.listener(t,findprop(t,'XlimMode'),    'PropertyPostSet',{@localReadProp,s.AutoScale});
     s.LimListener     = handle.listener(a,findprop(handle(a),'XLim'),'PropertyPostSet',{@localReadProp,s.Lim1,s.Lim2});
     %---Change groupbox name to match editor
      if isa(t,'sisogui.bodeditor')
         s.Main.setLabel(sprintf('Frequency'));
      elseif isa(t,'sisogui.rleditor')
         s.Main.setLabel(sprintf('Real Axis'));
      end
     %---Sync
      s.AutoScale.setState(strcmpi(t.XlimMode{1},'auto'));
      xlim = get(t.HG.PlotAxes(1),'XLim');
      s.Lim1.setText(num2str(xlim(1)));
      s.Lim2.setText(num2str(xlim(2)));
  else
     %---Clear
      s.LimModeListener = [];
      s.LimListener = [];
  end
 %---Save structure
  set(eventSrc,'UserData',s);


%%%%%%%%%%%
% evalnum %
%%%%%%%%%%%
function val = evalnum(val)
% Evaluate string val, returning valid real scalar only, empty otherwise
if ~isempty(val)
   val = evalin('base',val,'[]');
   if ~isnumeric(val) | ~(isreal(val) & isfinite(val) & isequal(size(val),[1 1]))
      val = [];
   end
end
