/**
 * package for classes that represent md2 models
 */
package simogl.model;

import java.io.File;
import simogl.model.animation.Animation;
import simogl.model.animation.AnimationFrame;

import com.sun.opengl.util.texture.Texture;


/**
 * This class represents a model that has been loaded from a md2 file.
 * Such models are usually used as characters in the game. Notice, that
 * this is an abstract class. You cannot intanciate an object of this
 * class directly.
 * @author Frank Bruns
 *
 */
public abstract class AbstractMD2Model
{	
	private float x = 0;
	private float y = 0;
	private float z = 0;	
	
	public static final int WALK = 0;
	public static final int STAND = 1;
	protected int currAnimState = STAND;
	
	protected Animation animWalk = null;
	protected Animation animStand = null;
	
	protected Texture texture = null;
	protected String texPath = "";
	protected File modFile = null;
	protected float scaleFactor = 1f;
	
	
	/**
	 * Creates a new md2 model at the specified location
	 * @param x x-coordinate
	 * @param y y-coordinate
	 * @param z z-coordinate
	 */
	public AbstractMD2Model(float x, float y, float z)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	/**
	 * Sets the positon of the model
	 * @param x x-coordinate
	 * @param y y-coordinate
	 * @param z z-coordinate
	 */
	protected synchronized void setPosition(float x, float y, float z)
	{		
		for(AnimationFrame frame : this.animStand.getAnimFrames())
		{
			frame.getMesh().setPosition(x, y, z);
		}
		
		for(AnimationFrame frame : this.animWalk.getAnimFrames())
		{
			frame.getMesh().setPosition(x, y, z);
		}
	}
	
	/**
	 * Sets the current animation of the model. Use it e.g. in the
	 * following way.
	 * <br>
	 * <br>
	 * <code>
	 * 	goblinModelObject.setAnimation(MD2Goblin.WALK)
	 * </code>
	 * @param state a constant that defines an animation state
	 */
	public void setAnimationState(int state)
	{
		this.currAnimState = state;
	}
	
	/**
	 * Returns the animation that is currently assigned to the model.
	 * @return the current animation of the model
	 */
	public synchronized Animation getCurrentAnim()
	{
		Animation anim = new Animation();
		
		switch(this.currAnimState)
		{
			case STAND : anim = this.animStand; break;
			case WALK : anim = this.animWalk; break;
		}
		
		return anim;
	}
	
	/**
	 * Returns the int that symbolizes the current animation state like
	 * "WALK" or "STAND".
	 * @return current animation state
	 */
	public int getCurrentAnimState()
	{
		int state = 0;
		
		switch(this.currAnimState)
		{
			case STAND : state = STAND; break;
			case WALK : state = WALK; break;
		}
		
		return state;
	}
	
	/** 
	 * This method can be used to create the "walk" animation
	 *
	 */
	protected abstract void createAnimStand();
	
	/**
	 * This method can be used to create the "walk" animation
	 *
	 */
	protected abstract void createAnimWalk();
	
	/**
	 * Updates a md2 model
	 * @param elapsedTime time between two frames
	 */
	public synchronized void update(long elapsedTime)
	{
		this.getCurrentAnim().update(elapsedTime);
	}
}
