function class004()
%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()];

n = 1;
fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 1 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 1 2 1 .5 .2 0 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 1 1 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 0 0 1 2 1 .5 .2];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 1 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 1 2 1 .5 .2 0 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 1 1 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 0 1 2 1 1 1 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;



fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 0 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 2 0 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 0 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 0 0 1 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;



fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 0 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 0 2 1.5 1 .5 .25 .125 .1 .09];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 0 1 0 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'x[n]'; n = n + 1;

fnc{n} = @stem; x{n} = -1:1:10;    y{n} = [0 0 1 -1 1 0 0 0 0 0 0 0];
xlbl{n} = 'n'; ylbl{n} = 'y[n]'; n = n + 1;



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})
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.flname       = 'my_image.png';
    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 
    
    % --------------------------------------------------------------------
    % 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 2.25 1.25], '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
    
    
    % --------------------------------------------------------------------
    % DISPLAT DATA -------------------------------------------------------
    % --------------------------------------------------------------------
    
    % PLOT DATA
    if isempty(opt.x)
        h = opt.fnc(opt.y,        opt.pltopt{:},'MarkerFaceColor','auto', 'MarkerSize', 3);
    else
        h = opt.fnc(opt.x, opt.y, opt.pltopt{:},'MarkerFaceColor','auto', 'MarkerSize', 3);
    end
    
    % OPTIONAL SETTING
    rangey = max(opt.y) - min(opt.y);
    if opt.ynum
        for ii = 1:length(opt.x), text(opt.x(ii), opt.y(ii)+rangey*0.15, num2str(opt.y(ii)), 'HorizontalAlign', 'Center'); end
    end
    
    % --------------------------------------------------------------------
    % SET COLORS AND AXES ------------------------------------------------
    % --------------------------------------------------------------------
    
    % DISPLAY SETTING
    set(gca, ...
      'Box'         , 'off'          , ...
      'TickDir'     , 'out'          , ...
      'TickLength'  , [.01 .01]      , ...
      'Color'       , [.95 .95 .95]  );
    
    % USE OAXES IF SELECTED AND POSSIBLE
    if opt.oaxes && exist('oaxes', 'file')
        set(gca,'Visible','off')
        oa = oaxes('origin', [0 0 0], 'xlabel', {'',opt.xlbl}, 'ylabel', {'',opt.ylbl}, ...
                   'ArrowAspectRatio', 1, 'Arrow', 'off', 'AxisLabelLocation', 'end', ...
                   'YLabelHorizontalAlignment', 'left', 'linewidth', 0.5);
    end
    axis([min(opt.x)-eps max(opt.x)+eps min(opt.y)-rangey*.1 max(opt.y)+rangey*0.1])
    uistack(h, 'top')
    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)
          % 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
