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

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

import net.sf.jaxodraw.JaxoTestUtils;
import net.sf.jaxodraw.io.imports.JaxoAxodraw4J;
import net.sf.jaxodraw.object.JaxoObject;
import net.sf.jaxodraw.object.JaxoObjectFactory;
import net.sf.jaxodraw.object.arc.JaxoGArc;
import net.sf.jaxodraw.object.loop.JaxoFLoop;
import net.sf.jaxodraw.util.JaxoColor;
import net.sf.jaxodraw.util.JaxoConstants;
import net.sf.jaxodraw.util.JaxoPrefs;


/** Tests JaxoSBezier. */
public class JaxoSBezierTest extends AbstractJaxoBezierObjectTest {
    private JaxoSBezier bezier = new JaxoSBezier();

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

    /** JUnit setup: initialize the object. */
    @Override
    protected void setUp() {
        super.setUp();
        init();
    }

    private void init() {
        bezier.setLocation(50, 50, 100, 50, 100, 100, 50, 100);
        bezier.setColor(JaxoColor.GREEN);
        bezier.setStrokeWidth(1.f);
        bezier.setPaintArrow(false);
        bezier.setArrowPosition(.5f);
        bezier.setFlip(false);
        bezier.setDoubleLine(false);
        bezier.setDLSeparation(2.f);
    }

    /** {@inheritDoc} */
    public JaxoObject getInstance() {
        return bezier;
    }

    /** Tests serialization. */
    public void testSerialization() {
        bezier.setStrokeWidth(1.5f);
        bezier.setPaintArrow(true);
        bezier.setArrowPosition(.5f);
        bezier.setFlip(true);
        JaxoTestUtils.checkSerializedEquality(bezier);
    }

    /** Tests that a copy of an object is still the same object. */
    public void testCopy() {
        bezier.setStrokeWidth(1.5f);
        bezier.setPaintArrow(true);
        bezier.setArrowPosition(.5f);
        bezier.setFlip(true);
        JaxoTestUtils.checkCopyEquality(bezier);

        JaxoSBezier bezier2 = new JaxoSBezier();
        bezier2.setLocation(50, 50, 100, 50, 100, 100, 50, 100);
        bezier2.setColor(JaxoColor.GREEN);
        bezier2.setStrokeWidth(1.f);
        bezier2.setPaintArrow(false);
        bezier2.setArrowPosition(.5f);
        bezier2.setFlip(false);
        bezier2.setDoubleLine(false);
        bezier2.setDLSeparation(2.f);
        assertFalse(bezier2.isCopy(bezier));

        bezier2.setStrokeWidth(1.5f);
        bezier2.setPaintArrow(true);
        bezier2.setArrowPosition(.5f);
        bezier2.setFlip(true);
        assertTrue(bezier2.isCopy(bezier));

        JaxoFLoop loop = new JaxoFLoop();
        assertFalse(bezier.isCopy(loop));

        JaxoSBezier sbezier = new JaxoSBezier();
        JaxoGArc garc = new JaxoGArc();
        assertFalse("SBezier is copy of GArc!", sbezier.isCopy(garc));

    }

    /** Tests the latex command. */
    public void testLatexCommand() {
        Dimension dim = new Dimension(100, 100);

        String expected = "\\Bezier[dash,dsize=0](50,50)(100,50)(100,0)(50,0)%JaxoID:SBez";
        String actual = bezier.latexCommand(1.f, dim);
        assertEquals("SBezier Latex commands do not match!", expected, actual);
    }

    /** Tests axodraw. */
    public void testAxodraw() {
        JaxoAxodraw4J axo = new JaxoAxodraw4J();
        JaxoObject ob = axo.getJaxoObject("\\SetWidth{1.0}");
        assertNull(ob);

        String command = "\\DashBezier(50,50)(100,50)(100,0)(50,0){0}%JaxoID:SBez";
        bezier = (JaxoSBezier) axo.getJaxoObject(command);
        checkBezier();

        command = "\\Bezier[dash,dsize=0](50,50)(100,50)(100,0)(50,0)%JaxoID:SBez";
        bezier = (JaxoSBezier) axo.getJaxoObject(command);
        checkBezier();

        command = "\\Bezier[dash,dashsize=5](50,50)(100,50)(100,0)(50,0)%JaxoID:SBez";
        bezier = (JaxoSBezier) axo.getJaxoObject(command);
        assertTrue("SBezier doesn't have the right dash!", bezier.dashIs(5.f));
    }

    private void checkBezier() {
        assertNotNull("SBezier not recognized!", bezier);
        assertEquals("SBezier doesn't have the right color!", JaxoColor.BLACK, bezier.getColor());
        assertTrue("SBezier doesn't have the right stroke!", Math.abs(bezier.getStrokeWidth() - 1.f) < 0.0001f);
        assertFalse("SBezier has an arrow!", bezier.isPaintArrow());
        assertEquals("SBezier doesn't have the right x1!", 50, bezier.getX());
        assertEquals("SBezier doesn't have the right y1!", -50, bezier.getY());
        assertEquals("SBezier doesn't have the right x2!", 100, bezier.getX2());
        assertEquals("SBezier doesn't have the right y2!", -50, bezier.getY2());
        assertEquals("SBezier doesn't have the right x3!", 100, bezier.getX3());
        assertEquals("SBezier doesn't have the right y3!", 0, bezier.getY3());
        assertEquals("SBezier doesn't have the right x4!", 50, bezier.getX4());
        assertEquals("SBezier doesn't have the right y4!", 0, bezier.getY4());
    }

    /** Tests the getBounds() method. */
    public void testGetBounds() {
        Rectangle bBox = bezier.getBounds();
        Rectangle expected = new Rectangle(49, 49, 39, 52);
        assertEquals("Bounding box not correct!", expected, bBox);
        bezier.setPaintArrow(true);
        bezier.setArrowPosition(.5f);
        bBox = bezier.getBounds();
        expected = new Rectangle(49, 49, 42, 52);
        assertEquals("Bounding box not correct!", expected, bBox);

        assertNotNull(bezier.getBounds2D());
    }

    /** Tests createNewObject in JaxoObjectFactory. */
    public void testCreateNewObject() {
        Point p = new Point(50, 50);
        Point q = new Point(100, 50);
        Point r = new Point(100, 100);
        Point s = new Point(50, 100);
        JaxoObject ob =
            JaxoObjectFactory.newObject(JaxoConstants.SBEZ, new Point[] {p, q, r, s});

        assertTrue("createNewObject did not return a SBezier!",
            (ob instanceof JaxoSBezier));

        bezier = (JaxoSBezier) ob;
        assertEquals("SBezier doesn't have the right x1!", 50, bezier.getX());
        assertEquals("SBezier doesn't have the right y1!", 50, bezier.getY());
        assertEquals("SBezier doesn't have the right x2!", 100, bezier.getX2());
        assertEquals("SBezier doesn't have the right y2!", 50, bezier.getY2());
        assertEquals("SBezier doesn't have the right x3!", 100, bezier.getX3());
        assertEquals("SBezier doesn't have the right y3!", 100, bezier.getY3());
        assertEquals("SBezier doesn't have the right x4!", 50, bezier.getX4());
        assertEquals("SBezier doesn't have the right y4!", 100, bezier.getY4());
        assertEquals("SBezier doesn't have the right color!",
            JaxoColor.getColor(JaxoPrefs.getStringPref(JaxoPrefs.PREF_COLOR)),
            bezier.getColor());
        assertTrue("SBezier doesn't have the right stroke!",
            bezier.strokeIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH)));
        assertEquals("SBezier doesn't have the right arrow!",
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_ARROW), bezier.isPaintArrow());
        assertEquals("SBezier doesn't have the right flip!", false, bezier.isFlip());
        assertEquals("SBezier doesn't have the right double line!", false,
            bezier.isDoubleLine());
        assertTrue("SBezier doesn't have the right dlsep!",
            bezier.dlSepIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP)));
    }
    /** {@inheritDoc} */
    public String className() {
        return "JaxoSBezier";
    }

    /** {@inheritDoc} */
    public void testJaxo20Compat() {
        JaxoSBezier object =
                (JaxoSBezier) instanceFrom20OpenGraph(JaxoSBezier.class);
        assertNotNull(object);
        check20Object("opened wrong object!", object);

        object =
                (JaxoSBezier) instanceFrom20ImportGraph(JaxoSBezier.class);
        assertNotNull(object);
        check20Object("imported wrong object!", object);
    }

    private void check20Object(String message, JaxoSBezier object) {

        assertEquals(message, 629, object.getX());
        assertEquals(message, 99, object.getY());
        assertEquals(message, 598, object.getX2());
        assertEquals(message, 158, object.getY2());
        assertEquals(message, 654, object.getX3());
        assertEquals(message, 230, object.getY3());
        assertEquals(message, 734, object.getX4());
        assertEquals(message, 108, object.getY4());

        assertTrue(message, object.strokeIs(1.6f));
        assertTrue(message, object.dashIs(11.f));

        assertEquals(message, JaxoColor.PURPLE, object.getColor());

        assertTrue(message, object.isPaintArrow());
        assertFalse(message, object.isFlip());
        assertTrue(message, object.arrowPositionIs(0.7f));
        assertArrow(message, object.getArrow(), 15.f, 6.f, 0.2f);
    }
}
