function class014()
%CLASS02  Displays plots for ECE 3500 class
%   CLASS02()  creates all the plots for class lecture notes through the
%   use of Dr. Harley's plotforclass MATLAB function. To get the full
%   results from the lecture notes, this function requires the "export_fig"
%   and "oaxes" functions from the MathWorks File Exchange. 
%
%   INPUTS: none
%
%   OUTPUTS: none
%
%   see also: plot, stem, subplot, figure

close all;

namebase = ['../notes/' mfilename()];

Ts = 0.01; Fs = 1/Ts;

n = 1;

fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same');
xlbl{n} = 't'; ylbl{n} = 'x(t)'; ynum{n} = false;  n = n + 1;

fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = cos(1*2*pi*x{n}).*conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same');
xlbl{n} = 't'; ylbl{n} = 'y(t)'; ynum{n} = false;  n = n + 1;

N = length(x{n-1});

fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{n-2})));
xlbl{n} = '\omega'; ylbl{n} = '|X(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;

fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{n-2})));
xlbl{n} = '\omega'; ylbl{n} = '|Y(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;


fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = cos(1*2*pi*x{n}).*cos(1*2*pi*x{n}).*conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same');
xlbl{n} = 't'; ylbl{n} = 'z(t)'; ynum{n} = false;  n = n + 1;

fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same');
xlbl{n} = 't'; ylbl{n} = 'x(t)'; ynum{n} = false;  n = n + 1;

fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{n-2})));
xlbl{n} = '\omega'; ylbl{n} = '|Z(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;

fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{n-2})));
xlbl{n} = '\omega'; ylbl{n} = '|X(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;



fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{2}))).'.*((x{n} > -1) - (x{n} > 1));
xlbl{n} = '\omega'; ylbl{n} = '|Y(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;

fnc{n} = @plot; x{n} = linspace(-Fs/2,Fs/2,N).';    y{n} = fftshift(Ts*abs(fft(y{2}))).'.*((x{n} < -1) + (x{n} > 1));
xlbl{n} = '\omega'; ylbl{n} = '|Y(\omega)|'; axis{n} = [-3 3 0 15];
ynum{n} = false; xTickSuffix{n} = '(2\pi)'; n = n + 1;



fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = 6+conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same');
xlbl{n} = 't'; ylbl{n} = 'x(t)'; ynum{n} = false;  n = n + 1;

fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = cos(1*2*pi*x{n}).*(6+conv((x{n}+5).*((x{n} > -5) - (x{n} > 0)) + (x{n}-5).*((x{n} > 0) - (x{n} > 5)), 1/200*ones(200,1), 'same'));
xlbl{n} = 't'; ylbl{n} = 'v(t)'; ynum{n} = false;  n = n + 1;

fnc{n} = @plot; x{n} = -8:Ts:8;    y{n} = [y{n-1}(:) y{n-2}(:)];
xlbl{n} = 't'; ylbl{n} = 'v(t)'; ynum{n} = false;  n = n + 1;


pltopt{n} = [];
figheight{n} = [];
axis{n} = [];
figwidth{n} = [];
hideticks{n} = [];
marker{n} = [];
markersize{n} = [];
xTickPrefix{n} = [];
xTickSuffix{n} = [];
yTickPrefix{n} = [];
yTickSuffix{n} = [];
ynum{n} = [];

for n = 1:length(x)
    plotforclass( 'fnc', fnc{n}, 'x', x{n}, 'y', y{n}, ...
                  'flname', [namebase '_' num2str(n, '%03u')], ...
                  'xlbl', xlbl{n}, 'ylbl', ylbl{n}, 'figwidth', figwidth{n}, ...
                  'hideticks', hideticks{n}, 'marker', marker{n}, ...
                  'markersize', markersize{n}, 'axis', axis{n}, ...
                  'xTickPrefix', xTickPrefix{n}, 'yTickPrefix', yTickPrefix{n}, ...
                  'yTickSuffix', yTickSuffix{n}, 'figheight', figheight{n}, ...
                  'xTickSuffix', xTickSuffix{n}, ...
                  'pltopt', pltopt{n}, 'ynum', ynum{n});
end


end


function plotforclass( varargin )
%PLOTFORCLASS  Custom plotter for ECE3500
%   PLOTFORCLASS(varargin) Custom MATLAB function to plot signals with
%   specific sizes and options. All inputs are formatted such that one
%   parameter indicates the input variable and the second parameter
%   indicates the parameter. For example, plotforclass('fnc', @stem).
%   Note that this function is still in development.
%
%   INPUT PARAMETERS [all optional]:
%     fnc: The function to use for plotting (typically @plot or @stem)
%       x: The x-values of plotted values
%       y: The y-values of plotted values
%       z: The z-values of plotted values (not active)
%    xlbl: The x-axis label 
%    ylbl: The y-axis label
%    zlbl: The z-axis label (not active)
%    axis: The length-4 vector [xmin xmax ymin ymax]
%   figno: The figure number for the given plot
%    ynum: If true, numbers y-values are displayed over points
%   oaxes: If true (and oaxes is found), plots are displayed using the
%          oaxes function from the Mathworks File Exchange
%  pltopt: Cell of plot options for given plot function (fnc)
% saveimg: If true (and export_fig is found), saves figure using the 
%          export_fig function from the Mathworks File Exchange
%  flname: String of the output file for saving. 
%
%   see also: plot, stem
%


    % SET DEFUALT OPTIONAL ARGUMENTS
    opt.fnc          = @plot;
    opt.x            = [];
    opt.y            = randn(length(opt.x));
    opt.z            = [];
    opt.xlbl         = 't';
    opt.ylbl         = 'x(t)'; 
    opt.zlbl         = '?';
    opt.axis         = [];
    opt.figno        = 0;
    opt.ynum         = false;
    opt.oaxes        = true;
    opt.pltopt       = {'linewidth', 1.5};
    opt.saveimg      = true;
    opt.marker       = [];
    opt.fontsize     = 8;
    opt.markersize   = 3;
    opt.flname       = 'my_image.png';
    opt.figwidth     = 2.25;
    opt.hideticks    = false;
    opt.xTickPrefix  = '';
    opt.xTickSuffix  = '';
    opt.yTickPrefix  = '';
    opt.yTickSuffix  = '';
    opt.yTickP  = '';
    opt.figheight    = 1.25;
    opt.myColorMap   = [ 79 129 189; ... %Blue
                         192  80  70; ... %Red
                         155 187  89; ... %Green
                         128 100 162; ... %Purple
                         247 150  70; ... %Orange
                         75  172 192; ... %Cyan
                       ]/255;
    
    % PARSE ARGUMENTS 
    if ~isempty(varargin), [opt, varargin] = parseArgs(opt, varargin{:}); end 
    if strcmp(func2str(opt.fnc),'plot') && max(strcmp(varargin,'ynum')), opt.ynum = false; end
    if strcmp(func2str(opt.fnc),'stem') && max(strcmp(varargin,'ynum')), opt.ynum = true; end

    
    % --------------------------------------------------------------------
    % PRE-PLOTTING FIGURE SETTINGS ---------------------------------------
    % --------------------------------------------------------------------
    
    % GET FIGURE
    if ~opt.figno,
        f = figure();
    else
        % OPEN AND CLOSE AND REOPEN FIGURE TO REMOVE PRIOR CHANGES
        figure(opt.figno); close(opt.figno); figure(opt.figno);
    end
    
    % SET SIZE, LOCATION, AND PROPERTIES OF THE FIGURE
    set(gcf, 'Units', 'inches', 'Position', [1 1 opt.figwidth opt.figheight], 'color', [1 1 1]);
    set(gcf, 'DefaultAxesColorOrder', opt.myColorMap)
    subplot(1,1,1);                                 % No subplot
    pos = get(gca,'position');                      % Read position [x y z]
    set(gca,'position',[.1 pos(2:4)-[0 -.01 0.1]])  % Move label to right
    
    
    % --------------------------------------------------------------------
    % DISPLAY DATA -------------------------------------------------------
    % --------------------------------------------------------------------
    
    % PLOT DATA
    if isempty(opt.x)
        h = opt.fnc(opt.y,        opt.pltopt{:},'MarkerFaceColor','auto', 'MarkerSize', 5, 'MarkerSize', opt.markersize);
    else
        h = opt.fnc(opt.x, opt.y, opt.pltopt{:},'MarkerFaceColor','auto', 'MarkerSize', 5, 'MarkerSize', opt.markersize);
    end
    
    
    % OPTIONAL SETTING
    if ~isempty(opt.marker), set(h, 'marker', opt.marker); end
    maxy = max(opt.y(:)); miny = min(opt.y(:));
    maxx = max(opt.x(:)); minx = min(opt.x(:));
    if ~isempty(opt.axis)
        minx = opt.axis(1); maxx = opt.axis(2); 
        miny = opt.axis(3); maxy = opt.axis(4);
    end
    if miny == maxy, miny = 0; end
    rangey = maxy - miny;
    if opt.ynum
        for ii = 1:length(opt.x), text(opt.x(ii), opt.y(ii)+sign(opt.y(ii)+eps)*rangey*0.25, ['  ' num2str(round(opt.y(ii)*100)/100)], 'HorizontalAlign', 'Center', 'FontName', 'Times New Roman'); end
    end
    if opt.hideticks
        set(gca,'xtick',[])
    end
    
    set(gca, ...
      'Box'         , 'off'          , ...
      'TickDir'     , 'out'          , ...
      'TickLength'  , [.01 .01]      , ...
      'XMinorTick'  , 'off'          , ...
      'YGrid'       , 'off'          , ...
      'XGrid'       , 'off'          , ...
      'Color'       , [.93 .93 .93]  , ...
      'YColor'      , [1  1  1]*.55   , ...
      'XColor'      , [1  1  1]*.55   , ...
      'FontName', 'Times New Roman'  , ...
      'FontSize', opt.fontsize);
    
    % --------------------------------------------------------------------
    % SET COLORS AND AXES ------------------------------------------------
    % --------------------------------------------------------------------
    
    % USE OAXES IF SELECTED AND POSSIBLE
    if opt.oaxes && exist('oaxes', 'file')
        set(gca,'Visible','off')
        oa = oaxes('origin', [0 0 0], 'xlabel', {'',['  \it' opt.xlbl]}, 'ylabel', {'',['\it' opt.ylbl]}, ...
                   'ArrowAspectRatio', 1, 'Arrow', 'off', 'AxisLabelLocation', 'end', ...
                   'YLabelHorizontalAlignment', 'right', 'linewidth', 0.5, 'TickLabelFontName', 'Times New Roman');
    end
    axis([minx-eps maxx+eps miny-rangey*.1-rangey*0.25*opt.ynum maxy+rangey*0.1+rangey*0.25*opt.ynum])
    
    % PLOT LINES
    ytick = get(gca, 'ytick'); %ytick = setdiff(ytick, [min(ytick) max(ytick)]);
    hold on;
    p2 = plot([minx maxx], ones(2,1)*ytick, '-w', 'linewidth', 1, 'linestyle', '-'); hold off;
    set(p2, 'HandleVisibility', 'off')
    children = get(gca, 'children');
    middlechildren = setdiff(children, [h(:); p2(:)]);
    set(gca,'children',[h(:); middlechildren(:); p2(:)])
    
    myxtick = get(gca, 'XTickLabel');
    set(gca, 'XTickLabel', [repmat(opt.xTickPrefix, size(myxtick,1), 1) myxtick repmat(opt.xTickSuffix, size(myxtick,1), 1)]);

    myytick = get(gca, 'YTickLabel');
    set(gca, 'YTickLabel', [repmat(opt.yTickPrefix, size(myytick,1), 1) myytick repmat(opt.yTickSuffix, size(myytick,1), 1)]);
    
    uistack(h, 'top')   
    set(findall(gcf,'type','text'),'FontName','Times New Roman')
    set(findall(gcf,'type','text'),'FontSize',opt.fontsize)
    
    drawnow();
    
    

    % --------------------------------------------------------------------
    % SAVE PLOT ----------------------------------------------------------
    % --------------------------------------------------------------------
    
    if opt.saveimg && exist('export_fig', 'file')
        if opt.oaxes && exist('oaxes', 'file'), set(oa, 'TickLength', get(oa, 'TickLength')*5); end
        export_fig(opt.flname, '-m5')
        if opt.oaxes && exist('oaxes', 'file'), set(oa, 'TickLength', get(oa, 'TickLength')/5); end
    end

end


function [options, newvarargin] = parseArgs(options, varargin)

    % ---------------------------------------------------
    % CODE ORGINATED FROM STACKOVERFLOW & THEN MODIFIED
    %   http://stackoverflow.com/questions/2775263/how-to-deal-with-name-value-pairs-of-function-arguments-in-matlab
    % ---------------------------------------------------
    
    % GET OPTIONS NAMES
    optionNames = fieldnames(options);

    % COUNT ARGUMENTS
    nArgs = length(varargin);
    if round(nArgs/2)~=nArgs/2
       error('Function needs propertyName/propertyValue pairs')
    end
    
    
    % PARSE ARGUMENTS
    n = 1; flag = false;
    newvarargin = {};
    for m = 1:numel(varargin)
       if flag, flag = false; continue; end
       inpName = varargin{m}; % make case insensitive

       if any(strcmpi(inpName,optionNames)) && m < numel(varargin) && ~isempty(varargin{m+1})
          % overwrite options. If you want you can test for the right class here
          % Also, if you find out that there is an option you keep getting wrong,
          % you can use "if strcmp(inpName,'problemOption'),testMore,end"-statements
          options.(inpName) = varargin{m+1}; flag = true;
       else
          newvarargin{n} = varargin{m}; n = n + 1;
       end
    end

end
