package aurelienribon.tweenengine;

/**
 * BaseTween is the base class of Tween and Timeline. It defines the
 * iteration engine used to play animations for any number of times, and in
 * any direction, at any speed.
 * <p/>
 *
 * It is responsible for calling the different callbacks at the right moments,
 * and for making sure that every callbacks are triggered, even if the update
 * engine gets a big delta time at once.
 *
 * @see Tween
 * @see Timeline
 * @author Aurelien Ribon | http://www.aurelienribon.com/
 */
public abstract class BaseTween<T> {
	// General
	private int step;
	private int repeatCnt;
	private boolean isIterationStep;
	private boolean isYoyo;

	// Timings
	protected float delay;
	protected float duration;
	private float repeatDelay;
	private float currentTime;
	private float deltaTime;
	private boolean isStarted; // true when the object is started
	private boolean isInitialized; // true after the delay
	private boolean isFinished; // true when all repetitions are done
	private boolean isKilled; // true if kill() was called
	private boolean isPaused; // true if pause() was called

	// Misc
	private TweenCallback callback;
	private int callbackTriggers;
	private Object userData;

	// Package access
	boolean isAutoRemoveEnabled;
	boolean isAutoStartEnabled;

	// -------------------------------------------------------------------------

	protected void reset() {
		step = -2;
		repeatCnt = 0;
		isIterationStep = isYoyo = false;

		delay = duration = repeatDelay = currentTime = deltaTime = 0;
		isStarted = isInitialized = isFinished = isKilled = isPaused = false;

		callback = null;
		callbackTriggers = TweenCallback.COMPLETE;
		userData = null;

		isAutoRemoveEnabled = isAutoStartEnabled = true;
	}

	// -------------------------------------------------------------------------
	// Public API
	// -------------------------------------------------------------------------

	/**
	 * Builds and validates the object. Only needed if you want to finalize a
	 * tween or timeline without starting it, since a call to ".start()" also
	 * calls this method.
	 *
	 * @return The current object, for chaining instructions.
	 */
	public T build() {
		return (T) this;
	}

	/**
	 * Starts or restarts the object unmanaged. You will need to take care of
	 * its life-cycle. If you want the tween to be managed for you, use a
	 * {@link TweenManager}.
	 *
	 * @return The current object, for chaining instructions.
	 */
	public T start() {
		build();
		currentTime = 0;
		isStarted = true;
		return (T) this;
	}

	/**
	 * Convenience method to add an object to a manager. Its life-cycle will be
	 * handled for you. Relax and enjoy the animation.
	 *
	 * @return The current object, for chaining instructions.
	 */
	public T start(TweenManager manager) {
		manager.add(this);
		return (T) this;
	}

	/**
	 * Adds a delay to the tween or timeline.
	 *
	 * @param delay A duration.
	 * @return The current object, for chaining instructions.
	 */
	public T delay(float delay) {
		this.delay += delay;
		return (T) this;
	}

	/**
	 * Kills the tween or timeline. If you are using a TweenManager, this object
	 * will be removed automatically.
	 */
	public void kill() {
		isKilled = true;
	}

	/**
	 * Stops and resets the tween or timeline, and sends it to its pool, for
+	 * later reuse. Note that if you use a {@link TweenManager}, this method
+	 * is automatically called once the animation is finished.
	 */
	public void free() {
	}

	/**
	 * Pauses the tween or timeline. Further update calls won't have any effect.
	 */
	public void pause() {
		isPaused = true;
	}

	/**
	 * Resumes the tween or timeline. Has no effect is it was no already paused.
	 */
	public void resume() {
		isPaused = false;
	}

	/**
	 * Repeats the tween or timeline for a given number of times.
	 * @param count The number of repetitions. For infinite repetition,
	 * use Tween.INFINITY, or a negative number.
	 *
	 * @param delay A delay between each iteration.
	 * @return The current tween or timeline, for chaining instructions.
	 */
	public T repeat(int count, float delay) {
		if (isStarted) throw new RuntimeException("You can't change the repetitions of a tween or timeline once it is started");
		repeatCnt = count;
		repeatDelay = delay >= 0 ? delay : 0;
		isYoyo = false;
		return (T) this;
	}

	/**
	 * Repeats the tween or timeline for a given number of times.
	 * Every two iterations, it will be played backwards.
	 *
	 * @param count The number of repetitions. For infinite repetition,
	 * use Tween.INFINITY, or '-1'.
	 * @param delay A delay before each repetition.
	 * @return The current tween or timeline, for chaining instructions.
	 */
	public T repeatYoyo(int count, float delay) {
		if (isStarted) throw new RuntimeException("You can't change the repetitions of a tween or timeline once it is started");
		repeatCnt = count;
		repeatDelay = delay >= 0 ? delay : 0;
		isYoyo = true;
		return (T) this;
	}

	/**
	 * Sets the callback. By default, it will be fired at the completion of the
	 * tween or timeline (event COMPLETE). If you want to change this behavior
	 * and add more triggers, use the {@link setCallbackTriggers()} method.
	 *
	 * @see TweenCallback
	 */
	public T setCallback(TweenCallback callback) {
		this.callback = callback;
		return (T) this;
	}

	/**
	 * Changes the triggers of the callback. The available triggers, listed as
	 * members of the {@link TweenCallback} interface, are:
	 * <p/>
	 *
	 * <b>BEGIN</b>: right after the delay (if any)<br/>
	 * <b>START</b>: at each iteration beginning<br/>
	 * <b>END</b>: at each iteration ending, before the repeat delay<br/>
	 * <b>COMPLETE</b>: at last END event<br/>
	 * <b>BACK_BEGIN</b>: at the beginning of the first backward iteration<br/>
	 * <b>BACK_START</b>: at each backward iteration beginning, after the repeat delay<br/>
	 * <b>BACK_END</b>: at each backward iteration ending<br/>
	 * <b>BACK_COMPLETE</b>: at last BACK_END event
	 * <p/>
	 *
	 * <pre> {@code
	 * forward :      BEGIN                                   COMPLETE
	 * forward :      START    END      START    END      START    END
	 * |--------------[XXXXXXXXXX]------[XXXXXXXXXX]------[XXXXXXXXXX]
	 * backward:      bEND  bSTART      bEND  bSTART      bEND  bSTART
	 * backward:      bCOMPLETE                                 bBEGIN
	 * }</pre>
	 *
	 * @param flags one or more triggers, separated by the '|' operator.
	 * @see TweenCallback
	 */
	public T setCallbackTriggers(int flags) {
		this.callbackTriggers = flags;
		return (T) this;
	}

	/**
	 * Attaches an object to this tween or timeline. It can be useful in order
	 * to retrieve some data from a TweenCallback.
	 *
	 * @param data Any kind of object.
	 * @return The current tween or timeline, for chaining instructions.
	 */
	public T setUserData(Object data) {
		userData = data;
		return (T) this;
	}

	// -------------------------------------------------------------------------
	// Getters
	// -------------------------------------------------------------------------

	/**
	 * Gets the delay of the tween or timeline. Nothing will happen before
	 * this delay.
	 */
	public float getDelay() {
		return delay;
	}

	/**
	 * Gets the duration of a single iteration.
	 */
	public float getDuration() {
		return duration;
	}

	/**
	 * Gets the number of iterations that will be played.
	 */
	public int getRepeatCount() {
		return repeatCnt;
	}

	/**
	 * Gets the delay occuring between two iterations.
	 */
	public float getRepeatDelay() {
		return repeatDelay;
	}

	/**
	 * Returns the complete duration, including initial delay and repetitions.
	 * The formula is as follows:
	 * <pre>
	 * fullDuration = delay + duration + (repeatDelay + duration) * repeatCnt
	 * </pre>
	 */
	public float getFullDuration() {
		if (repeatCnt < 0) return -1;
		return delay + duration + (repeatDelay + duration) * repeatCnt;
	}

	/**
	 * Gets the attached data, or null if none.
	 */
	public Object getUserData() {
		return userData;
	}

	/**
	 * Gets the id of the current step. Values are as follows:<br/>
	 * <ul>
	 * <li>even numbers mean that an iteration is playing,<br/>
	 * <li>odd numbers mean that we are between two iterations,<br/>
	 * <li>-2 means that the initial delay has not ended,<br/>
	 * <li>-1 means that we are before the first iteration,<br/>
	 * <li>repeatCount*2 + 1 means that we are after the last iteration
	 */
	public int getStep() {
		return step;
	}

	/**
	 * Gets the local time.
	 */
	public float getCurrentTime() {
		return currentTime;
	}

	/**
	 * Returns true if the tween or timeline has been started.
	 */
	public boolean isStarted() {
		return isStarted;
	}

	/**
	 * Returns true if the tween or timeline has been initialized. Starting
	 * values for tweens are stored at initialization time. This initialization
	 * takes place right after the initial delay, if any.
	 */
	public boolean isInitialized() {
		return isInitialized;
	}

	/**
	 * Returns true if the tween is finished (i.e. if the tween has reached
	 * its end or has been killed). If you don't use a TweenManager, you may
	 * want to call {@link free()} to reuse the object later.
	 */
	public boolean isFinished() {
		return isFinished || isKilled;
	}

	/**
	 * Returns true if the iterations are played as yoyo. Yoyo means that
	 * every two iterations, the animation will be played backwards.
	 */
	public boolean isYoyo() {
		return isYoyo;
	}

	/**
	 * Returns true if the tween or timeline is currently paused.
	 */
	public boolean isPaused() {
		return isPaused;
	}

	// -------------------------------------------------------------------------
	// Abstract API
	// -------------------------------------------------------------------------

	protected abstract void forceStartValues();
	protected abstract void forceEndValues();

	protected abstract boolean containsTarget(Object target);
	protected abstract boolean containsTarget(Object target, int tweenType);

	// -------------------------------------------------------------------------
	// Protected API
	// -------------------------------------------------------------------------

	protected void initializeOverride() {
	}

	protected void updateOverride(int step, int lastStep, boolean isIterationStep, float delta) {
	}

	protected void forceToStart() {
		currentTime = -delay;
		step = -1;
		isIterationStep = false;
		if (isReverse(0)) forceEndValues();
		else forceStartValues();
	}

	protected void forceToEnd(float time) {
		currentTime = time - getFullDuration();
		step = repeatCnt*2 + 1;
		isIterationStep = false;
		if (isReverse(repeatCnt*2)) forceStartValues();
		else forceEndValues();
	}

	protected void callCallback(int type) {
		if (callback != null && (callbackTriggers & type) > 0) callback.onEvent(type, this);
	}

	protected boolean isReverse(int step) {
		return isYoyo && Math.abs(step%4) == 2;
	}

	protected boolean isValid(int step) {
		return (step >= 0 && step <= repeatCnt*2) || repeatCnt < 0;
	}

	protected void killTarget(Object target) {
		if (containsTarget(target)) kill();
	}

	protected void killTarget(Object target, int tweenType) {
		if (containsTarget(target, tweenType)) kill();
	}

	// -------------------------------------------------------------------------
	// Update engine
	// -------------------------------------------------------------------------

	/**
	 * Updates the tween or timeline state. <b>You may want to use a
	 * TweenManager to update objects for you.</b>
	 *
	 * Slow motion, fast motion and backward play can be easily achieved by
	 * tweaking this delta time. Multiply it by -1 to play the animation
	 * backward, or by 0.5 to play it twice slower than its normal speed.
	 *
	 * @param delta A delta time between now and the last call.
	 */
	public void update(float delta) {
		if (!isStarted || isPaused || isKilled) return;

		deltaTime = delta;

		if (!isInitialized) {
			initialize();
		}

		if (isInitialized) {
			testRelaunch();
			updateStep();
			testCompletion();
		}

		currentTime += deltaTime;
		deltaTime = 0;
	}

	private void initialize() {
		if (currentTime+deltaTime >= delay) {
			initializeOverride();
			isInitialized = true;
			isIterationStep = true;
			step = 0;
			deltaTime -= delay-currentTime;
			currentTime = 0;
			callCallback(TweenCallback.BEGIN);
			callCallback(TweenCallback.START);
		}
	}

	private void testRelaunch() {
		if (!isIterationStep && repeatCnt >= 0 && step < 0 && currentTime+deltaTime >= 0) {
			assert step == -1;
			isIterationStep = true;
			step = 0;
			float delta = 0-currentTime;
			deltaTime -= delta;
			currentTime = 0;
			callCallback(TweenCallback.BEGIN);
			callCallback(TweenCallback.START);
			updateOverride(step, step-1, isIterationStep, delta);

		} else if (!isIterationStep && repeatCnt >= 0 && step > repeatCnt*2 && currentTime+deltaTime < 0) {
			assert step == repeatCnt*2 + 1;
			isIterationStep = true;
			step = repeatCnt*2;
			float delta = 0-currentTime;
			deltaTime -= delta;
			currentTime = duration;
			callCallback(TweenCallback.BACK_BEGIN);
			callCallback(TweenCallback.BACK_START);
			updateOverride(step, step+1, isIterationStep, delta);
		}
	}

	private void updateStep() {
		while (isValid(step)) {
			if (!isIterationStep && currentTime+deltaTime <= 0) {
				isIterationStep = true;
				step -= 1;

				float delta = 0-currentTime;
				deltaTime -= delta;
				currentTime = duration;

				if (isReverse(step)) forceStartValues(); else forceEndValues();
				callCallback(TweenCallback.BACK_START);
				updateOverride(step, step+1, isIterationStep, delta);

			} else if (!isIterationStep && currentTime+deltaTime >= repeatDelay) {
				isIterationStep = true;
				step += 1;

				float delta = repeatDelay-currentTime;
				deltaTime -= delta;
				currentTime = 0;

				if (isReverse(step)) forceEndValues(); else forceStartValues();
				callCallback(TweenCallback.START);
				updateOverride(step, step-1, isIterationStep, delta);

			} else if (isIterationStep && currentTime+deltaTime < 0) {
				isIterationStep = false;
				step -= 1;

				float delta = 0-currentTime;
				deltaTime -= delta;
				currentTime = 0;

				updateOverride(step, step+1, isIterationStep, delta);
				callCallback(TweenCallback.BACK_END);

				if (step < 0 && repeatCnt >= 0) callCallback(TweenCallback.BACK_COMPLETE);
				else currentTime = repeatDelay;

			} else if (isIterationStep && currentTime+deltaTime > duration) {
				isIterationStep = false;
				step += 1;

				float delta = duration-currentTime;
				deltaTime -= delta;
				currentTime = duration;

				updateOverride(step, step-1, isIterationStep, delta);
				callCallback(TweenCallback.END);

				if (step > repeatCnt*2 && repeatCnt >= 0) callCallback(TweenCallback.COMPLETE);
				currentTime = 0;

			} else if (isIterationStep) {
				float delta = deltaTime;
				deltaTime -= delta;
				currentTime += delta;
				updateOverride(step, step, isIterationStep, delta);
				break;

			} else {
				float delta = deltaTime;
				deltaTime -= delta;
				currentTime += delta;
				break;
			}
		}
	}

	private void testCompletion() {
		isFinished = repeatCnt >= 0 && (step > repeatCnt*2 || step < 0);
	}
}
