text: /**
   * @author       Richard Davey <rich@photonstorm.com>
   * @copyright    2020 Photon Storm Ltd.
   * @license      {@link https://opensource.org/licenses/MIT|MIT License}
   */
  
  var Clone = require('../../utils/object/Clone');
  var Defaults = require('../tween/Defaults');
  var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
  var GetBoolean = require('./GetBoolean');
  var GetEaseFunction = require('./GetEaseFunction');
  var GetNewValue = require('./GetNewValue');
  var GetTargets = require('./GetTargets');
  var GetTweens = require('./GetTweens');
  var GetValue = require('../../utils/object/GetValue');
  var Timeline = require('../Timeline');
  var TweenBuilder = require('./TweenBuilder');
  
  /**
   * Builds a Timeline of Tweens based on a configuration object.
   *
   * @function Phaser.Tweens.Builders.TimelineBuilder
   * @since 3.0.0
   *
   * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager to which the Timeline will belong.
   * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline.
   *
   * @return {Phaser.Tweens.Timeline} The created Timeline.
   */
  var TimelineBuilder = function (manager, config)
  {
      var timeline = new Timeline(manager);
  
      var tweens = GetTweens(config);
  
      if (tweens.length === 0)
      {
          timeline.paused = true;
  
          return timeline;
      }
  
      var defaults = Clone(Defaults);
  
      defaults.targets = GetTargets(config);
  
      //  totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration
  
      var totalDuration = GetAdvancedValue(config, 'totalDuration', 0);
  
      if (totalDuration > 0)
      {
          defaults.duration = Math.floor(totalDuration / tweens.length);
      }
      else
      {
          defaults.duration = GetNewValue(config, 'duration', defaults.duration);
      }
  
      defaults.delay = GetNewValue(config, 'delay', defaults.delay);
      defaults.easeParams = GetValue(config, 'easeParams', defaults.easeParams);
      defaults.ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), defaults.easeParams);
      defaults.hold = GetNewValue(config, 'hold', defaults.hold);
      defaults.repeat = GetNewValue(config, 'repeat', defaults.repeat);
      defaults.repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay);
      defaults.yoyo = GetBoolean(config, 'yoyo', defaults.yoyo);
      defaults.flipX = GetBoolean(config, 'flipX', defaults.flipX);
      defaults.flipY = GetBoolean(config, 'flipY', defaults.flipY);
  
      //  Create the Tweens
      for (var i = 0; i < tweens.length; i++)
      {
          timeline.queue(TweenBuilder(timeline, tweens[i], defaults));
      }
  
      timeline.completeDelay = GetAdvancedValue(config, 'completeDelay', 0);
      timeline.loop = Math.round(GetAdvancedValue(config, 'loop', 0));
      timeline.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0));
      timeline.paused = GetBoolean(config, 'paused', false);
      timeline.useFrames = GetBoolean(config, 'useFrames', false);
  
      //  Callbacks
  
      var scope = GetValue(config, 'callbackScope', timeline);
  
      var timelineArray = [ timeline ];
  
      var onStart = GetValue(config, 'onStart', false);
  
      //  The Start of the Timeline
      if (onStart)
      {
          var onStartScope = GetValue(config, 'onStartScope', scope);
          var onStartParams = GetValue(config, 'onStartParams', []);
  
          timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope);
      }
  
      var onUpdate = GetValue(config, 'onUpdate', false);
  
      //  Every time the Timeline updates (regardless which Tweens are running)
      if (onUpdate)
      {
          var onUpdateScope = GetValue(config, 'onUpdateScope', scope);
          var onUpdateParams = GetValue(config, 'onUpdateParams', []);
  
          timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope);
      }
  
      var onLoop = GetValue(config, 'onLoop', false);
  
      //  Called when the whole Timeline loops
      if (onLoop)
      {
          var onLoopScope = GetValue(config, 'onLoopScope', scope);
          var onLoopParams = GetValue(config, 'onLoopParams', []);
  
          timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope);
      }
  
      var onYoyo = GetValue(config, 'onYoyo', false);
  
      //  Called when a Timeline yoyos
      if (onYoyo)
      {
          var onYoyoScope = GetValue(config, 'onYoyoScope', scope);
          var onYoyoParams = GetValue(config, 'onYoyoParams', []);
  
          timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope);
      }
  
      var onComplete = GetValue(config, 'onComplete', false);
  
      //  Called when the Timeline completes, after the completeDelay, etc.
      if (onComplete)
      {
          var onCompleteScope = GetValue(config, 'onCompleteScope', scope);
          var onCompleteParams = GetValue(config, 'onCompleteParams', []);
  
          timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope);
      }
  
      return timeline;
  };
  
  module.exports = TimelineBuilder;
  