/**
 * package for the animation classes
 */
package simogl.model.animation;

import java.util.ArrayList;
import javax.media.opengl.GL;

import simogl.geometry.AbstractMesh;
import simogl.material.Material;

/**
 * This class represents an animation of a md2 model
 * @author Frank Bruns
 *
 */
public class Animation
{
	private long totalDuration = 0;
	private long currentAnimTime = 0;
	private int currentFrameIndex = 0;
	private ArrayList<AnimationFrame> animFrames = null;
	private static Material material = new Material(1f,1f,1f,0.5f);
	
	/**
	 * Creates a new Animation object
	 * 
	 */
	public Animation()
	{
		this.animFrames = new ArrayList<AnimationFrame>();
	}
	
	/**
	 * Adds a frame to the animation
	 * @param frame frame to add to the animation
	 * @param duration time in miliseconds this frame shall show up
	 */
	public void addAnimFrame(AbstractMesh frame, long duration)
	{
		this.totalDuration += duration;
		AnimationFrame f = new AnimationFrame(frame,this.totalDuration);
		f.getMesh().setMaterial(material);		
		this.animFrames.add(f);		
	}
	
	/**
	 * Returns the animation frame with the specified index in the animation
	 * @param index index of the animation's frame
	 * @return frame with the specified index in the animation
	 */
	public AnimationFrame getAnimFrame(int index)
	{
		return this.animFrames.get(index);
	}
	
	/**
	 * Returns the current frame of the animation
	 * @return current frame of the animation
	 */
	public AnimationFrame getCurrentFrame()
	{
		return this.getAnimFrame(this.currentFrameIndex);
	}
	
	/**
	 * Returns the ArrayList of animation frames that form the animation
	 * @return arraylist of animation frames
	 */
	public ArrayList<AnimationFrame> getAnimFrames()
	{
		return this.animFrames;
	}
	
	/**
	 * Runs the current animation
	 * @param gl
	 */
	public void play(GL gl)
	{
		if(this.animFrames.size() > 0)
		{
			this.animFrames.get(this.currentFrameIndex).getMesh().draw(gl);			
		}
	}
	
	/**
	 * Updates the animation
	 * @param elapsedTime time between two frames
	 */
	public synchronized void update(long elapsedTime)
	{
		if(this.animFrames.size() > 0)
		{
			this.currentAnimTime += elapsedTime;
			
			if(this.currentAnimTime >= this.totalDuration)
			{
				this.currentAnimTime = this.currentAnimTime % this.totalDuration;
				this.currentFrameIndex = 0;
			}
			
			if(this.currentAnimTime > this.animFrames.get(this.currentFrameIndex).getEndTime())				
			{
				this.currentFrameIndex++;
			}			
		}
	}

}
