function hmenu = tsplotmenu(hplot,plotType) 
%TSPLOTMENU  Constructs right-click menus for time series plots. 

AxGrid = hplot.AxesGrid;
Size = AxGrid.Size; 
hmenu = struct(... 
   'Timeseries',[],... 
   'Characteristics',[]); 
       
%% Group #1: Data contents (waves & characteristics) 
hmenu.Timeseries = hplot.addMenu('waves','Label',xlate('Time series')); 

% Create a Characteristics menu 
hmenu.Characteristics = hplot.addMenu('characteristics'); 
 
%% Group #2: Axes configuration, I/O and model selectors
if any(strcmp(plotType,{'XYPlot','CorrPlot'})) % XYPlot is a @respplot
    % Install listener to track responses added or deleted to update
    % characteristics.
    set(hmenu.Characteristics,'UserData',handle.listener(hplot,hplot.findprop('Responses'),...
     'PropertyPostSet',{@LocalCharCallback  hmenu.Characteristics,hplot}));
    grp2 = [hplot.addMenu('iogrouping'); ...
            hplot.addMenu('ioselector');];    
else    
    % Install listener to track responses added or deleted to update
    % characteristics.
    set(hmenu.Characteristics,'UserData',handle.listener(hplot,hplot.findprop('Waves'),...
     'PropertyPostSet',{@LocalCharCallback  hmenu.Characteristics,hplot}));
    grp2 = [hplot.addMenu('channelgrouping'); ...
            hplot.addMenu('channelselector');];
end
set(grp2(1),'Separator','on')
LocalUpdateVis([],[],AxGrid,grp2)  % initialize menu visibility
% Install listener to track plot size and update menu visibility
set(grp2(2),'UserData',handle.listener(AxGrid,...
   AxGrid.findprop('Size'),'PropertyPostSet',{@LocalUpdateVis AxGrid grp2}))

%% Group #3: Annotation and Focus 
hplot.addMenu('normalize');
AxGrid.addMenu('grid','Separator','on');

% Plot specific menus
switch plotType
    case 'TimePlot'
        hplot.addTSMenu('selectrule','Separator','on'); 
        hplot.addTSMenu('merge'); 
        hplot.addTSMenu('preproc');
        hplot.addTSMenu('shift');
        hplot.addTSMenu('remove');
        hplot.addTSMenu('keep');
        hplot.addTSMenu('delete');
        hplot.addTSMenu('newevent');
        hplot.addTSMenu('select');
    case 'SpecPlot'
        hplot.addTsMenu('merge','Separator','on');
        hplot.addTsMenu('preproc');
    case 'XYPlot'
        hplot.addTsMenu('merge'); 
        hplot.addTsMenu('remove');
        hplot.addTsMenu('delete');
        hplot.addTsMenu('keep');
end

%% Last group undo-redo
undoMenu = uimenu('Parent',AxGrid.UIcontextMenu,...
    'Label','Undo','Tag','undo','Separator','on',...
    'Callback',{@localUndo hplot});
redoMenu = uimenu('Parent',AxGrid.UIcontextMenu,...
    'Label','Redo','Tag','uredo',...
    'Callback',{@localRedo hplot});
r = tsguis.recorder;
hplot.addlisteners([handle.listener(r,r.findprop('Undo'),'PropertyPostSet',...
       {@setUndoStatus undoMenu r});...
     handle.listener(r,r.findprop('Redo'),'PropertyPostSet',...
       {@setRedoStatus redoMenu r})]);
setUndoStatus([],[],undoMenu,r)
setRedoStatus([],[],redoMenu,r)


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

function LocalUpdateVis(eventsrc,eventdata,AxGrid,MenuHandles)
% Initializes and updates visibility of "MIMO" menus
if prod(AxGrid.Size([1 2]))==1
   set(MenuHandles(1:2),'Visible','off')
else
   set(MenuHandles(1:2),'Visible','on')
end
   
% 
 function LocalCharCallback(eventsrc,eventdata,CharMenuHandle,hplot)
%  Listener Callback applies characteristics for systems imported through
%  the LTIVIEWER of in the hold mode.

subMenus=get(CharMenuHandle,'Children');
ch = subMenus(find(strcmp('on',get(subMenus,'checked'))));
if ~isempty(eventdata.NewValue)
   wf = find(eventdata.NewValue,'Characteristics',[]);
   for ct = 1:length(ch)
      for  ctwf = 1:length(wf)
         args = get(ch(ct),'UserData');
         try
            % RE: Creation may fail due to size incompatibility, cf. stability
            %     margins on plot with mix of SISO and MIMO systems
            wfChar = wf(ctwf).addchar(args{:});   
            syncprefs(wfChar.Data,hplot.Preferences); % initialize parameters
         end
      end
   end
end

function localUndo(eventSrc, eventData, this)

%% Undo menu callback
if ~isempty(this.Parent) % Object may not have been parented initially
    this.Parent.getRoot.TsViewer.undo;
end

function localRedo(eventSrc, eventData, this)

%% Redo menu callback
if ~isempty(this.Parent) % Object may not have been parented initially
    this.Parent.getRoot.TsViewer.redo;
end

function setUndoStatus(es,ed,undoMenu,r)

%% Recorder Undo stack listener callback
if isempty(r.Undo)
    set(undoMenu,'Enable','off')
else
    set(undoMenu,'Enable','on')
end

function setRedoStatus(es,ed,redoMenu,r)

%% Recorder Redo stack listener callback
if isempty(r.Redo)
    set(redoMenu,'Enable','off')
else
    set(redoMenu,'Enable','on')
end