package ei.engine.scene;

import java.awt.Rectangle;
import java.util.HashMap;

import org.lwjgl.opengl.GL11;

import ei.engine.texture.Texture;
import ei.engine.texture.TextureLoader;

/**
 * Implementation of sprite that uses an OpenGL quad and a texture
 * to render a given image to the screen.
 * 
 * @author Kevin Glass
 * @author Brian Matzon
 * @author Ziver Koc
 */
public class AnimatedSprite extends Entity {
	/** The texture that stores the image for this sprite */
	private HashMap<String,Texture[]> textures;
	private String currentAnimation;
	private int textureId;

	/**
	 * Create a new empty AnimatedSprite
	 * 
	 * @param window The window in which the sprite will be displayed
	 * @param ref A reference to the image on which this sprite should be based
	 */
	public AnimatedSprite(String name) {
		super(name);		
		textures = new HashMap<String,Texture[]>();
		currentAnimation = null;
		textureId = -1;
	}

	/**
	 * Adds a vector of textures to the AnimationSprite
	 * 
	 * @param name The name of the animation
	 * @param t The vector of textures
	 * @return true if successful else false
	 */
	public boolean addAnimation(String name, Texture[] t){
		if(!textures.containsKey(name)){
			textures.put(name,t);
			return true;
		}
		return false;
	}

	/**
	 * Adds a vector of textures to the AnimationSprite
	 * 
	 * @param name The name of the animation
	 * @param t The path to the textures
	 * @return true if successful else false
	 */
	public boolean addAnimation(String name, String[] s){
		Texture[] t = new Texture[s.length];
		
		for(int i=0; i<s.length ;i++){
			t[i] = TextureLoader.getTextureLoaderInstance().getTexture(s[i]);
		}
		
		return addAnimation(name,t);
	}
	
	/**
	 * Play an animation
	 * 
	 * @param name The name of the animation
	 * @return true if the animation exists else false
	 */
	public boolean playAnimation(String name){
		if(textures.containsKey(name)){
			currentAnimation = name;
			textureId = 0;
			return true;
		}
		return false;
	}

	/**
	 * Get the width of the current animation of this sprite in pixels
	 * 
	 * @return The width of this sprite in pixels
	 */
	public int getWidth() {
		if(textures.get(currentAnimation)[textureId] == null){
			return 0;
		}
		return textures.get(currentAnimation)[textureId].getImageWidth();
	}

	/**
	 * Get the height of the current animation of this sprite in pixels
	 * 
	 * @return The height of this sprite in pixels
	 */
	public int getHeight() {
		if(textures.get(currentAnimation)[textureId] == null){
			return 0;
		}
		return textures.get(currentAnimation)[textureId].getImageHeight();
	}

	/**
	 * Draw the sprite
	 */
	public void render() {
		if(currentAnimation != null){
			// store the current model matrix
			GL11.glPushMatrix();

			//Sets the location
			super.setTranslationGL();
			//the rotation
			super.setRotationGL(
					textures.get(currentAnimation)[textureId].getImageWidth()/2,
					textures.get(currentAnimation)[textureId].getImageHeight()/2);
			//Sets the scale of the sprite
			super.setScaleGL();

			// bind to the appropriate texture for this sprite
			textures.get(currentAnimation)[textureId].bindGL();
			GL11.glColor3f(1,1,1);

			// draw a quad textured to match the sprite
			GL11.glBegin(GL11.GL_QUADS);
			{
				//Vertex at the upper left
				GL11.glTexCoord2f(0, 0);
				GL11.glVertex2f(0, 0);
				//Vertex at the down left
				GL11.glTexCoord2f(0, textures.get(currentAnimation)[textureId].getHeight());
				GL11.glVertex2f(0, textures.get(currentAnimation)[textureId].getImageHeight());
				//Vertex at the upper right
				GL11.glTexCoord2f(
						textures.get(currentAnimation)[textureId].getWidth(), 
						textures.get(currentAnimation)[textureId].getHeight());
				GL11.glVertex2f(
						textures.get(currentAnimation)[textureId].getImageWidth(),
						textures.get(currentAnimation)[textureId].getImageHeight());
				//Vertex at the down right
				GL11.glTexCoord2f(textures.get(currentAnimation)[textureId].getWidth(), 0);
				GL11.glVertex2f(textures.get(currentAnimation)[textureId].getImageWidth(),0);
			}
			GL11.glEnd();

			// restore the model view matrix to prevent contamination
			GL11.glPopMatrix();
			//goes to the next texture
			textureId++;
			if(textures.get(currentAnimation).length >= textureId){
				textureId = 0;
			}
		}
	}

	/**
	 * Returns the bound of this class
	 */
	public Rectangle getBound() {
		return new Rectangle(
				(int)getLocation().getX(),
				(int)getLocation().getY(),
				textures.get(currentAnimation)[textureId].getImageWidth(),
				textures.get(currentAnimation)[textureId].getImageHeight());
	}
}