function mytraf(action)
%WVTRAF  This is an animation of a simulation of traffic flow.  Cars stopped 
%        at a red light are packed at a maximum density of U_max cars per mile. 
%        Traffic with density U_in cars per mile approach the end of the 
%        stopped traffic.  When the light turns green, traffic begins to move
%        forward with a density of u(x,t) (cars/mile) after t hours at position x.
%        
%        The density function u(x,t) is constructed from the conservation law
%        model
%
%                u_t + v_max(1 - 2u/u_max) u_x = 0
%
%        with initial traffic density
%            
%                       0      for x > 0
%             u(x,0) = u_max   for -L < x < 0
%                       u_in   for x < -L
%                
%        <TO START>
%        Type wvtraf at the MATLAB prompt with no input arguments.  This
%        routine also requires that WVTRAFFN.M be stored in the same 
%        subdirectory as WVTRAF.N
%
%        <TO USE>
%        After startup, press the PLAY button to begin the animation.  The 
%        top plot shows the initial traffic density u(x,0) followed by the
%        change in traffic density as t increases.  Shown in the lower plot
%        is a diagram of a road with cars reflecting the traffic density.
%
%        The animation can be adjusted through the controls:
%
%          Time - Animate the traffic flow from time Initial to time Final.
%          Range - Show the stretch of road from mile Initial to mile Final.
%                  The traffic light is located at position x=0.
%          Animation - Slider to adjust the animation speed.
%          Maximum Velocity - Velocity of a car if no other cars are on the road.
%          Maximum Density  - Maximum number of cars per mile possible on a road.
%          Incoming Density - Density (cars/mile) of traffic approaching the
%                             red light.
%
%        After adjusting these controls, press the RESTART button to redraw the
%        initial profile of traffic density. 

%Created:  5/95 by R. Knobel
%Last Modified: 4/99 by R. Knobel
%Requires: MATLAB 4.2(c) - MATLAB 5.3, wvtraffn.m 

if nargin < 1
   action = 'start';
end

if ~strcmp(action,'start'),
   handles = get(gcf,'UserData');
   hAxes1 = handles(1);
   hAxes2 = handles(2);
   hVmax  = handles(3);
   hUmax  = handles(4);
   hUin   = handles(5);
   hRoad  = [handles(6) handles(7)];
   hPlay  = handles(8);
   hXmin  = handles(9);
   hXmax  = handles(10);
   hTmin  = handles(11);
   hTmax  = handles(12);
   hSpeed = handles(13);
   hPlot1 = get(hAxes1,'UserData');
   hPlot2 = get(hAxes2,'UserData');
   Num_cars = get(hRoad(1),'UserData');
   Space    = get(hRoad(2),'UserData'); 
end;

% Length L (in miles) of traffic backed up at light

L = .1;

if strcmp(action,'start'),
   
   figure;
   set(gcf, ...
      'NumberTitle','off', ...
      'Name','Traffic', ...
      'backingstore','off',...
      'Color','black',...
      'Units','normalized');
   
   %====================================
   % The Console frame and control fields 
   
   top=0.95;
   bottom=0.05;
   left=0.84;
   btnWid = 0.13;
   btnHt=0.06;
   spacing=0.02;
   
   frmBorder=0.02;
   frmPos=[.82 .15 btnWid+2*frmBorder .82];
   uicontrol( ...
      'Style','frame', ...
      'Units','normalized', ...
      'Position', frmPos, ...
      'ForegroundColor','white',...
      'BackgroundColor','black');
   
   % Time interval
   
   uicontrol( ...
      'Style','text',...
      'Units','normalized',...
      'Position', [.83 .905 .15 .04],...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Time t (hr)');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.83 .86 .08 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Initial');
   
   hTmin=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.91 .86 .07 .04],...
      'BackgroundColor',[1 1 1],...
      'String','0');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.83 .81 .08 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Final');
   
   hTmax=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.91 .81 .07 .04],...
      'BackgroundColor',[1 1 1],...
      'String','.05');
   
   % X Interval
   
   uicontrol( ...
      'Style','text',...
      'Units','normalized',...
      'Position', [.83 .73 .15 .04],...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Range x (mi)');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.83 .68 .06 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Min');
   
   hXmin=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.89 .68 .09 .04],...
      'BackgroundColor',[1 1 1],...
      'String','-.5');
   
   uicontrol( 'Style','text',...
      'Units','normalized',...
      'Position', [.83 .63 .06 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Max');
   
   hXmax=uicontrol( ...
      'Style','edit',...
      'Units','normalized',...
      'Position', [.89 .63 .09 .04],...
      'BackgroundColor',[1 1 1],...
      'String','.5');
   
   % Speed control
   
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.83 .55 .15 .04],...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Animation');
   
   min_frames= 1;
   max_frames= 500;
   speed     = 250;
   hSpeed=uicontrol( ...
      'Style','slider',...
      'Units','normalized',...
      'Position',[.83 .50 .15 .04],...
      'Value',speed,...
      'Max',max_frames,...
      'Min',min_frames);
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.825 .46 .06 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Fast'); 
   uicontrol(...
      'Style','text',...
      'Units','normalized',...
      'Position',[.93 .46 .055 .04],...
      'BackgroundColor','black',...
      'ForegroundColor',[.8 .65 .4],...
      'String','Slow');
   
   
   %====================================
   % The Play/Pause button
   
   hPlay = uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[left .35  btnWid btnHt], ...
      'String','Play', ...
      'Interruptible','yes',...
      'Callback','wvtraf(''play_btn'')'); 
   
   
   
   %========================================
   % The Restart button
   
   uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[left .27  btnWid btnHt], ...
      'String','Restart', ...
      'Callback','wvtraf(''restart'')');
   
   %========================================
   % The CLOSE button
   
   uicontrol('Style','Pushbutton', ...
      'Units','normalized',...
      'Position',[left .19 btnWid btnHt], ...
      'Callback','wvtraf(''close'')',...
      'String','Close');
   
   
   %========================================
   % Traffic parameters:  Maximum car velocity,
   % maximum car density, and incoming car density.
   
   uicontrol('Style','text',...
      'Position',[.03 .11 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Maximum');
   uicontrol('Style','text',...
      'Position',[.03 .07 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Velocity =');
   uicontrol('Style','text',...
      'Units','normalized',...
      'Position',[.03 .03 .10 .045],...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','(mi/hr)');
   hVmax=uicontrol(...
      'Style','edit',...
      'Position',[.13 .07 .07 .045],...
      'Units','normalized',...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String','45');
   
   uicontrol('Style','text',...
      'Position',[.25 .11 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Maximum');
   uicontrol('Style','text',...
      'Position',[.25 .07 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','density =');
   uicontrol('Style','text',...
      'Position',[.25 .03 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','(cars/mi)');
   hUmax=uicontrol(...
      'Style','edit',...
      'Position',[.35 .07 .07 .045],...
      'Units','normalized',...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String','200');
   
   uicontrol('Style','text',...
      'Position',[.47 .11 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','Incoming');
   uicontrol('Style','text',...
      'Position',[.47 .07 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','density =');
   uicontrol('Style','text',...
      'Position',[.47 .03 .10 .045],...
      'Units','normalized',...
      'BackgroundColor','black',...
      'ForegroundColor','red',...
      'String','(cars/mi)');
   hUin=uicontrol(...
      'Style','edit',...
      'Position',[.57 .07 .07 .045],...
      'Units','normalized',...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String','10');
   
   %========================================
   % Setup main plot stuff
   
   % Top axis contains the plot of traffic density u(x,t) 
   
   hAxes1 = axes('Position',[.09 .45 .70 .45],...
      'Color','black',...
      'XColor','white',...
      'YColor','white',...
      'XLim',[0 1],...
      'YLim',[0 1]);
   hold on;
   xlabel('x');
   ylabel('u(x,t)');
   title('Traffic Density (cars / mile)','Color','white');
   hPlot1 = plot(0,0,'y','EraseMode','xor');
   
   % Bottom axis contains the movement of cars 
   
   hAxes2 = axes('Position',[.09 .20 .70 .10],...
      'XLim',[0 1],...
      'YLim',[-1,1],...
      'Visible','off'); 
   hold on;
   hRoad = plot([0 1],[.5 .5],'w', [0 1],[-.5 -.5],'w','EraseMode','xor');
   
   hPlot2 = zeros(1000,1);
   for j=1:1000,
      hPlot2(j) = plot(-1000,0,'y','EraseMode','xor');
   end;
   
   handles = [hAxes1 hAxes2 hVmax hUmax hUin hRoad(1) hRoad(2) hPlay hXmin hXmax ...
         hTmin hTmax hSpeed]; 
      
   set(gcf,'UserData',handles);
   set(hAxes1,'UserData',hPlot1);
   set(hAxes2,'UserData',hPlot2);
   Num_cars = 0;
   set(hRoad(1),'UserData',Num_cars);
   Space = 0;
   set(hRoad(2),'UserData',Space); 
      
   wvtraf('restart');
      
   elseif strcmp(action,'restart'),
      
      min_x = str2num(get(hXmin,'String'));
      max_x = str2num(get(hXmax,'String'));
      v_max = str2num(get(hVmax,'String'));
      u_max = str2num(get(hUmax,'String'));
      u_in  = str2num(get(hUin,'String'));
      
      % Reset axis limits
      
      max_y = u_max; 
      min_y = 0; 
      scale = max_y - min_y + eps;
      max_y = max_y + 0.1*scale;
      min_y = min_y - 0.1*scale;
      set(hAxes1, 'XLim',[min_x max_x],'YLim',[min_y max_y]);
      set(hAxes2, 'XLim',[min_x max_x]);
      set(hRoad,'XData',[min_x max_x]);
      
      % Plot initial density function
      
      x = linspace(min_x,max_x,50);
      t = 0;
      u = wvtraffn(x,t,v_max,u_max,u_in,L); 
      set(hPlot1, 'XData',x,'YData',u);
      
      % Plot initial position of cars
      
      car       = zeros(1000,1);
      car_size  = .005;
      plot1_pos = get(hAxes1,'Position');
      scale_factor = plot1_pos(3) / (max_x - min_x);
      
      % First do the cars that are packed behind the light
      
      Num_cars = 0;
      space    = 1/u_max;
      xpos     = -space;
      while xpos > -L,
         Num_cars = Num_cars + 1;
         car(Num_cars) = xpos;
         xpos = xpos - space;
      end;
      
      % Now do the incoming cars
      
      if u_in == 0,
         Space = 1000;
      else,
         Space = 1 / u_in; 
         xpos  = -L - Space;
         while xpos > min_x,
            Num_cars      = Num_cars + 1;
            car(Num_cars) = xpos;
            xpos          = xpos - Space;
         end;
      end;
      
      set(hRoad(1),'UserData',Num_cars);
      set(hRoad(2),'UserData',Space);
      for j=1:Num_cars,
         set(hPlot2(j),'XData',car(j),'YData',0);
      end;
      for j=Num_cars+1:1000,
         set(hPlot2(j),'XData',-1000);
      end;
      
      set(hPlay,'String','Play')
      
   elseif strcmp(action,'play_btn')
      
      sPlay = get(hPlay,'String');
      if strcmp(sPlay,'Play'),
         set(hPlay,'String','Pause')
         wvtraf('move')
      elseif strcmp(sPlay,'Pause'),
         set(hPlay,'String','Resume');
      else
         set(hPlay,'String','Pause')
      end;
      
   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'));
      speed = get(hSpeed,'Value');
      v_max = str2num(get(hVmax,'String'));
      u_max = str2num(get(hUmax,'String'));
      u_in  = str2num(get(hUin,'String'));
      
      Del_t   = (max_t - min_t) / speed; 
      x       = linspace(min_x,max_x,50);
      
      car = zeros(1000,1);      
      for j=1:Num_cars,
         car(j) = get(hPlot2(j),'XData');
      end;
      
      first_car = 1;
      last_car  = Num_cars;
      
      t = min_t;
      while t < max_t,
         
         t = t + Del_t; 
         u = wvtraffn(x,t,v_max,u_max,u_in,L);
         set(hPlot1,'YData',u)
         
         density  = wvtraffn(car,t,v_max,u_max,u_in,L);
         velocity = v_max*(1 - (1/u_max)*density);
         car      = car + Del_t * velocity;
         
         if car(first_car) > max_x,
            %delete(hPlot2(first_car));
            first_car = first_car + 1;
         end;
         
         if car(last_car) > min_x + Space,
            last_car = last_car + 1;
            car(last_car) = car(last_car -1) - Space;
         end;
         
         for j=first_car:last_car,
            set(hPlot2(j),'XData',car(j),'YData',0);
         end;
         
         pause(0.01);
         while strcmp(get(hPlay,'String'),'Resume')
            pause(0.01);
         end;
               
      end;
      set(hPlay,'String','Play')
      
   elseif strcmp(action,'close'),
      
      close
      
   end
   
   
   
   