package gizmoball.game;

import junit.framework.Assert;

import physics.*;

/**
 * The circular bumper gizmo.  This is a circle-shaped bumper with a
 * coefficient of reflection of 1.0.
 *
 * @author <a href="mailto:amdragon@mit.edu">Austin Clements</a>
 * @version 1.0
 */
public class CircleBumperGizmo extends AbstractGizmo {
    private static double RADIUS = 0.5;
    
    /**
     * Creates a new <code>CircleBumperGizmo</code> instance.
     */
    public CircleBumperGizmo() {
        super("Circle bumper", Vect.ZERO);
    }

    /**
     * Get the circle representing this bumper's geometry
     */
    public Circle getCircle() {
        return new Circle(getPosition().plus(new Vect(RADIUS, RADIUS)),
                          RADIUS);
    }

    /**
     * Does nothing.
     */
    public boolean tick(double time)
    {
        return false;
    }

    /**
     * Circle bumpers collide with ball gizmos, and never with
     * anything else.
     *
     * @param other the gizmo to test collidability with
     * @return CAN_COLLIDE for BallGizmo, NEVER_COLLIDE otherwise
     */
    public Collidability canCollideWith(AbstractGizmo other) {
        if (other instanceof BallGizmo) {
            return Collidability.CAN_COLLIDE;
        } else {
            return Collidability.NEVER_COLLIDE;
        }
    }

    /**
     * Determines the time until a collision with a ball.
     *
     * @requires other instanceof BallGizmo
     * @param other the gizmo to test collision time with
     * @return the time until collision with other, or
     * Double.POSITIVE_INFINITY if no collision will occur
     */
    public double timeUntilCollisionWith(AbstractGizmo other) {
        BallGizmo ball = (BallGizmo)other;
        Circle ballCircle = ball.getCircle();
        Vect ballVelocty = ball.getVelocity();

        return Geometry.timeUntilCircleCollision(getCircle(),
                                                 ballCircle,
                                                 ballVelocty);
    }

    /**
     * Resolve a collision with a ball.  This reflects the ball off
     * whatever face (or point) it collided with.  This assumes the
     * ball is approximately one radius away from one of the faces.
     *
     * @requires other instanceof BallGizmo
     * @param other the gizmo to collide with
     */
    public void collide(AbstractGizmo other) {
        BallGizmo ball = (BallGizmo)other;
        Circle ballCircle = ball.getCircle();
        Vect ballVelocity = ball.getVelocity();

        Vect newVelocity = Geometry.reflectCircle(getPosition().plus
                                                  (new Vect(RADIUS, RADIUS)),
                                                  ballCircle.getCenter(),
                                                  ballVelocity);
        ball.setVelocity(newVelocity);
    }

    /**
     * Does nothing.
     */
    public void fireTrigger(AbstractTrigger trigger) {
    }
}
