function f1 = helperBLEPlotChannelHopSequence(algObj, chanHops, varargin)
%helperBLEPlotChannelHopSequence Plot the channel hopping sequence for a
%given algorithm
%   helperBLEPlotChannelHopSequence(ALGOBJ, CHANHOPS) generates a figure
%   containing a plot representing the hopping pattern of specified
%   algorithm and a histogram of the given channel hops.
%
%   ALGOBJ is a object of type <a
%   href="matlab:help('bleChannelSelection')">bleChannelSelection</a>.
%
%   CHANHOPS is a vector containing the hopsequence for specified
%   connection events in the algorithm object ALGOBJ.
%
%   helperBLEPlotChannelHopSequence(..., Name, Value) specifies additional
%   name-value pair arguments described below. When a name-value pair is
%   not specified, its default value is used.
%
%   'ShowHopping'       Flag to enable the visualization of channel hopping
%                       sequence given by CHANHOPS vector corresponding to
%                       the algorithm object ALGOBJ. Default value is
%                       'false'.
%
%   'PlotIndex'         Figure number to be used for the generated plot.
%                       Default value is [].

%   Copyright 2018 The MathWorks, Inc.

% Validate inputs
validateattributes(algObj, {'bleChannelSelection'}, {}, '', 'algObj');
validateattributes(chanHops, {'numeric'}, {'row', 'integer', ...
    'nonnegative', '<=', 36}, '', 'chanHops');

p = inputParser;
addParameter(p,'ShowHopping',false);
addParameter(p,'PlotIndex',[]);
parse(p, varargin{:});
useParams = p.Results;
showHopping = useParams.ShowHopping;
plotIndex = useParams.PlotIndex;
validateattributes(showHopping, {'logical', 'double'}, ...
    {'scalar', 'binary'}, '', 'showHopping');

% Initialize
numConnectionEvents = numel(chanHops);
numDataChannels = 37;
eventCounter = algObj.EventCounter - numConnectionEvents;

%% If visualizing is selected
if showHopping
    % Initialize the figure properties
    fig = figure();
    csaFigAxis = axes(fig);
    if algObj.Algorithm == 1
        fig.Position = [680 300 1100 300];
        fig.Name = 'Channel Selection Algorithm #1';
        title(csaFigAxis, 'Channel Selection Algorithm #1')
    else
        fig.Position = [680 700 1100 300];
        fig.Name = 'Channel Selection Algorithm #2';
        title(csaFigAxis, 'Channel Selection Algorithm #2')
    end
    fig.NumberTitle = 'off';
    fig.Tag = 'CSAVisualizationFigure';
    
    % Set the dimension and color properties for each channel(rectangle)
    % object
    chHeight = 1;
    chWidth = 1;
    curvature = [0.8 0.8];
    chIdleColor = [0.1 0.5 0.7 0.8];
    chEdgeColor = [0 0.2 0.4 1];
    chSelColor = [0.85 0.35 0.1 0.9];
    chTextColor = [1 1 1 1];
    
    % Set text properties for info to be displayed
    ChanInfo = text(csaFigAxis, 0.8, 0.8, '', 'FontSize', 10);
    
    rect(1:numDataChannels) = rectangle(csaFigAxis, 'Visible', 'off');
    txt(1:numDataChannels) = text(csaFigAxis);
    
    % Initialize all the channels (Each curved rectangle represents a channel)
    for i = 1:numDataChannels
        rect(i) = rectangle(csaFigAxis);
        rect(i).Tag = ['rectangle' num2str(i-1)];
        rect(i).Position = [i-1,-(chHeight/2),chWidth,chHeight];
        rect(i).Curvature = curvature;
        rect(i).FaceColor = chIdleColor;
        rect(i).EdgeColor = chEdgeColor;
        
        txt(i) = text(csaFigAxis, i-0.5, chHeight/8, ['CH-' num2str(i-1)]);
        txt(i).Tag = ['CH-' num2str(i-1)];
        txt(i).Color = chTextColor;
        txt(i).FontWeight = 'bold';
        txt(i).Rotation = 90;
        txt(i).HorizontalAlignment = 'Center';
    end
    axis off
    axis([0 numDataChannels 0 1])
    
    i = 1;
    adjustIdx = zeros(1, numConnectionEvents);
    
    while i ~= numConnectionEvents+1
        % Use this index for accessing arrays since matlab indexing starts
        % from 1 and channel indices start from 0
        adjustIdx(i) = chanHops(i) + 1;
        
        rect(adjustIdx(i)).FaceColor = chSelColor;
        rect(adjustIdx(i)).Position = [chanHops(i),-(chHeight/2),chWidth,chHeight+0.1];
        txt(adjustIdx(i)).Color = [1 1 1];
        
        % Update statistics
        info = {['Selected Channel: ' num2str(chanHops(i))], ...
            ['Event Counter: ' num2str(eventCounter+i)]};
        ChanInfo.String = info;
        ChanInfo.Tag = 'Selected channel and event counter text';
        
        pause(0.1)
        % Handle close properly if the figure is closed externally
        if ~ishghandle(fig)
            break
        end
        if i < numConnectionEvents
            % Change back to original channel
            rect(adjustIdx(i)).FaceColor = chIdleColor;
            rect(adjustIdx(i)).Position = [chanHops(i),-(chHeight/2),chWidth,chHeight];
            txt(adjustIdx(i)).Color = chTextColor;
        end
        i = i + 1;
    end
    if ishghandle(fig)
        close(fig)
    end
end

%% Plot the hopping pattern
f1 = figure;
f1.NumberTitle = 'off';
f1.Tag = 'CSAPlotsFigure';
resolution = get(0, 'screensize');
csaPlotFigAx = axes(f1, 'Visible', 'off');
for i=1:2
    csaPlotFigAx(i) = copyobj(csaPlotFigAx(1),f1);
end

if algObj.Algorithm == 1
    f1.Position = [450 200 resolution(3)*0.5 resolution(3)*0.4];
    f1.Name = ['Figure ' num2str(plotIndex) ': Channel Selection Algorithm #1'];
else
    f1.Position = [500 150 resolution(3)*0.5 resolution(3)*0.4];
    f1.Name = ['Figure ' num2str(plotIndex) ': Channel Selection Algorithm #2'];
end

% Create two sub-plots, one for plotting hop pattern and one for bar chart
% representing statistics on number of times a channel is selected
s1 = subplot(2, 1, 1, csaPlotFigAx(1));
s1.Tag = 'subPlot1';
s2 = subplot(2, 1, 2, csaPlotFigAx(2));
s2.Tag = 'subPlot2';

% Plot the hop pattern
plot(s1, (eventCounter+1:eventCounter+numConnectionEvents), chanHops, 'kx-');
title(s1, 'Channel hopping pattern');
xlim(s1, [eventCounter, eventCounter+numConnectionEvents])
xlabel(s1, 'Connection event counter');
ylabel(s1, 'BLE channel');

%% Plot a histogram of channel hops
% Plot the histogram in the sub-plot representing the number of times each
% channel is selected
h = histogram(s2, chanHops);
xlabel(s2, 'BLE channel');
ylabel(s2, 'Channel count');
title(s2, ['Histogram of channel selection for ' ...
    num2str(algObj.EventCounter - eventCounter) ' connection events']);
ylim(s2, [0 max(5, 1.1*max(h.Values))]);
