package de.rico.adventure.script.trigger;

import java.util.List;

import javax.media.opengl.GL;

import de.rico.adventure.entity.character.AbstractCharacter;
import de.rico.engine.geometry.MeshFactory;

/**
 * This class represents a rectangular trigger area.
 * @author Frank Bruns
 */
public class RectTriggerArea extends AbstractTrigger
{
	private float width = 0f;
	private float length = 0f;

	private float meshWidth = 0f;
	private float meshLength = 0f;


	/**
	 * Creates a new rectangular trigger area with no candidates for
	 * firering the trigger initially assigned.
	 * @param scriptId id for reference purposes in script files
	 * @param x x-coordinate of the trigger center
	 * @param z z-coordinate of the trigger center
	 * @param width width of the trigger reactangle
	 * @param length height of the trigger reactangle
	 */
	public RectTriggerArea(String scriptId, float x, float z, float width, float length)
	{
		super(scriptId,x,z);
		this.width = width;
		this.length = length;
	}

	/**
	 * Creates a new rectangular trigger area with the
	 * specified character as the only one that can fire the
	 * trigger.
	 * @param scriptId id for reference purposes in script files
	 * @param x x-coordinate of the trigger center
	 * @param z z-coordinate of the trigger center
	 * @param width width of the trigger rectangle
	 * @param length height of the trigger reactangle
	 * @param c only character that can fire the trigger
	 */
	public RectTriggerArea(String scriptId, float x, float z, float width, float length, AbstractCharacter c)
	{
		super(scriptId,x,z,c);
		this.width = width;
		this.length = length;
	}

	/**
	 * Creates a new rectangular trigger area with the specified list
	 * of characters that can fire the trigger.
	 * @param scriptId id for reference purposes in script files
	 * @param x x-coordinate of the trigger center
	 * @param z z-coordinate of the trigger center
	 * @param width width of the trigger rectangle
	 * @param length length of the trigger reactangle
	 * @param candiates candiates for firering the trigger
	 */
	public RectTriggerArea(String scriptId, float x, float z, float width, float length, List<AbstractCharacter> candiates)
	{
		super(scriptId,x,z,candiates);
		this.width = width;
		this.length = length;
	}

	/**
	 * Returns the width of the trigger area.
	 * @return width of the trigger area
	 */
	public float getWidth()
	{
		return this.width;
	}

	/**
	 * Sets a new width for the trigger area.
	 * @param width new width for the trigger
	 */
	public void setWidth(float width)
	{
		this.width = width;
	}

	/**
	 * Returns the length of the trigger area.
	 * @return length of the trigger area
	 */
	public float getLength()
	{
		return this.length;
	}

	/**
	 * Sets a new length for the trigger area.
	 * @param length new length for the trigger
	 */
	public void setLength(float length)
	{
		this.length = length;
	}

	/* (non-Javadoc)
	 * @see de.rico.adventure.script.trigger.AbstractTrigger#isCandiateOnTrigger()
	 */
	@Override
	public boolean isCandiateOnTrigger()
	{
		for(AbstractCharacter c : this.getCandidates())
		{
			float cX = c.getMesh().getPosX();
			float cZ = c.getMesh().getPosZ();

			// check if the character'c center lies within the
			// bounds od the trigger rectangle
			if((cX >= this.getX()-this.width/2f && cX <= this.getX()+this.width/2f)
					&& (cZ >= this.getZ()-this.length/2f && cZ <= this.getZ()+this.length/2f))
			{
				return true; // character is on the trigger
			}
		}

		return false; // no candidate is on the trigger
	}

	/* (non-Javadoc)
	 * @see de.rico.adventure.script.trigger.AbstractTrigger#draw(javax.media.opengl.GL)
	 */
	@Override
	public void draw(GL gl)
	{
		if(this.visMesh != null) this.visMesh.draw(gl);
	}


	/**
	 * This method updates the special things of the circular
	 * trigger area and calls the update() method of the super class
	 * {@link de.rico.adventure.script.trigger.AbstractTrigger#update(long)}, too.
	 * @param elapsedTime time between two frames
	 */
	@Override
	public void update(long elapsedTime)
	{
		super.update(elapsedTime);

		if(this.visMesh == null)
		{
			this.visMesh = MeshFactory.createHorizontalRectangle(this.length, this.width, 1f, false);
			this.meshWidth = this.width;
			this.meshLength = this.length;
			this.visMesh.setPosition(this.getX(), 0f, this.getZ());
		}


		// resize the mesh by reconstructing it in the next update()
		// call if the trigger size changed
		if(this.width != this.meshWidth || this.length != this.meshLength)
		{
			this.visMesh.destroy();
			this.visMesh = null;
		}

	}

}
