/**
 *
 */
package com.tootsville.npc;

import java.util.concurrent.atomic.AtomicInteger;

import org.json.JSONObject;
import org.starhope.appius.except.GameLogicException;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.except.UserDeadException;
import org.starhope.appius.geometry.Coord2D;
import org.starhope.appius.geometry.Coord3D;
import org.starhope.appius.geometry.Vector2D;
import org.starhope.appius.physica.Geometry;
import org.starhope.appius.room.Room;

/**
 * @author ewinkelman
 */
public class Volleyball extends SoccerBall {

	/**
	 * Java serialisation unique ID
	 */
	private static final long serialVersionUID = 4901576938301015117L;

	/**
	 * Static next instance ID for keeping track of instances of soccer
	 * balls
	 */
	private static AtomicInteger nextInstanceID = new AtomicInteger ();

	/**
	 * Create an instance of a soccer ball
	 * 
	 * @throws GameLogicException WRITEME
	 * @throws NotFoundException WRITEME
	 */
	public Volleyball () throws NotFoundException, GameLogicException {
		super ("$VolleyBall");
		setVariable ("noClick", "true");
	}







	/**
	 * @see org.starhope.appius.physica.Collidable#getCenterOfMass()
	 */
	@Override
	public Coord2D getCenterOfMass () {
		return getLocation ().toCoord2D ();
	}

	/**
	 * Ball is velocity based and doesn't have predetermined start/stop
	 * 
	 * @see org.starhope.appius.physica.Collidable#getEndMovementTime(long)
	 */
	@Override
	public long getEndMovementTime (final long currentTime) {
		return Geometry.getTimeToTarget (this, currentTime)
		+ currentTime;
	}

	/**
	 * @see org.starhope.appius.user.AbstractNonPlayerCharacter#getInstanceID()
	 */
	@Override
	protected int getInstanceID () {
		return Volleyball.nextInstanceID.incrementAndGet ();
	}

	/**
	 * @see org.starhope.appius.physica.Collidable#getMass()
	 */
	@Override
	public double getMass () {
		return 2.0d;
	}

	/**
	 * @see org.starhope.appius.physica.Collidable#getStartMovementTime()
	 */
	@Override
	public long getStartMovementTime () {
		return getStartT ();
	}

	/**
	 * @return WRITEME
	 * @see org.starhope.appius.physica.Collidable#getVelocity()
	 */
	@Override
	public synchronized Vector2D getVelocity () {
		final Coord3D loc = getLocation ();
		final Coord3D target = getTarget ();
		Vector2D result = new Vector2D (target.getX () - loc.getX (),
				target.getY () - loc.getY ());
		if (result.length () != 0) {
			result = result.normalize ();
		}
		result = result.scale (getTravelRate ());
		return result;
	}



	/**
	 * @see org.starhope.appius.user.AbstractUser#sendOops()
	 */
	@Override
	public void sendOops () {
		// no op

	}

	/**
	 * @see org.starhope.appius.user.AbstractUser#sendResponse(org.json.JSONObject)
	 */
	@Override
	public void sendResponse (final JSONObject result) {
		// no op
	}

	/**
	 * @see org.starhope.appius.user.AbstractUser#sendWardrobe()
	 */
	@Override
	public void sendWardrobe () {
		// no op
	}

	/**
	 * @param com WRITEME
	 * @see org.starhope.appius.physica.Collidable#setCenterOfMass(Coord2D)
	 */
	@Override
	public void setCenterOfMass (final Coord2D com) {
		final Room aRoom = getRoom ();
		if (null != aRoom) {
			aRoom.putHere (this, com.toCoord3D ());
		}
	}

	/**
	 * @param velocity WRITEME
	 * @see org.starhope.appius.physica.Collidable#setVelocity(Vector2D)
	 */
	@Override
	public synchronized void setVelocity (final Vector2D velocity) {
		final Room aRoom = getRoom ();
		if (null != aRoom) {
			setTravelRate (velocity.length ());
			final Coord3D loc = getLocationForUpdate ();
			try {
			aRoom.goTo (this, loc.add (velocity.getX (),
						velocity.getY (), 0d), null, "Walk");
			} finally {
				unlockLocation ();
			}
		}
	}

	/**
	 * @see org.starhope.appius.util.AcceptsMetronomeTicks#tick(long,
	 *      long)
	 */
	@Override
	public void tick (final long currentTime, final long deltaTime)
	throws UserDeadException {
		// TODO Auto-generated method stub

	}

}
