function playAnimation(varargin)
%playAnimation Play an animation on the screen.
%   playAnimation plays the animation in the current figure.
%
%   playAnimation(fig) plays the animation in figure FIG.
%
%   playAnimation(..., 'AnimationRange', [timeBegin timeEnd])
%   plays in the given time range.
%
%   playAnimation(..., 'FrameRate', n)
%   plays n frames per unit time.
%
%   playAnimation(..., 'Backwards', true)
%   plays the animation backwards.
%
%   playAnimation(..., 'SpeedFactor', x)
%   plays the animation at a speed of x units of time per second.
%
%   Example: 
%      syms t
%      fanimator(@plot, t, t^2, '*')
%      playAnimation
%
%   See also animationToFrame, fanimator, writeAnimation.

%   Copyright 2018 The MathWorks, Inc.

import matlab.internal.editor.*

p = inputParser;
% do not use gcf here because we do not want to open a figure if the user
% is working in a uifigure
addOptional(p, 'Figure', get(groot, 'CurrentFigure'), ...
    @(X) isa(X, '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);
addParameter(p, 'SpeedFactor', 1, @isreal);
parse(p, varargin{:});

fig = p.Results.Figure; 
F = findAnimators(fig);
if isempty(F)
    % no animated object
    return;
end

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

% create our own timer class within the figure
animTimer = matlab.graphics.function.AnimationTimer(fig, ...
    'TimeBegin', timeMin, 'TimeStep', 1/frameRate, ...
    'TimeEnd', timeMax, 'Backwards', p.Results.Backwards, ...
    'SpeedFactor', p.Results.SpeedFactor);
start(animTimer);   

% Inform the Live Editor that the current figure is being animated.
import matlab.internal.editor.figure.*
isLiveEditorFigure = AnimationUtils.isEmbeddedLiveEditorFigure(fig);
if isLiveEditorFigure
    AnimationUtils.startAnimation(fig);
    cleanupFcn = onCleanup(@() AnimationUtils.stopAnimation(fig));
end

waitfor(animTimer.Timer);
end