function epd(action)
%EPD A simple demonstration of endpoint detection in speech.
% 
% To start, load a signal using the 'New' menu.
%
%  Author: Stuart N Wrigley       
%  MAD - Matlab Auditory Demonstrations
%  (c) University of Sheffield 1998
%  Revision 0.01: 27 July 1998

% updated July 1999 for v2.1 by Martin

if nargin < 1
  action='init';
end

switch action

case 'init'
  f=findobj('Tag','epd_fig');
  if ~isempty(f)
    figure(f);
  else  	   
    epd_gui;
    ud=get(gcf,'UserData');    
    ud.YLim=[-1.1 1.1];
    ud.sig=[];
    set(gcf,'UserData',ud);      
  end

case 'calc' 
  ud=get(gcf,'UserData');
  [ud.ITL,ud.ITU,ud.IZCT,ud.energy,ud.zc,ud.autoLC,ud.autoRC]=epdStats(ud.sig,ud.fs);
  maxE=max(ud.energy); ud.eYLim=maxE+(.3*maxE);
  maxZ=max(ud.zc);     ud.zYLim=maxZ+(.3*maxZ);   
  set(ud.energyAxes,'XLim',[1 length(ud.energy)],'YLim',[0 ud.eYLim]);
  set(ud.zcAxes,    'XLim',[1 length(ud.zc)],    'YLim',[0 ud.zYLim]); 
  set(gcf,'UserData',ud);      
  
case 'showPlots'   
  ud=get(gcf,'UserData');
  if ~isempty(ud.sig)
    if get(ud.plotsToggle,'Value')
      maxE=max(ud.energy); ud.eYLim=maxE+(.3*maxE);
      maxZ=max(ud.zc); ud.zYLim=maxZ+(.3*maxZ);   
      set(ud.energyLine,'XData',1:length(ud.energy),'YData',ud.energy,'Color','blue');
      set(ud.zcLine,'XData',1:length(ud.zc),'YData',ud.zc,'Color','blue');
    else
      set(ud.energyLine,'XData',[],'YData',[]);
      set(ud.zcLine,'XData',[],'YData',[]);
      set(ud.thresholdToggle,'Value',0);
      set(ud.ITULine,'XData',[],'YData',[]);
      set(ud.ITLLine,'XData',[],'YData',[]);
      set(ud.IZCTLine,'XData',[],'YData',[]);
    end
  else
    set(ud.plotsToggle,'Value',0);
  end

case 'showThresholds'   
  ud=get(gcf,'UserData');
  if and(~isempty(ud.sig),get(ud.plotsToggle,'Value'))
    if get(ud.thresholdToggle,'Value')
      l=length(ud.energy);z=zeros(1,l);
      set(ud.ITULine,'XData',1:l,'YData',z+ud.ITU,'Color','red');
      set(ud.ITLLine,'XData',1:l,'YData',z+ud.ITL,'Color','red');
      set(ud.IZCTLine,'XData',1:l,'YData',z+ud.IZCT,'Color','red');
    else
      set(ud.ITULine,'XData',[],'YData',[]);
      set(ud.ITLLine,'XData',[],'YData',[]);
      set(ud.IZCTLine,'XData',[],'YData',[]);
    end
  else
    set(ud.thresholdToggle,'Value',0)
  end

case 'showEnds'   
  ud=get(gcf,'UserData');
  if ~isempty(ud.sig)
    if get(ud.cursorToggle,'Value')
      set(ud.signalAutoLC,'XData',[ud.autoLC ud.autoLC],'YData',ud.YLim,'Color','m');
      set(ud.signalAutoRC,'XData',[ud.autoRC ud.autoRC],'YData',ud.YLim,'Color','m');
    else
      set(ud.signalAutoLC,'XData',[],'YData',[]);
      set(ud.signalAutoRC,'XData',[],'YData',[]);
    end
  else
    set(ud.thresholdToggle,'Value',0)
  end

case 'left'
  set(gcf,'WindowButtonMotionFcn','epd moveleft');
  set(gcf,'WindowButtonUpFcn','epd release');
  
case 'right'
  set(gcf,'WindowButtonMotionFcn','epd moveright');
  set(gcf,'WindowButtonUpFcn','epd release');
  
case 'release'
  set(gcf,'WindowButtonMotionFcn','');
  set(gcf,'WindowButtonUpFcn','');
  ud=get(gcf,'UserData');
  if getuicontrolvalue(ud.playCheck)
    soundsc(ud.sig(ud.left:ud.right),ud.fs);
  end	

case 'moveleft'
  ud=get(gcf,'UserData');
  currentPoint=get(gca,'CurrentPoint');
  ud.left=min(ud.right-1,max(1,ceil(currentPoint(1))));
  step=round(0.2*(ud.winright-ud.winleft));
  if ud.left <= ud.winleft
    ud.winleft=max(1,ud.winleft-step);
    if ud.winleft > 1
      ud.winright=ud.winright-step;
    end	  
    set(ud.signalAxes,'XLim',[ud.winleft ud.winright]);
  end
  if ud.right >= ud.winright
    ud.winright=min(ud.samples,ud.winright+step);
    if ud.winright < ud.samples
      ud.winleft=ud.winleft+step;
    end	  
    set(ud.signalAxes,'XLim',[ud.winleft ud.winright]);
  end    
  set(ud.signalUserLC,'XData',[ud.left ud.left]);
  set(ud.signalUserRC,'XData',[ud.right ud.right]);
  set(gcf,'UserData',ud);
  
case 'moveright'
  ud=get(gcf,'UserData');
  currentPoint=get(gca,'CurrentPoint');
  ud.right=min(ud.samples,max(ud.left+1,ceil(currentPoint(1))));
  step=round(0.2*(ud.winright-ud.winleft));
  if ud.right >= ud.winright
    ud.winright=min(ud.samples,ud.winright+step);
    if ud.winright < ud.samples
      ud.winleft=ud.winleft+step;
    end	  
    set(ud.signalAxes,'XLim',[ud.winleft ud.winright]);
  end  
  if ud.left <= ud.winleft
    ud.winleft=max(1,ud.winleft-step);
    if ud.winleft > 1
      ud.winright=ud.winright-step;
    end	  
    set(ud.signalAxes,'XLim',[ud.winleft ud.winright]);
  end 
  set(ud.signalUserLC,'XData',[ud.left ud.left]);
  set(ud.signalUserRC,'XData',[ud.right ud.right]);  
  set(gcf,'UserData',ud);
case 'create'
  [sig,fs,name]=createsig;
  if length(sig)
    ud=get(gcf,'UserData');
    ud.sig=sig; ud.name=name; ud.fs=fs; 
    set(gcf,'UserData',ud);
    epd 'newsig'
  end
  
case 'load'
  ud=get(gcf,'UserData');
  [name,sig,fs]=loadsig(fullfile(madroot,'data','sounds'));
  if length(sig) 
    ud.sig=sig; ud.name=name; ud.fs=fs; 
    set(gcf,'UserData',ud);
    epd 'newsig'
  end
     
case 'newsig'
  ud=get(gcf,'UserData');
  ud.sig=ud.sig;
      ud.sig=normalise(ud.sig(:));  % ensure column vector
      ud.fs=ud.fs;
      ud.samples=length(ud.sig);
      ud.winleft=1;
      ud.winright=ud.samples;
      ud.left=round(0.1*length(ud.sig));
      ud.right=round(0.9*length(ud.sig));
      set(ud.plotsToggle,'Value',0);
      set(ud.thresholdToggle,'Value',0);
      set(ud.cursorToggle,'Value',0);
      set(gcf,'UserData',ud);      
      epd showPlots;
      epd showEnds;
      epd plotSignal;
      epd calc;

case 'plotSignal'
  ud=get(gcf,'UserData');
  if ~isempty(ud.sig)
    set(ud.signalAxes,'YLim',[-1.1 1.1],'XLim',[1 ud.samples]);
    set(ud.signalLine,'XData',1:ud.samples,'YData',ud.sig,'Color','blue');
    set(ud.signalUserLC,'XData',[ud.left ud.left],'YData',ud.YLim,'Color','red');
    set(ud.signalUserRC,'XData',[ud.right ud.right],'YData',ud.YLim,'Color','red');
  end

case 'playSignal'
  ud=get(gcf,'UserData');
  if ~isempty(ud.sig)
    soundsc(ud.sig,ud.fs);
  end
  
otherwise
  maduievent('epd',action);

end


