function frames = animationToFrame(varargin)
%animationToFrame Convert animation to array of frames.
%   F = animationToFrame
%   returns an array of frames generated by the animation in the current
%   figure.
% 
%   F = animationToFrame(fig)
%   does the same for the figure fig.
%
%   F = animationToFrame(..., 'AnimationRange', [timeBegin, timeEnd})
%   uses the given time range.
%
%   F = animationToFrame(..., 'FrameRate', n)
%   creates n frames per second. 
%
%   F = animationToFrame(..., 'Backwards', true)
%   reverses the order of frames.
%
%   Example: 
%      syms t
%      fanimator(@plot, t, t^2, '*')
%      F = animationToFrame
%
%   See also fanimator, playAnimation, writeAnimation.

%   Copyright 2018 The MathWorks, Inc.

p = inputParser;
addOptional(p, 'Figure', get(groot, 'CurrentFigure'), @(fig) isa(fig, 'matlab.ui.Figure'));
addParameter(p, 'AnimationRange', [NaN, NaN], @matlab.graphics.function.internal.checkRangeVector);
addParameter(p, 'FrameRate', NaN, @(X) isreal(X) && X>0);
addParameter(p, 'Backwards', false, @islogical);

parse(p, varargin{:});
fig = p.Results.Figure;

F = findAnimators(fig); 
frames = [];
if isempty(F)
    % no animated object
    return;
end

[timeMin, timeMax, frameRate] = commonRange(F, p.Results.AnimationRange, p.Results.FrameRate);
timeStep = 1/frameRate;

% This forces a morph on the figure.
matlab.ui.internal.prepareFigureFor(fig, mfilename('fullpath'));

% save the old position of the clock, and restore it later
animTimer = matlab.graphics.function.AnimationTimer(fig, ...
    'TimeBegin', timeMin, 'TimeStep', timeStep, ...
    'TimeEnd', timeMax, 'Backwards', p.Results.Backwards);
oldTime = animTimer.CurrentTime;
cleanupObj = onCleanup(@() set(animTimer, 'CurrentTime', oldTime));

if p.Results.Backwards
    tvec = timeMax: -timeStep: timeMin;
else    
    tvec = timeMin: timeStep : timeMax;
end

for t = tvec
    setTime(animTimer, t);
    frames = [frames getframe(fig)]; %#ok
end

end