package de.rico.adventure.entity;

import de.rico.engine.effect.ortho.RectangleRenderer;
import de.rico.engine.effect.ortho.TextRenderer;
import de.rico.engine.geometry.AbstractMesh;
import de.rico.engine.material.Color4f;

/**
 * This is the abstract base class for all entities (game objects) in the game.
 *
 * @author Frank Bruns
 */
public abstract class AbstractEntity
{
	private AbstractMesh mesh = null;

	private String scriptId = null;

	private boolean enabled = true;

	private TextRenderer textRenderer = null;
	
	private RectangleRenderer rectRenderer = null;

	private String screenName = "Give me a name, please!";

	/**
	 * Creates a new entity with the specified mesh as a model
	 *
	 * @param mesh mesh to use as a model for the entity
	 */
	public AbstractEntity(AbstractMesh mesh)
	{
		this.mesh = mesh;
		this.textRenderer = new TextRenderer();
		this.rectRenderer = new RectangleRenderer(new Color4f(0f,0f,0f,0.65f));
	}

	/**
	 * Sets the screen name of the entity. The name must be unique
	 * for all the entities.
	 *
	 * @param name screen name of the entity
	 */
	public void setScreenName(String name)
	{
		this.screenName = name;
	}

	/**
	 * Returns the entity's screen name.
	 *
	 * @return screen name of the entity
	 */
	public String getScreenName()
	{
		return this.screenName;
	}

	/**
	 * Returns the mesh that is used for this entity.
	 *
	 * @return the mesh for the entity
	 */
	public AbstractMesh getMesh()
	{
		return this.mesh;
	}

	/**
	 * Returns the reference id for this entity which is used in a script file.
	 *
	 * @return reference id in a script file
	 * @throws NullPointerException Occurs when no id has been specified for the
	 *         entity.
	 */
	public String getScriptId()
	{
		return this.scriptId;
	}

	/**
	 * Sets the identifier that can be used to refer to this entity in a script
	 * file.
	 *
	 * @param id reference id in a script file
	 */
	public void setScriptId(String id)
	{
		this.scriptId = id;
	}

	/**
	 * Determines whether or not the entity is enabled.
	 * @return is enabled? --> true=yes, false=no
	 */
	public boolean isEnabled()
	{
		return this.enabled;
	}

	/**
	 * Sets whether or not this entity is enabled.
	 * @param enable set enabled? --> true=yes, false=no
	 */
	public void setEnabled(boolean enable)
	{
		this.enabled = enable;
	}

	/**
	 * Draws the description of the character at the specified screen position.
	 *
	 * @param screenX x-coordinate on the screen
	 * @param screenY y-coordinate on the screen
	 */
	public void drawScreenName(int screenX, int screenY)
	{
		// draw text background
		this.rectRenderer.drawRectangle(
				screenX, 
				screenY-this.textRenderer.getFont().getHeight()-4, 
				this.textRenderer.getStringWidth(this.screenName),
				this.textRenderer.getFont().getHeight()+2);
		
		// draw name
		this.textRenderer.drawString(
				this.screenName,
				screenX,
				screenY-this.textRenderer.getFont().getHeight()-5);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		return "Entity: "+this.screenName+" ["+this.mesh.getPosX()+";"+this.mesh.getPosY()+";"+this.mesh.getPosZ()+"]";
	}

	/**
	 * Destroys the entity and releases its resources.
	 *
	 */
	public void destroy()
	{
		this.mesh.destroy();
		this.textRenderer = null;;
		this.screenName = null;
		this.scriptId = null;
	}
}
