function edcaPlotLatencies(modelName)
%edcaPlotLatencies Plots the MAC frame latencies in all access category 
%
%   This is an example helper function.
%
%   edcaPlotLatencies(MODELNAME) plot the MAC frame latencies in each
%   access category for the selected node in the Simulink model with given
%   MODELNAME.

%   Copyright 2019 The MathWorks, Inc.

if ~exist('macLatenciesLog.mat', 'file')
    error(['macLatenciesLog.mat is not found in MATLAB path. Run the model ''' modelName ''' to create a new macLatenciesLog.mat']);
end

% Load the Simulink model
load_system(modelName);

% Load latencies information from MAT file
latenciesInfo = load('macLatenciesLog.mat');
latenciesTable = latenciesInfo.latenciesTable;

% Get screen resolution
resolution = get(0, 'screensize');
screenWidth = resolution(3);
screenHeight = resolution(4);
figureWidth = screenWidth*0.7;
figureHeight = screenHeight*0.7;
% Create figure
latenciesFig = figure('Name', 'MAC QoS Traffic Latencies', 'Tag', 'QoSLatencies', ...
    'Position', [screenWidth*0.1, screenHeight*0.05, figureWidth, figureHeight], ...
    'Resize', 'off');
hold on;
p = uipanel(latenciesFig,'Position', [0.14 0.925 0.2 0.04], 'BorderType', 'none');
% Create textbox
annotation(p,'textbox', [0 0.93 0.077 0.03], 'String','Node Selector:',...
    'LineStyle','none', 'FitBoxToText','off');

% Get node names
nodeNames = dcfGetNodeNamesList(modelName);
for i = 1:numel(nodeNames)
    nodeNames{i} = strrep(nodeNames{i}, [modelName '/'], '');
end

% Create drop down for node selection
nodeSelector = uicontrol(p, 'Style', 'popupmenu', 'String', nodeNames, ...
    'Position', [100 3 155 27], ...
    'Callback', @plotLatencies);
    prevNode = -1;

% Create plots for each access category
bkPlot = plot(0, 0, 'Marker', '*', 'LineStyle', '-', 'LineWidth', 1);
bePlot = plot(0, 0, 'Marker', 'o', 'LineStyle', '-', 'LineWidth', 1);
viPlot = plot(0, 0, 'Marker', 'diamond', 'LineStyle', '-', 'LineWidth', 1);
voPlot = plot(0, 0, 'Marker', 'square', 'LineStyle', '-', 'LineWidth', 1);

% Add legend
legend('Background Traffic', 'Best Effort Traffic', 'Video Traffic', 'Voice Traffic', 'Location', 'northeastoutside');
% Add X and Y labels
xlabel('Node Timeline (Microseconds)', 'FontSize', 12);
ylabel('MAC Latency (Milliseconds)', 'FontSize', 12);

% Plot selected node queue lengths
plotLatencies([], []);
    function plotLatencies(~, ~)
        % New a node is selected
        if (nodeSelector.Value ~= prevNode)
            % Get latencies information of each access category for the
            % selected node
            prevNode = nodeSelector.Value;
            ac0Latencies = diff(latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 0) , [1 4]}, 1, 2)/1e3;
            ac1Latencies = diff(latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 1) , [1 4]}, 1, 2)/1e3;
            ac2Latencies = diff(latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 2) , [1 4]}, 1, 2)/1e3;
            ac3Latencies = diff(latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 3) , [1 4]}, 1, 2)/1e3;
            
            % Get the frame discard timestamp for each frame corresponding
            % to the latencies above
            ac0Times = latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 0) , 4};
            ac1Times = latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 1) , 4};
            ac2Times = latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 2) , 4};
            ac3Times = latenciesTable{(latenciesTable.NodeID == nodeSelector.Value) & (latenciesTable.AC == 3) , 4};
            
            % Update each AC plot with latencies
            bePlot.XData = ac0Times;
            bePlot.YData = ac0Latencies;
            bkPlot.XData = ac1Times;
            bkPlot.YData = ac1Latencies;
            viPlot.XData = ac2Times;
            viPlot.YData = ac2Latencies;
            voPlot.XData = ac3Times;
            voPlot.YData = ac3Latencies;
        end
    end
end