function CMenu = addmenu(Constr, SISOfig)
%ADDMENU  Creates a common right-click context menu for the constraint objects.

%   Author(s): Bora Eryilmaz, A. Stothert
%   Revised:
%   Copyright 1986-2004 The MathWorks, Inc. 
%   $Revision: 1.1.6.2 $ $Date: 2004/12/10 19:30:57 $

% Define a right click context menu for the constraint
CMenu = uicontextmenu('Parent', SISOfig);
%Add menu item to edit constraint
uimenu(CMenu, 'Label', xlate('Edit...'), 'Callback', ...
   {@LocalEdit Constr}, ...
   'visible','on',...
   'Tag','edit');
%Add menu item to delete constraint
uimenu(CMenu, 'Label', xlate('Delete'),  'Callback', ...
   {@LocalDelete Constr}, ...
   'visible', 'on', ...
   'Tag', 'delete');
%Add menu item to split constraint
uimenu(CMenu, 'Label', xlate('Split'), 'Callback', ...
   {@localSplit Constr Constr.Data}, ...
   'visible', 'off',...
   'tag', 'split');
%Add menu item to flip constraint
uimenu(CMenu, 'Label', xlate('Flip'), 'Callback', ...
   {@localFlip Constr Constr.Data}, ...
   'visible', 'off', ...
   'tag', 'flip');
%Add menu item to glue left end of constraint
uimenu(CMenu, 'Label', xlate('Join left'), 'Callback', ...
   {@localJoin Constr 'left' Constr.Data}, ...
   'tag', 'left',...
   'checked', 'off', ...
   'visible', 'off');
%Add menu item to glue right end
uimenu(CMenu, 'Label', xlate('Join right'), 'Callback', ...
   {@localJoin Constr 'right' Constr.Data}, ...
   'tag', 'right',...
   'checked', 'off', ...
   'visible','off');

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

% ----------------------------------------------------------------------------%
% Function: LocalEdit
% Edit the constraint
% ----------------------------------------------------------------------------%
function LocalEdit(eventSrc, eventData, Constr)
Constr.TextEditor.show(Constr);

% ----------------------------------------------------------------------------%
% Function: LocalDelete
% Delete the constraint
% ----------------------------------------------------------------------------%
function LocalDelete(eventSrc, eventData, Constr)
% Delete constraint
EventMgr = Constr.EventManager;
% Start recording
T = ctrluis.transaction(Constr,'Name',xlate('Delete Constraint'),...
    'OperationStore','on','InverseOperationStore','on');

%Remove the selected edge
Constr.delete;

%Filter transaction to remove changes that cause problems
%with undo
localFilterTransaction(T)

% Commit and stack transaction
EventMgr.record(T);

%--------------------------------------------------------------------------
function localFlip(hSrc,hData,this,ObjToRecord)

EventMgr = this.EventManager;
% Start recording
T = ctrluis.transaction(ObjToRecord,'Name',xlate('Flip Constraint'),...
    'OperationStore','on','InverseOperationStore','on');

%Toggle bound from upper to lower or vice versa
switch this.Type;
   case 'lower'
      this.Type = 'upper';
   case 'upper'
      this.Type = 'lower';
end
this.update;

% Commit and stack transaction
EventMgr.record(T);

%--------------------------------------------------------------------------
function localSplit(hSrc, hData, this,ObjToRecord)

EventMgr = this.EventManager;
% Start recording
T = ctrluis.transaction(ObjToRecord,'Name',xlate('Split edge'),...
    'OperationStore','on','InverseOperationStore','on');

%Call abstract method to split constraint
this.splitEdge;

% Commit and stack transaction
EventMgr.record(T);

%--------------------------------------------------------------------------
function localJoin(hSrc, hData, this, WhichEnd,ObjToRecord)

EventMgr = this.EventManager;
% Start recording
T = ctrluis.transaction(ObjToRecord,'Name',xlate('Join edge'),...
    'OperationStore','on','InverseOperationStore','on');

% Call  method to join ends
this.join(WhichEnd);

% Commit and stack transaction
EventMgr.record(T);

%--------------------------------------------------------------------------
function localFilterTransaction(T)

%Define object property changes to ignore
RemoveList = {...
   'Camera', ...
   'Tight', ...
   'YLim', ...
   'ZLim',...
   'XLim'};

idxRemove = false*ones(numel(T.Transaction.Operations),1);
Names = cell(size(idxRemove));
%Get list of all object property changes recorded
for idx = 1:numel(idxRemove)
   if isa(T.Transaction.Operations(idx),'handle.SetOp')
      Names{idx} = T.Transaction.Operations(idx).Property.Name;
   else
      Names{idx} = '';
   end
end

%Compare list of all recorded changes with the remove list
for idx = 1:numel(RemoveList)
   idxRemove = idxRemove | ...
      strncmp(Names,RemoveList{idx},numel(RemoveList{idx}));
end

%Get rid or operations defined by remove list
idxRemove = fliplr(find(idxRemove'));
for idx = idxRemove
   delete(T.Transaction.Operations(idx))
end

