package gizmoball.game;

import java.util.*;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import physics.Geometry;
import physics.Vect;

/**
 * Unit tests for the concrete gizmos
 *
 * @author <a href="mailto:amdragon@mit.edu">Austin Clements</a>
 * @version $Id: GizmoTest.java,v 1.1 2004/04/25 10:48:36 amthrax Exp $
 */
public class GizmoTest extends TestCase {
    private static final double TOLERANCE = 0.01;

    public GizmoTest(String name) {
        super(name);
    }

    public static Test suite() {
        return new TestSuite(GizmoTest.class);
    }

    public void testBallGizmo() {
        BallGizmo bg = new BallGizmo();

        bg.setPosition(Vect.ZERO);
        bg.setVelocity(Vect.Y_HAT.neg());

        // Run some simple simulation
        bg.tick(1);

        assertEquals(0.0, bg.getPosition().x(), TOLERANCE);
        assertEquals(-1.0, bg.getPosition().y(), TOLERANCE);

        assertEquals(0.0, bg.getVelocity().x(), TOLERANCE);
        assertEquals((-1+25.0)*(1-0.025-0.025*24), bg.getVelocity().y(),
                     TOLERANCE);

        bg.tick(1);

        assertEquals(0.0, bg.getPosition().x(), TOLERANCE);
        assertEquals(-1.0+(-1+25.0)*(1-0.025-0.025*24), bg.getPosition().y(),
                     TOLERANCE);

        if (false) {  // FIXME Collisions don't work yet

        // Test collidability
        bg.setPosition(Vect.ZERO);
        bg.setVelocity(Vect.Y_HAT.neg());

        assertSame(Collidability.CAN_COLLIDE,
                   bg.canCollideWith(new BallGizmo()));

        BallGizmo bg2 = new BallGizmo();
        bg.setPosition(Vect.Y_HAT.neg().times(2));
        bg.setVelocity(Vect.Y_HAT);
        assertEquals(1.0, bg.timeUntilCollisionWith(bg2), TOLERANCE);

        BallGizmo bg3 = new BallGizmo();
        bg.setPosition(Vect.Y_HAT.neg().times(2));
        bg.setVelocity(Vect.Y_HAT.neg());
        assertEquals(Double.POSITIVE_INFINITY, bg.timeUntilCollisionWith(bg3),
                     TOLERANCE);

        bg.tick(1);
        bg.collide(bg2);
        Geometry.VectPair vp = Geometry.reflectBalls(bg.getPosition(), 1,
                                                     bg.getVelocity(),
                                                     bg2.getPosition(), 1,
                                                     bg2.getVelocity());
        assertEquals(vp.v1.x(), bg.getVelocity().x(), TOLERANCE);
        assertEquals(vp.v1.y(), bg.getVelocity().y(), TOLERANCE);
        assertEquals(vp.v2.x(), bg2.getVelocity().x(), TOLERANCE);
        assertEquals(vp.v2.y(), bg2.getVelocity().y(), TOLERANCE);

        }
    }
}
