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

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

import net.sf.jaxodraw.JaxoTestUtils;
import net.sf.jaxodraw.io.imports.JaxoAxodraw;
import net.sf.jaxodraw.object.JaxoObject;
import net.sf.jaxodraw.object.JaxoObjectFactory;
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 JaxoSArc. */
public class JaxoSArcTest extends AbstractJaxoArcObjectTest {
    private JaxoSArc arc = new JaxoSArc();

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

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

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

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

    /** Tests serialization. */
    public void testSerialization() {
        arc.setStrokeWidth(1.5f);
        arc.setDash(21.0f);
        arc.setPaintArrow(true);
        arc.setFlip(true);
        JaxoTestUtils.checkSerializedEquality(arc);
    }

    /** Tests that a copy of an object is still the same object. */
    public void testCopy() {
        JaxoSArc arc2 = new JaxoSArc();
        arc2.setState(arc);

        arc.setStrokeWidth(1.5f);
        arc.setDash(21.0f);
        arc.setPaintArrow(true);
        arc.setFlip(true);
        JaxoTestUtils.checkCopyEquality(arc);

        assertFalse(arc2.isCopy(arc));

        arc2.setStrokeWidth(1.5f);
        arc2.setDash(21.0f);
        arc2.setPaintArrow(true);
        arc2.setFlip(true);
        assertTrue(arc2.isCopy(arc));

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

    }

    /** Tests identity. */
    public void testIdentity() {
        JaxoSArc arc2 = arc;
        assertEquals(arc, arc2);
    }

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

        String expected = "\\Arc[dash,dashsize=10,clock](75,-12)(35.355,135,-45)";
        String actual = arc.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        arc.setPaintArrow(true);
        expected = "\\Arc[dash,dashsize=10,arrow,arrowpos=0.5,arrowlength=5,arrowwidth=2,arrowinset=0.2,clock](75,-12)(35.355,135,-45)";
        actual = arc.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        arc.setFlip(true);
        expected = "\\Arc[dash,dashsize=10,arrow,arrowpos=0.5,arrowlength=5,arrowwidth=2,arrowinset=0.2,flip,clock](75,-12)(35.355,135,-45)";
        actual = arc.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        arc.setPaintArrow(false);
        arc.setFlip(false);
        arc.setDoubleLine(true);
        arc.setDLSeparation(3.f);

        dim.setSize(69, 69);
        expected = "\\Arc[dash,dashsize=10,double,sep=3,clock](75,-6)(35.355,135,-45)";
        actual = arc.latexCommand(1.f, dim);
        assertEquals("Latex double line commands do not match!", expected,
            actual);

    }

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

        command = "\\DashCArc(75,-12)(35.36,-45,135){10}";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(false);

        command = "\\DashArrowArc(75,-12)(35.36,-45,135){10}";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(false);
        assertTrue("SArc doesn't have the right arrow!", arc.isPaintArrow());

        command = "\\DashArrowArcn(75,-12)(35.36,135,-45){10}";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(false);
        assertTrue("SArc doesn't have the right arrow!", arc.isPaintArrow());
        assertTrue("SArc doesn't have the right flip!", arc.isFlip());

        command =
            "\\DashCArc(75,-6)(38.36,-45,135){11.0}\\DashCArc(75,-6)(32.36,-45,135){11.0}%%JaxoDrawID:DoubleLine(3)";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(true);

        command =
            "\\DashArrowArc(75,-6)(38.36,-45,135){10.0}\\DashArrowArc(75,-6)(32.36,-45,135){10.0}%%JaxoDrawID:DoubleLine(3)";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(true);
        assertTrue("SArc doesn't have the right arrow!", arc.isPaintArrow());

        command =
            "\\DashArrowArcn(75,-6)(38.36,135,-45){10.0}\\DashArrowArcn(75,-6)(32.36,135,-45){10.0}%%JaxoDrawID:DoubleLine(3)";
        arc = (JaxoSArc) axo.getJaxoObject(command);
        checkArcParameters(true);
        assertTrue("SArc doesn't have the right arrow!", arc.isPaintArrow());
        assertTrue("SArc doesn't have the right flip!", arc.isFlip());

    }

    private void checkArcParameters(boolean doubleLine) {
        assertEquals("SArc doesn't have the right color!", JaxoColor.BLACK,
            arc.getColor());
        assertTrue("SArc doesn't have the right stroke!", arc.strokeIs(1.f));
        assertEquals("Mismatch in SArc doubleLine!", doubleLine,
            arc.isDoubleLine());

        float dlsep = 2.f;
        if (doubleLine) {
            dlsep = 3.f;
        }

        assertTrue("Mismatch in SArc doubleLine separation! Got: "
            + arc.getDLSeparation(), arc.dlSepIs(dlsep));
        assertTrue("Mismatch in SArc dash! Got: " + arc.getDash(),
            arc.dashIs(10.f));

    }

    /** Tests the getBounds() method. */
    public void testGetBounds() {
        Rectangle bBox = arc.getBounds();
        Rectangle expected = new Rectangle(49, 39, 62, 61);
        assertEquals("Bounding box not correct!", expected, bBox);

        arc.setLocation(50, 50, 100, 100, 150, 50);
        arc.setPaintArrow(true);
        bBox = arc.getBounds();
        expected.setRect(49, 49, 102, 54);
        assertEquals("Arc Bounding box not correct!", expected, bBox);

        arc.setDoubleLine(true);
        bBox = arc.getBounds();
        expected.setRect(48, 49, 104, 54);
        assertEquals("DL Bounding box not correct!", expected, bBox);

        assertNotNull(arc.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);
        JaxoObject ob =
            JaxoObjectFactory.newObject(JaxoConstants.SARC, new Point[] {p, q, r});

        assertTrue("createNewObject did not return a SArc!",
            (ob instanceof JaxoSArc));

        arc = (JaxoSArc) ob;
        assertEquals("SArc doesn't have the right x1!", 50, arc.getX());
        assertEquals("SArc doesn't have the right y1!", 50, arc.getY());
        assertEquals("SArc doesn't have the right x2!", 100, arc.getX2());
        assertEquals("SArc doesn't have the right y2!", 50, arc.getY2());
        assertEquals("SArc doesn't have the right x3!", 100, arc.getX3());
        assertEquals("SArc doesn't have the right y3!", 100, arc.getY3());
        assertEquals("SArc doesn't have the right color!",
            JaxoColor.getColor(JaxoPrefs.getStringPref(JaxoPrefs.PREF_COLOR)),
            arc.getColor());
        assertTrue("SArc doesn't have the right stroke!",
            arc.strokeIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH)));
        assertEquals("SArc doesn't have the right arrow!",
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_ARROW), arc.isPaintArrow());
        assertEquals("SArc doesn't have the right flip!", false, arc.isFlip());
        assertEquals("SArc doesn't have the right double line!", false,
            arc.isDoubleLine());
        assertTrue("SArc doesn't have the right dlsep!",
            arc.dlSepIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP)));
        assertTrue("SArc doesn't have the right dash!", arc.dashIs(10.f));

    }
    /** {@inheritDoc} */
    public String className() {
        return "JaxoSArc";
    }

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

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

    private void check20Object(String message, JaxoSArc object) {

        assertEquals(message, 385, object.getX());
        assertEquals(message, 161, object.getY());
        assertEquals(message, 368, object.getX2());
        assertEquals(message, 102, object.getY2());
        assertEquals(message, 309, object.getX3());
        assertEquals(message, 119, object.getY3());

        assertTrue(message, object.strokeIs(0.6f));
        assertTrue(message, object.dashIs(9.996f));

        assertFalse(message, object.isDoubleLine());

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

        assertTrue(message, object.isPaintArrow());
        assertTrue(message, object.isFlip());
        assertArrow(message, object.getArrow(), 5.f, 2.f, 0.2f);
    }
}
