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

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.arc.JaxoFArc;
import net.sf.jaxodraw.util.JaxoColor;
import net.sf.jaxodraw.util.JaxoConstants;
import net.sf.jaxodraw.util.JaxoPrefs;


/** Tests JaxoSLoop. */
public class JaxoSLoopTest extends AbstractJaxoLoopObjectTest {
    private JaxoSLoop loop = new JaxoSLoop();

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

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

    private void init() {
        loop.setLocation(69, 100);
        loop.setRelWAndH(-31, 40);
        loop.setColor(JaxoColor.RED);
        loop.setStrokeWidth(1.f);
        loop.setDash(10.f);
        loop.setPaintArrow(false);
        loop.setFlip(false);
        loop.setDoubleLine(false);
        loop.setDLSeparation(2.f);
    }

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

    /** Tests serialization. */
    public void testSerialization() {
        loop.setStrokeWidth(1.6f);
        loop.setDash(7.f);
        loop.setPaintArrow(true);
        loop.setFlip(true);
        loop.setDoubleLine(true);
        JaxoTestUtils.checkSerializedEquality(loop);
    }

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

        loop.setStrokeWidth(1.6f);
        loop.setDash(7.f);
        loop.setPaintArrow(true);
        loop.setFlip(true);
        loop.setDoubleLine(true);
        JaxoTestUtils.checkCopyEquality(loop);

        assertFalse(loop2.isCopy(loop));

        loop2.setStrokeWidth(1.6f);
        loop2.setDash(7.f);
        loop2.setPaintArrow(true);
        loop2.setFlip(true);
        loop2.setDoubleLine(true);
        assertTrue(loop2.isCopy(loop));

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

    }

    /** Tests identity. */
    public void testIdentity() {
        JaxoSLoop loop2 = loop;
        assertEquals(loop, loop2);
    }

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

        String expected = "\\Arc[dash,dashsize=10](69,1)(50.606,52,412)";
        String actual = loop.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        loop.setPaintArrow(true);
        expected = "\\Arc[dash,dashsize=10,arrow,arrowpos=0,arrowlength=5,arrowwidth=2,arrowinset=0.2](69,1)(50.606,52,412)";
        actual = loop.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        loop.setFlip(true);
        expected = "\\Arc[dash,dashsize=10,arrow,arrowpos=0,arrowlength=5,arrowwidth=2,arrowinset=0.2,flip](69,1)(50.606,52,412)";
        actual = loop.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        // reset to initial state
        loop.setPaintArrow(false);
        loop.setFlip(false);

        loop.setDoubleLine(true);
        loop.setDLSeparation(4.f);

        expected = "\\Arc[dash,dashsize=10,double,sep=4](69,1)(50.606,52,412)";
        actual = loop.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        loop.setRelWAndH(0, 0);
        expected = "%";
        actual = loop.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

    }

    /** Tests axodraw. */
    public void testAxodraw() {
        JaxoAxodraw axo = new JaxoAxodraw();
        JaxoObject ob = axo.getJaxoObject("\\SetWidth{1.0}");
        assertNull(ob);
        axo.checkRequired("\\begin{picture}(101,101) (49,-49)");
        String command;

        command = "\\DashCArc(100,1)(50.61,52,412){10}";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(false);

        command = "\\DashArrowArc(100,1)(50.61,52,412){10}";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(false);

        command = "\\DashArrowArcn(100,1)(50.61,412,52){10}";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(false);

        axo.checkRequired("\\begin{picture}(105,105) (47,-47)");

        command =
            "\\DashCArc(100,5)(52.61,52,412){11.0}\\DashCArc(100,5)(48.61,52,412){11.0}%%JaxoDrawID:DoubleLine(3)";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(true);

        axo.checkRequired("\\begin{picture}(107,107) (46,-46)");
        command =
            "\\DashArrowArc(100,7)(53.61,52,412){10.0}\\DashArrowArc(100,7)(47.61,52,412){10.0}%%JaxoDrawID:DoubleLine(3)";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(true);

        command =
            "\\DashArrowArcn(100,7)(53.61,412,52){10.0}\\DashArrowArcn(100,7)(47.61,412,52){10.0}%%JaxoDrawID:DoubleLine(3)";
        loop = (JaxoSLoop) axo.getJaxoObject(command);
        checkLoopParameters(true);

    }

    private void checkLoopParameters(boolean doubleLine) {
        assertEquals("SLoop doesn't have the right color!", JaxoColor.BLACK,
            loop.getColor());
        assertTrue("SLoop doesn't have the right stroke!", loop.strokeIs(1.f));
        assertTrue("SLoop doesn't have the right dash! Got:" + loop.getDash(),
            loop.dashIs(10.f));
        assertEquals("SLoop doesn't have the right x!", 100, loop.getX());
        assertEquals("SLoop doesn't have the right y!", 100, loop.getY());
        assertEquals("Mismatch in SLoop doubleLine!", doubleLine,
            loop.isDoubleLine());

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

        assertTrue("Mismatch in SLoop doubleLine separation!",
            loop.dlSepIs(dlsep));

    }

    /** Tests the getBounds() method. */
    public void testGetBounds() {
        Rectangle bBox = loop.getBounds();
        Rectangle expected = new Rectangle(17, 48, 104, 104);
        assertEquals("Bounding box not correct!", expected, bBox);

        loop.setPaintArrow(false);
        bBox = loop.getBounds();
        expected.setRect(17, 48, 104, 104);
        assertEquals("Arc Bounding box not correct!", expected, bBox);

        loop.setDoubleLine(true);
        bBox = loop.getBounds();
        expected.setRect(16, 47, 106, 106);
        assertEquals("DL Bounding box not correct!", expected, bBox);

        assertNotNull(loop.getBounds2D());
    }

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

        assertTrue("createNewObject did not return a SLoop!",
            (ob instanceof JaxoSLoop));

        loop = (JaxoSLoop) ob;
        assertEquals("SLoop doesn't have the right x!", 50, loop.getX());
        assertEquals("SLoop doesn't have the right y!", 50, loop.getY());
        assertEquals("SLoop doesn't have the right color!",
            JaxoColor.getColor(JaxoPrefs.getStringPref(JaxoPrefs.PREF_COLOR)),
            loop.getColor());
        assertTrue("SLoop doesn't have the right stroke!",
            loop.strokeIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH)));
        assertEquals("SLoop doesn't have the right arrow!",
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_ARROW), loop.isPaintArrow());
        assertEquals("SLoop doesn't have the right flip!", false,
            loop.isFlip());
        assertEquals("SLoop doesn't have the right double line!", false,
            loop.isDoubleLine());
        assertTrue("SLoop doesn't have the right dlsep!",
            loop.dlSepIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP)));
        assertTrue("SLoop doesn't have the right dash!", loop.dashIs(10.f));
    }

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

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

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

    private void check20Object(String message, JaxoSLoop object) {
        assertEquals(message, 221, object.getX());
        assertEquals(message, 143, object.getY());
        assertEquals(message, 30, (int) Math.round(object.getRadius()));

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

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

        assertFalse(message, object.isPaintArrow());
    }
}
