function dummy = editconstr(Editor)
%EDITCONSTR  Opens and manages the design constraint editor.

%   Author(s): K. Gondoly and P. Gahinet
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.12 $  $Date: 2000/08/25 21:35:11 $

% REVISIT
dummy = [];

% Open editor
[Dialog,hEdit] = LocalOpenEditor(Editor);

% Install listeners
lsnr(1) = handle.listener(Editor,findprop(Editor,'Visible'),...
    'PropertyPostSet',{@EditorVisibleCB Dialog});
lsnr(2) = handle.listener(Editor,findprop(Editor,'Constraints'),...
    'PropertyPostSet',{@ChangeConstrCB hEdit(:,2)});
lsnr(3) = handle.listener(Editor.LoopData,...
    'ObjectBeingDestroyed',{@CloseCB Dialog});
set(Dialog,'UserData',lsnr)

% Store dialog handle
% REVISIT: simplify
HG = Editor.HG;
HG.ConstraintDialog = Dialog;
Editor.HG = HG;


%------------------------ Callback Functions --------------------

%%%%%%%%%%%%%%%%%%%
% EditorVisibleCB %
%%%%%%%%%%%%%%%%%%%
function EditorVisibleCB(hProp,event,hDialog)
% Close constraint dialog if editor is hidden
if strcmp(event.NewValue,'off')
    close(hDialog)
end


%%%%%%%%%%%
% CloseCB %
%%%%%%%%%%%
function CloseCB(hSrc,event,hDialog)
% Close constraint dialog when GUI is closed
close(hDialog)


%%%%%%%%%%%%%%%%%%
% ChangeConstrCB %
%%%%%%%%%%%%%%%%%%
function ChangeConstrCB(hSrc,event,hEdit)
% Update constraint values
NewConstr = event.NewValue;
if NewConstr.SettlingTime.On,
    NewValue = NewConstr.SettlingTime.Value;
    set(hEdit(1),'UserData',NewValue,'String',sprintf('%.3g',NewValue))
end
if NewConstr.Overshoot.On,
    NewValue = NewConstr.Overshoot.Value;
    set(hEdit(2),'UserData',NewValue,'String',sprintf('%.3g',NewValue))
end
if NewConstr.Damping.On,
    NewValue = NewConstr.Damping.Value;
    set(hEdit(3),'UserData',NewValue,'String',sprintf('%.3g',NewValue))
end
if NewConstr.NaturalFrequency.On,
    NewValue = NewConstr.NaturalFrequency.Value;
    set(hEdit(4),'UserData',NewValue,'String',sprintf('%.3g',NewValue))
end


%%%%%%%%%%%%%
% LocalEdit %
%%%%%%%%%%%%%
function LocalEdit(EditBox,event,Constraint,CheckBox)
% Edit constraint

% Evaluate user input
InputText = get(EditBox,'String');
if length(InputText)
    InputValue = evalin('base',InputText,'[]');
else
    InputValue = [];
end

% Determine if user input is valid
if isequal(size(InputValue),[1 1]) & isreal(InputValue) & isfinite(InputValue),
    switch Constraint
    case 'settling'
        IsValid = (InputValue>0);
    case 'overshoot'
        IsValid = (InputValue>=0 & InputValue<=100);
    case 'damping'
        InputValue = abs(InputValue);
        IsValid = (InputValue>=0 & InputValue<=1);
    case 'frequency'
        IsValid = (InputValue>0);
    end
else
    IsValid = 0;
end

if IsValid   
    % Update content in userdata
    set(EditBox,'String',num2str(InputValue),'UserData',InputValue);
    % Automatically check corresponding check box
    set(CheckBox,'Value',1);
else
    % Invalid input: revert to previous value
    set(EditBox,'String',num2str(get(EditBox,'UserData')))
end


%%%%%%%%%%%%%%
% LocalApply %
%%%%%%%%%%%%%%
function LocalApply(hSrc,event,Hedit,Editor,CloseReq)
% Apply user-defined constraints

% RE: hEdit = check box and edit box handles

% Update contraint data
Constr = Editor.Constraints;
Constr.SettlingTime.Value = get(Hedit(1,2),'UserData');
Constr.Overshoot.Value = get(Hedit(2,2),'UserData');
Constr.Damping.Value = get(Hedit(3,2),'UserData');
Constr.NaturalFrequency.Value = get(Hedit(4,2),'UserData');
Constr.SettlingTime.On = ...
    get(Hedit(1,1),'Value') & ~isempty(Constr.SettlingTime.Value);
Constr.Overshoot.On = ...
    get(Hedit(2,1),'Value') & ~isempty(Constr.Overshoot.Value);
Constr.Damping.On = ...
    get(Hedit(3,1),'Value') & ~isempty(Constr.Damping.Value);
Constr.NaturalFrequency.On = ...
    get(Hedit(4,1),'Value') & ~isempty(Constr.NaturalFrequency.Value);
Editor.Constraints = Constr;

% Close the dialog if requested
if nargin>4,
    close(get(Hedit(1,1),'Parent'))
end


%------------------------ Local Functions --------------------


%%%%%%%%%%%%%%%%%%%
% LocalOpenEditor %
%%%%%%%%%%%%%%%%%%%
function [Dialog,Hedit] = LocalOpenEditor(Editor)
% Open design constraint dialog

Constraints = Editor.Constraints;
StdColor = get(0,'defaultuicontrolbackgroundcolor');
PointsToPixels = 72/get(0,'ScreenPixelsPerInch');
StdUnit = 'point';

% Main figure
% UDDREVISIT: UserData should contain handle to RLEDITOR object
Dialog = figure('Units',StdUnit, ...
   'Color',[0.8 0.8 0.8], ...
   'MenuBar','none', ...
   'unit','pixel', ...
   'Name','Design Constraints', ...
   'IntegerHandle','off', ...
   'HandleVis','off',...
   'NumberTitle','off', ...
   'Resize','off',...
   'Position',[187 188 270 171]);

% Frames 
uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',StdColor, ...
   'Position',PointsToPixels*[5 36 260 132], ...
   'HelpTopicKey','sisorootlocusconstraint',...
   'Style','frame')

% Constraints
AddConstrText = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'Position',PointsToPixels*[45 138 168 20], ...
   'String','Add constraints for:', ...
   'Style','text',...
   'HelpTopicKey','sisorootlocusconstraint',...
   'Tag','AddConstraint');
Hedit = zeros(4,2);
OnOff = {'off','on'};
% Settling time
Hedit(1,1) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',StdColor, ...
   'Position',PointsToPixels*[10 116 150 20], ...
   'Horizontal','left', ...
   'String','Settling Time =', ...
   'Style','checkbox', ...
   'HelpTopicKey','settlingtimeconstraint',...
   'Value',Constraints.SettlingTime.On);
Hedit(1,2) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',[1 1 1], ...
   'Callback',{@LocalEdit 'settling' Hedit(1,1)}, ...
   'HorizontalAlign','left', ...
   'Position',PointsToPixels*[164 116 90 20], ...
   'Style','edit', ...
   'HelpTopicKey','settlingtimeconstraint',...
   'String',num2str(Constraints.SettlingTime.Value), ...
   'UserData',Constraints.SettlingTime.Value, ...
   'tag','settlingtime'); % Do not erase - required for testing purpose
% Peak overshoot
Hedit(2,1) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',StdColor, ...
   'Position',PointsToPixels*[10 93 150 20], ...
   'Horizontal','left', ...
   'String','Peak Overshoot (%) =', ...
   'Style','checkbox', ...
   'HelpTopicKey','dampingratioconstraint',...
   'Value',Constraints.Overshoot.On);
Hedit(2,2) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',[1 1 1], ...
   'Callback',{@LocalEdit 'overshoot' Hedit(2,1)}, ...
   'HorizontalAlign','left', ...
   'Position',PointsToPixels*[164 93 90 20], ...
   'Style','edit', ...
   'HelpTopicKey','dampingratioconstraint',...
   'String',num2str(Constraints.Overshoot.Value), ...
   'UserData',Constraints.Overshoot.Value, ...
   'tag','overshoot'); % Do not erase - required for testing purposes
% Damping ratio
Hedit(3,1) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',StdColor, ...
   'Position',PointsToPixels*[10 70 150 20], ...
   'Horizontal','left', ...
   'String','Damping Ratio =', ...
   'Style','checkbox', ...
   'HelpTopicKey','dampingratioconstraint',...
   'Value',Constraints.Damping.On);
Hedit(3,2) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',[1 1 1], ...
   'Callback',{@LocalEdit 'damping' Hedit(3,1)}, ...
   'HorizontalAlign','left', ...
   'Position',PointsToPixels*[164 70 90 20], ...
   'Style','edit', ...
   'HelpTopicKey','dampingratioconstraint',...
   'String',num2str(Constraints.Damping.Value), ...
   'UserData',Constraints.Damping.Value, ...
   'tag','dampingratio'); % Do not erase - required for testing purpose;
% Natural frequency
Hedit(4,1) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',StdColor, ...
   'Position',PointsToPixels*[10 47 150 20], ...
   'Horizontal','left', ...
   'String','Natural Frequency =', ...
   'Style','checkbox', ...
   'HelpTopicKey','naturalfrequencyconstraint',...
   'Value',Constraints.NaturalFrequency.On);
Hedit(4,2) = uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'BackgroundColor',[1 1 1], ...
   'Callback',{@LocalEdit 'frequency' Hedit(4,1)}, ...
   'HorizontalAlign','left', ...
   'Position',PointsToPixels*[164 47 90 20], ...
   'Style','edit', ...
   'HelpTopicKey','naturalfrequencyconstraint',...
   'String',num2str(Constraints.NaturalFrequency.Value), ...
   'UserData',Constraints.NaturalFrequency.Value, ...
   'tag','naturalfrequency'); % Do not erase - required for testing purpose
set(AddConstrText,'UserData',Hedit)

% OK/Cancel/Help/Apply buttons
uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'Position',PointsToPixels*[5 5 50 25], ...
   'String','OK', ...
   'Callback',{@LocalApply Hedit Editor 'close'});
uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'Position',PointsToPixels*[76 5 50 25], ...
   'String','Cancel', ...
   'Callback','close(gcbf)');
uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'Position',PointsToPixels*[146 5 50 25], ...
   'String','Help', ...
   'Callback','ctrlguihelp(''sisorootlocusconstraint'');');
uicontrol('Parent',Dialog, ...
   'Units',StdUnit, ...
   'Position',PointsToPixels*[215 5 50 25], ...
   'String','Apply', ...
   'Callback',{@LocalApply Hedit Editor});

% Install CS help
% RE: Do this last for proper initialization when opened while CS help is on
cshelp(Dialog,Editor.up.Figure);


