function wvmovie(action,myFunction,min_t,max_t,min_x,max_x)
%WVMOVIE  Wave animator
%
%         <DESCRIPTION>
%         wvmovie is a graphical interface to animate a function u(x,t) 
%         with respect to time.  
%
%         <TO RUN>
%         Type wvmovie at the MATLAB prompt with no arguments.
%
%         <USE>
%         After startup, several controls can be set:
%
%           Time t  - Animate u(x,t) over the time interval t0 < t < t1
%           Range x - At each time t, graph u(x,t) over the interval x0 < x < x1
%           Speed   - Slider which adjusts the number of frames per unit t
%           u(x,t)  - The function of x and t to animate
%
%         After setting the controls, press PLAY to animate.
%
%         The OTHER VIEWS menu passes the movie parameters to two other
%         visualization tools.  SURFACE PLOT graphs u=u(x,t) in xtu-space.
%         SLICE PLOT graphs slices of the surface u=u(x,t) in xtu-space
%         at discrete times.

% Created: 7/95 by R. Knobel
% Last revised: 1/3/99  R. Knobel
% Requires:  MATLAB 4.2(c) - MATLAB 5.2
% Also links to: wvslice.m and wvsurf.m

if nargin < 1
   action = 'start';
end

if ~strcmp(action,'start')
   handles = get(gcf,'UserData');
   hPlot = handles(1);
   hAxes = handles(2);
   hFunction = handles(3);
   hXmin = handles(4);
   hXmax = handles(5);
   hTmin = handles(6);
   hTmax = handles(7);
   hSpeed = handles(8);
end;


if strcmp(action,'start'),
   
   bgcolor = 'black';
   fgcolor = 'white';
   
   figure;
   set(gcf, ...
      'NumberTitle','off', ...
      'Name','Wave Movie', ...
      'BackingStore','off',...
      'Units','normalized',...
      'Color',bgcolor);
   
   % Console Frame 
   
   top      =0.95;
   bottom   =0.05;
   left     =0.82;
   btnWid   =0.13;
   btnHt    =0.06;
   spacing  =0.02;
   frmBorder=0.02;
   
   frmPos=[.79 .15 btnWid+3*frmBorder .82];
   uicontrol( ...
      'Style','frame', ...
      'Units','normalized', ...
      'Position', frmPos, ...
      'ForegroundColor',fgcolor,...
      'BackgroundColor',bgcolor);
   
   %  Time interval
   
   uicontrol( ...
      'Style','text',...
      'Units','normalized',...
      'Position', [.81 .905 .15 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor','red',...
      'String','Time t');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.81 .86 .08 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Initial');
   if nargin < 3,
      min_t = 0;
   end;
   hTmin=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.89 .86 .07 .04],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',num2str(min_t));
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.81 .81 .08 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Final');
   if nargin < 4,
      max_t = 3;
   end;
   hTmax=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.89 .81 .07 .04],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',num2str(max_t));
   
   % X interval
   
   uicontrol( ...
      'Style','text',...
      'Units','normalized',...
      'Position', [.81 .73 .15 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor','red',...
      'String','Range x');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.81 .68 .06 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Min');
   if nargin < 5,
      min_x = 0;
   end;
   hXmin=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.87 .68 .09 .04],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',num2str(min_x));
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.81 .63 .06 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Max');
   if nargin < 6,
      max_x = 5;
   end;
   hXmax=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.87 .63 .09 .04],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',num2str(max_x));
   
   % Speed control
   
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.81 .55 .15 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor','red',...
      'String','Speed');
   
   min_frames= 10;
   max_frames= 200;
   speed     = 50;
   hSpeed=uicontrol( ...
      'Style','slider',...
      'Units','normalized',...
      'Position',[.81 .50 .15 .04],...
      'Value',speed,...
      'Max',max_frames,...
      'Min',min_frames);
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.805 .46 .06 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Fast'); 
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.91 .46 .055 .04],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','Slow');
   
   
   % The Play button
      
   uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[left .35  btnWid btnHt], ...
      'String','Play', ...
      'Callback','wvmovie(''move'')');
   
   % The Restart button
   
   uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[left .27  btnWid btnHt], ...
      'String','Restart', ...
      'Callback','wvmovie(''restart'')');
   
   % The Close button
   
   uicontrol('Style','Pushbutton', ...
      'Units','normalized',...
      'Position',[left .19 btnWid btnHt], ...
      'Callback','wvmovie(''close'')',...
      'String','Close');
   
   % Field to define the function u(x,t) 
      
   if nargin < 2,
      myFunction = 'exp(-(x-t)^2)';
   end;
   
   uicontrol('Style','text',...
      'Units','normalized',...
      'Position',[.03 .07 .10 .045],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','u(x,t) =');
   
   hFunction=uicontrol(...
      'Style','edit',...
      'Units','normalized',...
      'Position',[.13 .07 .64 .045],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',myFunction );
   
   
   % Menu for calling other 3D visualization tools 
   
   view_menu = uimenu('Label','Other Views');
   
   uimenu(view_menu,...
      'Label','Surface Plot',...
      'CallBack','wvmovie(''GotoSurface'')');
   uimenu(view_menu,...
      'Label','Slice Plot',...
      'CallBack','wvmovie(''GotoSlice'')');
   
   % Setup main plot area
      
   hAxes = axes(...
      'Position',[.12 .28 .6 .6],...
      'XLim',[0 1],...
      'YLim',[0 1],...
      'Color',bgcolor,...
      'XColor',fgcolor,...
      'YColor',fgcolor);
   hold on;
   xlabel('x');
   ylabel('u(x,t)');
   hPlot = plot(0,0,'y','EraseMode','xor');
   
   handles = [hPlot hAxes hFunction hXmin hXmax hTmin hTmax hSpeed];
   set(gcf,'UserData',handles); 
      
   wvmovie('restart')
   
elseif strcmp(action,'restart'),
   
   min_t       = str2num(get(hTmin,'String'));
   max_t       = str2num(get(hTmax,'String'));
   min_x       = str2num(get(hXmin,'String'));
   max_x       = str2num(get(hXmax,'String'));
   
   f = get(hFunction,'String');
   l = length(f);
   for k = fliplr(find((f=='^') | (f=='*') | (f=='/')))
      if ~strcmp(f(k-1),'.')
         f = [f(1:k-1) '.' f(k:l)];
         l = l+1;
      end
   end
   vectorized_f = f;
   
   [x t] = meshgrid(linspace(min_x,max_x,25),linspace(min_t,max_t,25));
   u = eval(vectorized_f);
   min_u = min(min(u));
   max_u = max(max(u));
   
   scale = max_u - min_u + eps;
   max_u = max_u + 0.1*scale;
   min_u = min_u - 0.1*scale;
   set(hAxes, 'XLim',[min_x max_x],'YLim',[min_u max_u]);
   
   clear t x u
   x = linspace(min_x,max_x,100);
   t = min_t;
   u = eval(vectorized_f);
   set(hPlot, 'XData',x,'YData',u);
   
elseif strcmp(action,'move'),
   
   min_t = str2num(get(hTmin,'String'));
   max_t = str2num(get(hTmax,'String'));
   min_x = str2num(get(hXmin,'String'));
   max_x = str2num(get(hXmax,'String'));
   
   x       = linspace(min_x,max_x,100); 
   speed   = get(hSpeed,'Value');
   NFrames = fix(speed * (max_t - min_t));
   Del_t   = (max_t - min_t) / NFrames;
   
   f = get(hFunction,'String');
   l = length(f);
   for k = fliplr(find((f=='^') | (f=='*') | (f=='/')))
   if ~strcmp(f(k-1),'.')
     f = [f(1:k-1) '.' f(k:l)];
     l = l+1;
   end
   end
   vectorized_f = f;
   
   for j=1:NFrames,
      
      t = min_t + j*Del_t;
      u = eval(vectorized_f); 
      set(hPlot,'XData',x,'YData',u)
      pause(0.01)
      
   end
   
elseif strcmp(action(1:4),'Goto')
   
   myFunction = get(hFunction,'String');
   min_x      = str2num(get(hXmin,'String'));
   max_x      = str2num(get(hXmax,'String'));
   min_t      = str2num(get(hTmin,'String'));
   max_t      = str2num(get(hTmax,'String'));
   
   wvmovie('close')
   
   if strcmp(action,'GotoSlice'),
      wvslice('start',myFunction,min_t,max_t,min_x,max_x),
   elseif strcmp(action,'GotoSurface'),
      wvsurf('start',myFunction,min_t,max_t,min_x,max_x), 
   end;
   
   
elseif strcmp(action,'close'),
   
   close;
   
end