/*
 * Copyright 2014-2023 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.motion;

/**
 * Represents a motion.
 */
public class Motion {

	private final Function function;
	private final int startValue;
	private final int stopValue;
	private final long duration;

	/**
	 * Creates a motion.
	 *
	 * @param function
	 *            the function of the motion.
	 * @param startValue
	 *            the start value of the motion.
	 * @param stopValue
	 *            the stop value of the motion.
	 * @param duration
	 *            the duration of the motion.
	 */
	public Motion(Function function, int startValue, int stopValue, long duration) {
		this.function = function;
		this.startValue = startValue;
		this.stopValue = stopValue;
		this.duration = duration;
	}

	/**
	 * Gets the function of this motion.
	 *
	 * @return the function of this motion.
	 */
	public Function getFunction() {
		return this.function;
	}

	/**
	 * Gets the start value of this motion.
	 *
	 * @return the start value of this motion.
	 */
	public int getStartValue() {
		return this.startValue;
	}

	/**
	 * Gets the stop value of this motion.
	 *
	 * @return the stop value of this motion.
	 */
	public int getStopValue() {
		return this.stopValue;
	}

	/**
	 * Gets the duration of this motion.
	 *
	 * @return the duration of this motion.
	 */
	public long getDuration() {
		return this.duration;
	}

	/**
	 * Returns the value of this motion for a specific elapsed time.
	 *
	 * @param elapsedTime
	 *            the elapsed time.
	 * @return the value for the given elapsed time.
	 */
	public int getValue(long elapsedTime) {
		if (elapsedTime >= this.duration) {
			return this.stopValue;
		} else if (elapsedTime <= 0) {
			return this.startValue;
		} else {
			float t = (float) elapsedTime / this.duration;
			float functionValue = this.function.computeValue(t);
			return Math.round(this.startValue + (this.stopValue - this.startValue) * functionValue);
		}
	}
}
