/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.object.vertex;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;

import net.sf.jaxodraw.object.AbstractJaxoExtendedObjectTest;
import net.sf.jaxodraw.util.JaxoConstants;


/**
 * Base Test for JaxoVertex.
 */
public abstract class AbstractJaxoVertexTest
    extends AbstractJaxoExtendedObjectTest {

    private JaxoVertex instance;

    /**
     * Constructor.
     *
     * @param testName The name of this test.
     */
    protected AbstractJaxoVertexTest(String testName) {
        super(testName);
    }

    /** JUnit setup: get a new instance of the object. */
    @Override
    protected void setUp() {
        super.setUp();
        this.instance = (JaxoVertex) getInstance();
    }

      //
     // tests
    //

    /** Tests moveBy. */
    public void testMoveBy() {
        instance.setLocation(100, 100, 200, 200);
        instance.moveBy(23, -45);

        assertEquals("Wrong moveBy x!", 123, instance.getX());
        assertEquals("Wrong moveBy y!", 55, instance.getY());
        assertEquals("Wrong moveBy x2!", 223, instance.getX2());
        assertEquals("Wrong moveBy y2!", 155, instance.getY2());
    }

    /** Tests smallestDistanceTo. */
    public void testSmallestDistanceTo() {
        instance.setLocation(100, 100, 200, 200);

        float dist = instance.smallestDistanceTo(103, 104);
        assertEquals("Wrong distance", dist, 5.f);
        dist = instance.smallestDistanceTo(203, 204);
        assertEquals("Wrong distance", dist, 5.f);
    }

    /** Tests rescaleObject. */
    public void testRescaleObject() {
        instance.setLocation(100, 100, 200, 200);

        instance.rescaleObject(instance.getX(), instance.getY(), 2.f);
        assertEquals("Vertex x wrongly rescaled!", 200, instance.getRelw());
        assertEquals("Vertex y wrongly rescaled!", 200, instance.getRelh());
    }

    /** Tests getGrabbedHandle. */
    public void testGetGrabbedHandle() {
        instance.setRelWAndH(100, 0);
        checkHandle(200, 100, JaxoVertex.SELECT_P2);
        checkHandle(500, 500, JaxoVertex.SELECT_NONE);
        checkHandle(100, 100, JaxoVertex.SELECT_P1);

        instance.setRelWAndH(0, -100);
        checkHandle(100, 0, JaxoVertex.SELECT_P2);
        instance.setRelWAndH(-100, 0);
        checkHandle(0, 100, JaxoVertex.SELECT_P2);
    }

    /** Tests canBeSelected. */
    public void testCanBeSelected() {
        instance.setLocation(100, 100, 200, 200);

        int mode = JaxoConstants.MOVE;
        int handle = JaxoVertex.SELECT_P1;
        assertTrue("P1 in MOVE mode", instance.canBeSelected(handle, mode));
        handle = JaxoVertex.SELECT_P2;
        assertTrue("P2 in MOVE mode", instance.canBeSelected(handle, mode));

        mode = JaxoConstants.RESIZE;
        handle = JaxoVertex.SELECT_P1;
        assertFalse("P1 in RESIZE mode", instance.canBeSelected(handle, mode));
        handle = JaxoVertex.SELECT_P2;
        assertTrue("P2 in RESIZE mode", instance.canBeSelected(handle, mode));
    }

    /** Tests float compare methods. */
    public void testFloatCompare() {
        instance.setStrokeWidth(3.f);
        assertTrue(instance.strokeIs(3.000000001f));
        assertFalse(instance.strokeIs(3.01f));
    }

    /** Tests getLaTexRadius. */
    public void testGetLaTexRadius() {
        float rad = instance.getLaTexRadius((float) Math.sqrt(2.d));
        assertTrue("Wrong LaTexRadius!", Math.abs(rad - 100.f) < 0.01f);
    }

    /** Tests getLaTexCenter. */
    public void testGetLaTexCenter() {
        checkCenter((Point2D.Float) instance.getLaTexCenter(2.f, 600), 50.f,
            250.f);

        instance.setRelWAndH(100, -100);
        checkCenter((Point2D.Float) instance.getLaTexCenter(2.f, 600), 50.f,
            250.f);

        instance.setRelWAndH(-100, 100);
        checkCenter((Point2D.Float) instance.getLaTexCenter(2.f, 600), 50.f,
            250.f);

        instance.setRelWAndH(-100, -100);
        checkCenter((Point2D.Float) instance.getLaTexCenter(2.f, 600), 50.f,
            250.f);

    }

    private void checkCenter(Point2D.Float centerPoint, float x, float y) {
        assertTrue("Wrong LaTexCenter x! Got: " + centerPoint.x,
            Math.abs(centerPoint.x - x) < 0.01f);
        assertTrue("Wrong LaTexCenter y! Got: " + centerPoint.y,
            Math.abs(centerPoint.y - y) < 0.01f);
    }

    /** {@inheritDoc} */
    public void testContains() {
        instance.setLocation(100, 100, 130, 130);

        assertTrue(getInstance().contains(75, 75));
        assertFalse(getInstance().contains(5, 5));

        assertTrue(getInstance().contains(75, 75, 5, 5));
        assertFalse(getInstance().contains(5, 5, 5, 5));

        assertTrue(getInstance().contains(new Point(75, 75)));
        assertFalse(getInstance().contains(new Point(5, 5)));

        assertTrue(getInstance().contains(new Rectangle(75, 75, 5, 5)));
        assertFalse(getInstance().contains(new Rectangle(5, 5, 5, 5)));
    }

    /** {@inheritDoc} */
    public void testIntersects() {
        instance.setLocation(100, 100, 130, 130);

        assertTrue(getInstance().intersects(5, 5, 100, 100));
        assertFalse(getInstance().intersects(5, 5, 10, 10));

        assertTrue(getInstance().intersects(new Rectangle(130, 130)));
        assertFalse(getInstance().intersects(new Rectangle(10, 10)));
    }

    /** {@inheritDoc} */
    public String[] serializableProperties() {
        return new String[] {
            "pointCount", "points", "color", "strokeWidth", "rotationAngle"
        }; // 5
    }

      //
     // abstract
    //

    /** Tests serialization. */
    public abstract void testSerialization();

}
