function wvfour2(action)
%WVFOUR2  Visual construction of Fourier sine series
%
%         <DESCRIPTION>
%         wvfour2 is a graphical interface for constructing Fourier sine series
%         approximations of a function f(x) by manually adjusting coefficients
%         c(n) of 
%
%               sum( c(n) sin(n Pi x), n=1:N)
%
%         <TO RUN>
%         Type wvfour2 at the MATLAB prompt with no arguments.
%
%         <TO USE>
%         Once started, two plot areas are shown.  On the bottom is a graph of
%         coefficients c(1),c(2),c(3),... which are used to define the function
%
%              S(x) = c(1)sin(Pi x) + c(2)sin(2Pi x) + c(2)sin(3Pi x) + ...
%
%         The values of c(n) can be changed by clicking on the graph of c(n). 
%
%         On top are the graphs of the default function f(x) and S(x).  By 
%         clicking on the lower plot area to change the values of c(n), the
%         resulting change in S(x) is displayed in the top graph.  By watching 
%         the changes in S(x), one can attempt to adjust the coefficients c(n) 
%         so that S(x) approximates f(x).  
%
%         Set Coefficient Buttons:
%
%           All Zero - sets all c(n) back to 0
%           Actual   - sets all c(n) to the actual Fourier sine series coefficients
%
%         Actual Coefficient Radio Buttons:
%
%           Hide - hides the actual Fourier sine coefficients from the bottom plot.
%           Show - displays the actual Fourier sine coefficients on the bottom 
%                  plot in addition to the values of c(n)
%

% Created: 6/95 by R. Knobel
% Last Modified: 1/99 by R. Knobel
% Requires: MATLAB 4.2(c) - MATLAB 5.2


if nargin < 1
   action = 'start';
end

if ~strcmp(action,'start'),
   handles = get(gcf,'UserData');
   hFunction = handles(1);
   hAxes1 = handles(2);
   hAxes2 = handles(3);
   hPlot1a = handles(4);
   hPlot1b = handles(5);
   hHide = handles(6);
   hShow = handles(7);
   
   handles = get(hAxes2,'UserData');
   hPlot2a = handles(1,:);
   hPlot2b = handles(2,:);
   
end;

% Number of terms to use in the truncated series. Used by most actions

Max_terms = 10;

if strcmp(action,'start'),
   
   bgcolor = 'black';
   fgcolor = 'white';
   
   set(gcf, ...
      'NumberTitle','off', ...
      'Name','Constructing Fourier Sine Series', ...
      'BackingStore','off',...
      'Units','normalized',...
      'Color',bgcolor);
   
   % The CONSOLE frame

   top   =0.95;
   bottom=0.05;
   left  =0.87;
   right =0.97;
   btnHt =0.08;
   btnWid=0.10;
   space =0.02;
   
   frmPos=[left-space bottom-space right-left+2*space top-bottom+2*space]; 
   uicontrol( ...
      'Style','frame', ...
      'Units','normalized', ...
      'Position',frmPos, ...
      'ForegroundColor','white',...
      'BackgroundColor','black');
   
   % Buttons to set the adjustable coefficients to All Zero or to their 
   % Actual Fourier sine series values 
   
   uicontrol( ...
      'Style','Frame',...
      'Units','normalized',...
      'Position',[left-.01 .71 btnWid+.02 .20],...
      'BackgroundColor','black',...
      'ForegroundColor','white');
   uicontrol( ...
      'Style','Text',...
      'Units','normalized',...
      'Position',[left .84 btnWid .05],...
      'String','Set Coeff',...
      'ForegroundColor','red',...
      'BackgroundColor','black');
   uicontrol( ...
      'Style','Push', ...
      'Units','normalized', ...
      'Position',[left .79 btnWid .05],...
      'String','All Zero',...
      'CallBack','wvfour2(''setcoeffzero'')');
   uicontrol( ...
      'Style','Push',...
      'Units','normalized',...
      'Position',[left .72 btnWid .05],...
      'String','Actual',...
      'CallBack','wvfour2(''setcoeffactual'')');
   
   %==========================================
   %  To Hide or Show Actual Coefficients with the adjustable coefficients
   
   uicontrol( ...
      'Style','Frame',...
      'Units','normalized',...
      'Position',[left-.01 .36 btnWid+.02 .24],...
      'BackgroundColor','black',...
      'ForegroundColor','white');
   uicontrol( ...
      'Style','Text',...
      'Units','normalized',...
      'Position',[left .47 btnWid .10],...
      'String','Actual Coeff',...
      'Backgroundcolor','black',...
      'Foregroundcolor','red');
   hHide = uicontrol(...
      'Style','radio',...
      'String','Hide',...
      'Units','normalized',...
      'Position',[left .42 btnWid .05],...
      'Value',1,...
      'CallBack','wvfour2(''actualhide'')',...
      'BackgroundColor',[.8 .8 .8]);
   hShow = uicontrol(...
      'Style','radio',...
      'String','Show',...
      'Units','normalized',...
      'Position',[left .37 btnWid .05],...
      'Value',0,...
      'CallBack','wvfour2(''actualshow'')',...
      'BackgroundColor',[.8 .8 .8]);
   
   % The Restart button
   
   uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[left bottom+btnHt+space btnWid btnHt], ...
      'String','Restart', ...
      'Callback','wvfour2(''restart'')');
   
   % The CLOSE button
   
   uicontrol('Style','Pushbutton', ...
      'Units','normalized',...
      'Position',[left bottom btnWid btnHt], ...
      'Callback','wvfour2(''close'')',...
      'String','Close');
   
   % Field in middle of screen to enter f(x)
   
   f = 'x*(1-x)'; 
   
   uicontrol('Style','text',...
      'Units','normalized',...
      'Position',[.23 .48 .10 .045],...
      'BackgroundColor',bgcolor,...
      'ForegroundColor',fgcolor,...
      'String','f(x) = ');
   hFunction=uicontrol(...
      'Style','edit',...
      'Units','normalized',...
      'Position',[.33 .48 .25 .045],...
      'BackgroundColor','white',...
      'ForegroundColor','black',...
      'String',f);
   
   %========================================
   % Setup Initial Plot Areas 
   
   % Top axis contains the plots of f(x) (green) and the  
   % Fourier approx (yellow)
   
   hAxes1 = axes(...
      'Position',[.10 .62 .70 .30],...
      'XLim',[0 1],...
      'YLim',[0 1],...
      'XColor',fgcolor,...
      'YColor',fgcolor,...
      'Color',bgcolor);
   hold on;
   xlabel('x');
   ylabel('f(x)');
   title('Green - f(x)    Yellow - Constructed Fourier Sine Series','Color',fgcolor);
   hPlot1a = plot(0,0,'g','EraseMode','xor');
   hPlot1b = plot(0,0,'y','EraseMode','xor');
   
   % Bottom axis contains the plots of the Fourier coeff for f(x) (green)
   % and the movable coeff (yellow).  A blue dashed line along y=0
   % is also drawn for reference.
   
   hAxes2 = axes(...
      'Position',[.10 .12 .70 .30],...
      'XLim',[0 Max_terms],...
      'YLim',[0,1],...
      'XColor',fgcolor,...
      'YColor',fgcolor,...
      'Color',bgcolor,...
      'ButtonDownFcn', 'wvfour2(''click'')' );
   hold on;
   xlabel('Click on plot to move values of c(n)');
   ylabel('Coefficients of sin(n*Pi*x)');
   for k=1:Max_terms
      hPlot2a(k) = plot(k,0,'go','EraseMode','xor',...
         'Visible','off',...
         'Interruptible','yes',...
         'ButtonDownFcn','wvfour2(''click'')');
      hPlot2b(k) = plot(k,0,'yo','EraseMode','xor',...
         'ButtonDownFcn','wvfour2(''click'')');
   end;
   
   handles = [hPlot2a;hPlot2b];
   set(hAxes2,'UserData',handles);
   
   plot([0 Max_terms], [0 0], 'w:', 'EraseMode','xor',...
      'ButtonDownFcn','wvfour2(''click'')');
   
   handles = [hFunction hAxes1 hAxes2 hPlot1a hPlot1b hHide hShow];
   set(gcf,'UserData',handles); 
   
   % Start the plots

   wvfour2('restart')
   
elseif strcmp(action,'restart'),
   
   % Recompute Fourier coefficients
   
   x = linspace(0,1,100);
   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
   vector_f = f;
   
   for k=1:Max_terms,
     integrand = ['(' vector_f ').* sin(pi*' num2str(k) '*x)'];
     sin_coeff(k) = 2*sum( eval(integrand) ) / 100;
   end;
      
   % Recompute axis limits for upper plot
   
   y = eval(vector_f);
   if length(y)==1,
      y = y*ones(size(x));
   end;
   
   a = min(y);
   b = max(y);
   scale = b-a;
   if scale==0,
      scale=1;
   end;
   
   min_y = min([0 a-.1*scale]);
   max_y = max([0 b+.1*scale]);
   set(hAxes1, 'YLim',[min_y max_y]);
   
   % Plot original function (this stays fixed unless restarted)
   
   set(hPlot1a, 'XData',x,'YData',y);
   
   % Recompute axis limits for lower plot
   
   b = max( abs(sin_coeff) );
   if b==0,
      b = 0.1;
   end;
   
   min_y = -1.3*b;
   max_y =  1.3*b;
   set(hAxes2, 'YLim',[min_y max_y]);
   
   % Plot the actual Fourier coeff of f(x).  
   % These are hidden until the Show radio button is pushed.
   
   for k=1:Max_terms
      set(hPlot2a(k),'YData',sin_coeff(k),'Visible','off')
   end;
   set(hHide,'Value',1)
   set(hShow,'Value',0)
   
   % Start with all coeff = 0.
   
   for k=1:Max_terms
      set(hPlot2b(k),'YData',0);
   end;
   
   wvfour2('draw')
   
elseif strcmp(action,'click'),
   
   % Get (x,y) coordinates of mouse click
   
   pt=get(gca,'currentpoint');
   x =pt(1,1);
   y =pt(1,2);
   
   % Determine nearest value of n to the x coordinate
   % (within limits)
   
   n = round(x);
   if n<1 
      n = 1;
   elseif n > Max_terms
      n = Max_terms;
   end;
   
   % Move Coeff(n) up/down to the height of the click
   
   coeff = y;
   y_limits = get(hAxes2,'YLim');
   if coeff<y_limits(1) 
      coeff = y_limits(1);
   elseif coeff>y_limits(2)
      coeff = y_limits(2);
   end;
   
   % Redraw figures
   
   set(hPlot2b(n),'YData',coeff);
   wvfour2('draw')
   
elseif strcmp(action,'draw')  
   
   % Redraw Fourier Series plot in top graph     
   
   x = linspace(0,1,100); 
   y = zeros( size(x) );
   for k=1:Max_terms,
      coeff = get(hPlot2b(k),'YData');
      y = y + coeff * sin(k*pi*x);
   end;
   set(hPlot1b,'XData',x,'YData',y)
   
   % Redraw Fourier coefficients in lower graph
   %
   %for k=1:Max_terms,
   %   set(hPlot2b(k), 'YData', Coeff(k));
   %end;
   
elseif strcmp(action(1:4),'setc'),
   
   if strcmp(action,'setcoeffzero')
      for k=1:Max_terms
         set(hPlot2b(k),'YData',0);
      end;
   elseif strcmp(action,'setcoeffactual')
      for k=1:Max_terms
         true_coeff = get(hPlot2a(k),'YData');
         set(hPlot2b(k),'YData',true_coeff);
      end;
   end;
   
   wvfour2('draw')
   
elseif strcmp(action(1:4),'actu'),
   
   % Show or hide the actual Fourier coefficients.
   
   if strcmp(action,'actualhide')
      for k=1:Max_terms
         set(hPlot2a(k),'Visible','off')
      end;
      set(hHide,'Value',1)
      set(hShow,'Value',0)
   elseif strcmp(action,'actualshow'),
      for k=1:Max_terms
         set(hPlot2a(k),'Visible','on')
      end;
      set(hHide,'Value',0)
      set(hShow,'Value',1)
   end;
   
elseif strcmp(action,'close'),
   
   close
   
end