function Stop = plotElapsedTime(bo, State)
%plotElapsedTime     PlotFcn for plotting total elapsed time
%versus the number of function evaluations.
%   Stop = plotElapsedTime(bo, State) plots total elapsed time
%   versus the number of function evaluations.
%
% See also: BAYESOPT, BAYESIANOPTIMIZATION
%

%   Copyright 2016-2022 The MathWorks, Inc.

persistent Axes Curves;
narginchk(2,2);
Title = bayesoptim.infoString('ElapsedTimeTitle');
XLabel = bayesoptim.infoString('FEvals');
YLabel = bayesoptim.infoString('TotElapsed');
Stop = false;
set(0, 'defaultfigureunits', 'pixels');     % Make sure units are pixels
switch State
    case 'initial'
        f = figure('Tag','bayesopt.ElapsedTime');
        Axes = axes(f);
        title(Axes, Title);
        xlabel(Axes, XLabel);
        ylabel(Axes, YLabel);
        Curves = {};
    case {'iteration', 'done'}
        cellfun(@delete, Curves);
        if isvalid(Axes)
            obj = cumsum(bo.ObjectiveEvaluationTimeTrace, 'omitnan');
            tot = bo.TotalElapsedTimeTrace;
            Curves{end+1} = plotCurve(tot, Axes, 'b');
            Curves{end+1} = plotCurve(obj, Axes, 'g');
            if bo.PrivOptions.UseParallel
                % Do not include modeling time, and relabel
                % legend
                legend(Axes, {bayesoptim.infoString('RealTime'),...
                    bayesoptim.infoString('FEvalTimeParallel')},...
                    'Location', 'best');
            else
                % Include modeling time
                Curves{end+1} = plotCurve(tot-obj, Axes, 'r');
                legend(Axes, {bayesoptim.infoString('TotTime'),...
                    bayesoptim.infoString('FEvalTime'),...
                    bayesoptim.infoString('ModelingTime')},...
                    'Location', 'best');
            end
        end
    case 'standalone'
        obj = cumsum(bo.ObjectiveEvaluationTimeTrace, 'omitnan');
        tot = bo.TotalElapsedTimeTrace;
        f = figure('Tag','bayesopt.ElapsedTime');
        StandaloneAxes = axes(f);
        title(StandaloneAxes, Title);
        xlabel(StandaloneAxes, XLabel);
        ylabel(StandaloneAxes, YLabel);
        plotCurve(tot, StandaloneAxes, 'b');
        plotCurve(obj, StandaloneAxes, 'g');
        if bo.PrivOptions.UseParallel
            legend(StandaloneAxes, {bayesoptim.infoString('RealTime'),...
                bayesoptim.infoString('FEvalTimeParallel')}, ...
                'Location', 'best');
        else
            plotCurve(tot-obj, StandaloneAxes, 'r');
            legend(StandaloneAxes, {bayesoptim.infoString('TotTime'),...
                bayesoptim.infoString('FEvalTime'),...
                bayesoptim.infoString('ModelingTime')}, ...
                'Location', 'best');
        end
end

    function Curve = plotCurve(Trace, Axes, color)
        HoldOff = bayesoptim.holdOn(Axes);
        Curve = plot(Axes, 1:numel(Trace), Trace, ['-' color 'o'], 'MarkerSize', 2);
    end
end

