package cz.cuni.amis.pogamut.ut2004.agent.module.sensor;

import cz.cuni.amis.pogamut.base.agent.worldview.IWorldView;
import cz.cuni.amis.pogamut.base.agent.worldview.WorldEventListener;
import cz.cuni.amis.pogamut.ut2004.agent.module.AgentModule;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Bumped;

import java.util.logging.Logger;

/**
 * Memory module specialized on agent's sences.
 *
 * @author Juraj 'Loque' Simlovic
 */
public class Senses extends AgentModule
{
	/**
	 * Tells, whether the agent is colliding with map geometry.
	 *
	 * <p><b>Note: This method clears the collision flag upon invocation.</b>
	 * This is to prevent taking more action because of one collision.
	 *
	 * @return True, if the agent is colliding with map geometry.
	 */
	public boolean isColliding ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean isBumping ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean isFalling ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean isHearingNoise ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean isHearingPickup ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	/**
	 * Tells, whether the agent sees any enemies nearby.
	 *
	 * @return True, if the agent sees any enemies nearby.
	 */
	public boolean seeEnemiesNearby ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	/**
	 * Tells, whether the agent is being damaged.
	 *
	 * @return True, if the agent is being damaged.
	 */
	public boolean isBeingDamaged ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean seeIncomingProjectile ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	public boolean isCausingDamage ()
	{
		// FIXME[js]: implement when available
		throw new UnsupportedOperationException("Not supported yet");
	}

	/*========================================================================*/

	/** Most rescent message containing info about the agent. */
	Bumped lastBumped = null;

	/*========================================================================*/

	/**
	 * Bumped listener.
	 */
	private class BumpedListener implements WorldEventListener<Bumped>
	{
		@Override
		public void notify(Bumped event)
		{
			// FIXME[js]: self updating?
			lastBumped = event;
		}

		/**
		 * Constructor. Registers itself on the given WorldView object.
		 * @param worldView WorldView object to listent to.
		 */
		public BumpedListener(IWorldView worldView)
		{
			worldView.addListener(Bumped.class, this);
		}
	}

	/** Bumped listener */
	BumpedListener bumpedListener;

	/*========================================================================*/

	/** AgentInfo memory module. */
	protected AgentInfo agentInfo;

	/**
	 * Constructor. Setups the memory module based on given WorldView.
	 * @param worldView WorldView object to read the info from.
	 * @param agentInfo AgentInfo memory module. Note: If <i>null</i> is
	 * provided, this memory module creates its own AgentInfo memory module.
	 * Provide shared AgentInfo memory module to economize CPU time and other
	 * resources.
	 * @param log Logger to be used for logging runtime/debug info.
	 */
	public Senses(IWorldView worldView, AgentInfo agentInfo, Logger log)
	{
		super(log);

		// set or create AgentInfo memory module
		if (agentInfo != null) this.agentInfo = agentInfo;
		else this.agentInfo = new AgentInfo(worldView, null, log);

		// create listeners
		bumpedListener = new BumpedListener(worldView);
	}
}