/**
 *  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;

import java.awt.Point;
import java.awt.Rectangle;

import net.sf.jaxodraw.util.JaxoConstants;

/**
 * Base Test for 3PointObjects.
 */
public abstract class AbstractJaxo3PointObjectTest
        extends AbstractJaxoParticleObjectTest {

    private Jaxo3PointObject instance;

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

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

    /** Tests moveBy. */
    public void testMoveBy() {
        instance.setLocation(50, 50, 100, 50, 100, 100);

        instance.moveBy(0, 0);
        assertEquals("Wrong moveBy!", 50, instance.getX());
        assertEquals("Wrong moveBy!", 50, instance.getY());

        instance.moveBy(10, 5);
        assertEquals("Wrong moveBy!", 60, instance.getX());
        assertEquals("Wrong moveBy!", 55, instance.getY());
        assertEquals("Wrong moveBy!", 110, instance.getX2());
        assertEquals("Wrong moveBy!", 55, instance.getY2());
        assertEquals("Wrong moveBy!", 110, instance.getX3());
        assertEquals("Wrong moveBy!", 105, instance.getY3());
    }

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

        instance.rescaleObject(instance.getX(), instance.getY(), 2.f);
        assertEquals("Arc x wrongly rescaled!", 50, instance.getX());
        assertEquals("Arc y wrongly rescaled!", 50, instance.getY());
        assertEquals("Arc x wrongly rescaled!", 150, instance.getX2());
        assertEquals("Arc y wrongly rescaled!", 50, instance.getY2());
        assertEquals("Arc x wrongly rescaled!", 150, instance.getX3());
        assertEquals("Arc y wrongly rescaled!", 150, instance.getY3());

        instance.setLocation(50, 50, 100, 50, 100, 100);
        instance.setAmp(5);
        instance.setWiggles(25);
        instance.rescaleObject(instance.getX(), instance.getY(), 3.f);
        assertEquals("Arc amp wrongly rescaled!", 15, instance.getAmp());
        assertEquals("Arc wiggles wrongly rescaled!", 75, instance.getWiggles());
    }

    /** Tests getGrabbedHandle. */
    public void testGetGrabbedHandle() {
        instance.setLocation(50, 50, 100, 50, 100, 100);
        checkHandle(50, 50, Jaxo3PointObject.SELECT_P1);
        checkHandle(100, 50, Jaxo3PointObject.SELECT_P2);
        checkHandle(100, 100, Jaxo3PointObject.SELECT_P3);
        checkHandle(500, 500, Jaxo3PointObject.SELECT_NONE);
    }

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

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

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

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

        float dist = instance.smallestDistanceTo(103, 104);
        assertEquals("Wrong distance", dist, 5.f);
        dist = instance.smallestDistanceTo(100, 55);
        assertEquals("Wrong distance", dist, 5.f);
        dist = instance.smallestDistanceTo(53, 54);
        assertEquals("Wrong distance", dist, 5.f);
    }

    /** Tests all getters/setters. */
    public void testGetSetXY() {
        assertEquals("Wrong PointCount!", 3, instance.getPointCount());
        try {
            instance.setPointCount(2);
            fail("setPointCount(2) should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // expected, now check it doesn't throw with proper value
            instance.setPointCount(3);
        }
    }

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

        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(50, 50, 100, 50, 100, 100);

        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(30, 30)));
    }
}
