function s = edit(Constr,Container)
%EDIT  Builds Bode gain constraint parameter editor.

%   Authors: P. Gahinet, A.Stothert
%   Copyright 1986-2004 The MathWorks, Inc. 
%   $Revision: 1.1.6.2 $ $Date: 2004/12/26 21:51:42 $

import com.mathworks.mwswing.*;
import java.awt.*;

% Definitions
Prefs   = cstprefs.tbxprefs;
GL_31   = java.awt.GridLayout(3,1,0,3);
LEFT    = MJLabel.LEFT;
CENTER  = MJLabel.CENTER;
BWEST   = BorderLayout.WEST;
BCENTER = BorderLayout.CENTER;
BEAST   = BorderLayout.EAST;

% Labels
P1 = MJPanel(GL_31); 
Container.add(P1,BWEST);
L = cell(3,1);
Text = {xlate('Select edge to edit');...
   xlate('Real'); ...
   xlate('Imaginary')};
for ct=1:numel(L)
    Label = MJLabel(sprintf('%s:',Text{ct}),LEFT); 
    awtinvoke(P1,'add(Ljava.awt.Component;)',Label);  
    awtinvoke(Label,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);
    L{ct} = Label;
end

%Edge Selector
EdgeP  = MJPanel(GL_31);
EdgeCB = MJComboBox;
for ct = 1:size(Constr.xCoords,1)
   EdgeCB.addItem(num2str(ct));
end
EdgeCB.setSelectedItem(num2str(Constr.SelectedEdge(1)));
EdgeP.add(EdgeCB);

% Text fields
P6 = MJPanel(BorderLayout(0,0));
Container.add(P6,BCENTER);
P2 = MJPanel(BorderLayout(7,0)); 
awtinvoke(P6,'add(Ljava.awt.Component;Ljava.lang.Object;)',P2,BWEST);
T = cell(3,3);
% Column #1
P3 = MJPanel(GL_31);  
awtinvoke(P2,'add(Ljava.awt.Component;Ljava.lang.Object;)',P3,BWEST);
awtinvoke(P3,'add(Ljava.awt.Component;)',EdgeCB)
T{1,1} = EdgeCB;
W = MJTextField(10); 
awtinvoke(P3,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{2,1} = W;
W = MJTextField(10); 
awtinvoke(P3,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{3,1} = W;
% Column #2
P4 = MJPanel(GL_31);   
awtinvoke(P2,'add(Ljava.awt.Component;Ljava.lang.Object;)',P4,BCENTER);
awtinvoke(P4,'add(Ljava.awt.Component;)',MJLabel('',LEFT))
W = MJLabel(sprintf('to'),CENTER); 
awtinvoke(P4,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{2,2} = W;
W = MJLabel(sprintf('to'),CENTER); 
awtinvoke(P4,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{3,2} = W;
% Column #3
P5 = MJPanel(GL_31);   
awtinvoke(P2,'add(Ljava.awt.Component;Ljava.lang.Object;)',P5,BEAST);
awtinvoke(P5,'add(Ljava.awt.Component;)',MJLabel('',LEFT));
W = MJTextField(10); 
awtinvoke(P5,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{2,3} = W;
W = MJTextField(10); 
awtinvoke(P5,'add(Ljava.awt.Component;)',W);   
awtinvoke(W,'setFont(Ljava.awt.Font;)',Prefs.JavaFontP);  T{3,3} = W;

% Callbacks
Callback = {@LocalChangeEdge Constr T};
set(T{1,1},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)
Callback = {@LocalEditCoord Constr T 1 'Sigma'};
set(T{2,1},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)
Callback = {@LocalEditCoord Constr T 1 'Omega'};
set(T{3,1},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)
Callback = {@LocalEditCoord Constr T 2 'Sigma'};
set(T{2,3},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)
Callback = {@LocalEditCoord Constr T 2 'Omega'};
set(T{3,3},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)

% Initialize text field values
LocalUpdateText([],[],Constr,T);

% Update listeners (track changes in constraint data)
props = [Constr.findprop('Sigma');...
      Constr.findprop('Omega');...
      Constr.findprop('SigmaUnits');...
      Constr.findprop('OmegaUnits'); ...
      Constr.findprop('SelectedEdge')];
Listener = handle.listener(Constr,props,'PropertyPostSet',{@LocalUpdateText Constr T});
Listener = [Listener; ...
   handle.listener(Constr,'DataChanged',{@LocalUpdateText Constr T})];

% Save other handles
s = struct('Panels',{{P1;P2;P3;P4;P5;P6}},'Handles',{[L ; T(:)]},'Listeners',Listener);

%--------------------------------------------------------------------------
function LocalChangeEdge(eventsrc,eventdata,Constr,T)

if ~ishandle(Constr), return; end;

NewEdge = str2double(T{1,1}.getSelectedItem);
if (NewEdge~=Constr.SelectedEdge(1)) && ...
      (NewEdge > 0) && ...
      (NewEdge <= size(Constr.Omega,1)) 
   Constr.SelectedEdge = NewEdge;
   LocalUpdateText([],[],Constr,T);
end

%--------------------------------------------------------------------------
function LocalUpdateText(eventsrc,eventdata,Constr,T)

if ~ishandle(Constr), return; end;

% Updates text fields from contraint data
sig = unitconv(Constr.Sigma(Constr.SelectedEdge,:),Constr.SigmaUnits,Constr.getDisplayUnits('XUnits'));
omega = Constr.Omega(Constr.SelectedEdge,:);
omega(abs(omega)<1e-3) = 0;
omega = unitconv(omega,Constr.OmegaUnits,Constr.getDisplayUnits('YUnits'));
if T{1,1}.getItemCount ~= size(Constr.Sigma,1)
   %Added or deleted edge, need to reset combobox item list
   Callback = get(T{1,1},'ActionPerformedCallback');
   %Disable combobox callbacks
   set(T{1,1},'ActionPerformedCallback','','FocusLostCallback','')
   T{1,1}.removeAllItems;
   for ct = 1:size(Constr.Omega,1)
      T{1,1}.addItem(num2str(ct));
   end
   Str = java.lang.String(num2str(Constr.SelectedEdge(1)));
   awtinvoke(T{1,1},'setSelectedItem(Ljava.lang.Object;)',Str);
   set(T{1,1},'ActionPerformedCallback',Callback,'FocusLostCallback',Callback)
else
   Str = java.lang.String(num2str(Constr.SelectedEdge(1)));
   awtinvoke(T{1,1},'setSelectedItem(Ljava.lang.Object;)',Str);
end
set(T{2,1},'Text',sprintf('%.3g',sig(1)))
set(T{2,3},'Text',sprintf('%.3g',sig(2)))
set(T{3,1},'Text',sprintf('%.3g',omega(1)))
set(T{3,3},'Text',sprintf('%.3g',omega(2)))

%--------------------------------------------------------------------------
function v = LocalEvaluate(TextField)
% Evaluate text field content
s = get(TextField,'Text');
if isempty(s)
   v = [];
else
   v = evalin('base',s,'[]');
   if ~isequal(size(v),[1 1]) || ~isreal(v),
      v = [];
   end
end

%--------------------------------------------------------------------------
function LocalEditCoord(TextField,eventData,Constr,T,jx,WhichCoord)

if ~ishandle(Constr), return; end;

%Find axes units
if strcmp(WhichCoord,'Sigma')
   WhichUnits = 'XUnits';
else
   WhichUnits = 'YUnits';
end

% Update coordinate
v = unitconv(LocalEvaluate(TextField),...
   Constr.getDisplayUnits(WhichUnits), ...
   Constr.([WhichCoord,'Units'])(Constr.SelectedEdge));

% Get new range 
Range = Constr.(WhichCoord)(Constr.SelectedEdge,:);
if ~isempty(v)
   Range(jx) = v;
end

% Update data
if isequal(Constr.(WhichCoord),Range)
   % No change: resync text
   LocalUpdateText([],[],Constr,T);
else
   T = Constr.recordon;
   Constr.(WhichCoord)(Constr.SelectedEdge,:) = Range;
   Constr.recordoff(T);
   % Update display and notify observers
   Constr.send('DataChangeFinished');
   update(Constr)
end
