import { addTo } from './addTo';
import { getGroup } from './getGroup';
import { getTween } from './getTween';
import { pop3 } from './utils/pop3';
/**
 * This helpers makes it possible to change the world over time.
 * It's done by moving objects away from the center point of the scene to a point far away not visible.
 * @example
 * ```ts
  const act1 = getGroup();
  addTo(act1, getSpinning(getPrefab({ id: 'en_p_lantern_02', p: [0, 0, 5] })));

  const act2 = getGroup();
  addTo(act2, getPrefab({ id: 'bonfire_01', p: [0, 0, 5] }));

  const act3 = getGroup();
  addTo(act3, getScape());


  // Quic way
  addTo(root, getTimeline([act1, act2, act3], { duration: 15 }));

  // Aor Advance way

  addTo(
    root,
    getTimeline(
      [
        {
          act: act1,
          start: 0,
          end: 3,
        },
        {
          act: act2,
          start: 3,
          end: 4,
        },
        {
          act: act3,
          start: 2,
          end: 5,
        },
      ],
      { duration: 5 }
    )
  );
 * ```
 */
export const getTimeline = (acts, options = {}) => {
    options = {
        duration: undefined,
        ...options,
    };
    const wrapper = getGroup(options);
    if (acts.length === 0)
        return wrapper;
    let autoDuration = false;
    // See if start and end should be calculated automatic.
    if (!acts[0].end) {
        autoDuration = true;
        const actsTemp = [];
        const defaultActDuration = 4;
        if (!options.duration)
            options.duration = defaultActDuration * acts.length;
        let actDuration = options.duration / acts.length;
        for (let index = 0; index < acts.length; index++) {
            actsTemp.push({
                act: acts[index],
                start: actDuration * index,
                end: actDuration * (index + 1),
            });
        }
        acts = actsTemp;
    }
    let duration = 0;
    for (let index = 0; index < acts.length; index++) {
        const actData = acts[index];
        if (duration < actData.end) {
            duration = actData.end;
        }
    }
    // If duration is defined in options and it's longer than the calculated duration us duration from options.
    if (options.duration && options.duration > duration) {
        duration = options.duration;
    }
    const smallNumber = 0.0001;
    const phantomZoneOffset = 10000;
    for (let index = 0; index < acts.length; index++) {
        const actData = acts[index];
        const startTS = actData.start / duration;
        const endTS = actData.end / duration;
        const kf = [
            { ts: 0, p: pop3(phantomZoneOffset), easing: 'EASE_STEP_HOLD_NEXT' },
            { ts: startTS + smallNumber, p: pop3(phantomZoneOffset), easing: 'EASE_STEP_HOLD_NEXT' },
            { ts: startTS + smallNumber * 2, p: pop3(0), easing: 'EASE_STEP_HOLD_NEXT' },
            { ts: endTS - smallNumber * 2, p: pop3(0), easing: 'EASE_STEP_HOLD_NEXT' },
            { ts: endTS - smallNumber, p: pop3(phantomZoneOffset), easing: 'EASE_STEP_HOLD_NEXT' },
            { ts: 1, p: pop3(phantomZoneOffset), easing: 'EASE_STEP_HOLD_NEXT' },
        ];
        // Create a wrapper for objects to tween
        const tweenWrapper = getGroup({ p: [0, 0, 5] });
        addTo(wrapper, tweenWrapper);
        // Create object to tween and apply the tween
        addTo(tweenWrapper, getTween(actData.act, kf, { loopBehaviour: 'RESTART', duration }));
    }
    return wrapper;
};
//# sourceMappingURL=getTimeline.js.map