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

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 JaxoZigZagLine. */
public class JaxoZigZagLineTest extends AbstractJaxoLineObjectTest {
    private JaxoZigZagLine line = new JaxoZigZagLine();

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

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

    private void init() {
        line.setLocation(100, 100);
        line.setRelWAndH(100, 100);
        line.setStrokeWidth(1.f);
        line.setColor(JaxoColor.GREEN);
        line.setAmp(15);
        line.setWiggles(14);
        line.setDoubleLine(false);
        line.setDLSeparation(2.f);
    }

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

    /** Tests serialization. */
    public void testSerialization() {
        line.setAmp(20);
        line.setDoubleLine(true);
        line.setDLSeparation(4.f);
        JaxoTestUtils.checkSerializedEquality(line);
    }

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

        line.setAmp(20);
        line.setDoubleLine(true);
        line.setDLSeparation(4.f);
        JaxoTestUtils.checkCopyEquality(line);

        assertFalse(line2.isCopy(line));

        line2.setAmp(20);
        line2.setDoubleLine(true);
        line2.setDLSeparation(4.f);
        assertTrue(line2.isCopy(line));

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

    }

    /** Tests identity. */
    public void testIdentity() {
        JaxoZigZagLine line2 = line;
        assertEquals(line, line2);
    }

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

        String expected = "\\ZigZag(100,6)(200,-94){7.5}{14}";
        String actual = line.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        dim.setSize(103, 103);
        line.setSymmetric(true);
        expected = "\\ZigZag(100,3)(200,-97){7.5}{14.5}";
        actual = line.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        line.setRelWAndH(-100, -100);
        expected = "\\ZigZag(100,3)(0,103){7.5}{14.5}";
        actual = line.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

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

        expected =
            "\\ZigZag(97.172,0.172)(-2.828,100.172){7.5}{14.5}\\ZigZag(102.828,5.828)(2.828,105.828){7.5}{14.5}%%JaxoDrawID:DoubleLine(4)";
        actual = line.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        line.setRelWAndH(0, 0);
        expected = "%";
        actual = line.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);
        String command;

        command = "\\ZigZag(200,-100)(100,0){7.5}{7.5}";
        line = (JaxoZigZagLine) axo.getJaxoObject(command);
        checkLineParameters(line, false);

        command =
            "\\ZigZag(102.12,-185.88)(202.12,-285.88){7.5}{7.5}\\ZigZag(97.88,-190.12)(197.88,-290.12){7.5}{7.5}%%JaxoDrawID:DoubleLine(3)";
        line = (JaxoZigZagLine) axo.getJaxoObject(command);
        checkLineParameters(line, true);

    }

    private void checkLineParameters(JaxoZigZagLine aline, boolean doubleLine) {
        assertEquals("ZigZagLine doesn't have the right color!",
            JaxoColor.BLACK, aline.getColor());
        assertTrue("ZigZagLine doesn't have the right stroke!",
            aline.strokeIs(1.f));
        assertEquals("ZigZagLine doesn't have the right amp!", 15,
            aline.getAmp());
        assertEquals("Mismatch in ZigZagLine doubleLine!", doubleLine,
            aline.isDoubleLine());

        float dlsep = 2.f;
        int x = 200;
        int y = 100;
        if (doubleLine) {
            dlsep = 3.f;
            x = 100;
            y = 188;
        }

        assertEquals("ZigZagLine doesn't have the right x!", x, aline.getX());
        assertEquals("ZigZagLine doesn't have the right y!", y, aline.getY());
        assertTrue("Mismatch in ZigZagLine doubleLine separation!",
            aline.dlSepIs(dlsep));

    }

    /** Tests the getBounds() method. */
    public void testGetBounds() {
        Rectangle bBox = line.getBounds();
        Rectangle expected = new Rectangle(96, 93, 108, 114);
        assertEquals("Bounding box not correct!", expected, bBox);
        line.setDoubleLine(true);
        bBox = line.getBounds();
        expected.setRect(96, 92, 108, 116);
        assertEquals("DL Bounding box not correct!", expected, bBox);

        assertNotNull(line.getBounds2D());
    }

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

        assertTrue("createNewObject did not return a ZigZagLine!",
            (ob instanceof JaxoZigZagLine));

        line = (JaxoZigZagLine) ob;
        assertEquals("ZigZagLine doesn't have the right x!", 50, line.getX());
        assertEquals("ZigZagLine doesn't have the right y!", 50, line.getY());
        assertEquals("ZigZagLine doesn't have the right color!",
            JaxoColor.getColor(JaxoPrefs.getStringPref(JaxoPrefs.PREF_COLOR)),
            line.getColor());
        assertTrue("ZigZagLine doesn't have the right stroke!",
            line.strokeIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH)));
        assertEquals("ZigZagLine doesn't have the right double line!", false,
            line.isDoubleLine());
        assertTrue("ZigZagLine doesn't have the right dlsep!",
            line.dlSepIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP)));
        assertEquals("ZigZagLine doesn't have the right amplitude!",
            JaxoPrefs.getIntPref(JaxoPrefs.PREF_AMPLITUDE), line.getAmp());
    }

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


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

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

    private void check20Object(String message, JaxoZigZagLine object) {

        assertEquals(message, 33, object.getX());
        assertEquals(message, 467, object.getY());
        assertEquals(message, 108, object.getX2());
        assertEquals(message, 522, object.getY2());

        assertFalse(message, object.isDoubleLine());
        assertTrue(message, object.strokeIs(1.4f));

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

        assertEquals(message, 17, object.getAmp());
        assertEquals(message, 7, object.getWiggles());
        assertTrue(message, object.isSymmetric());
    }

    /** {@inheritDoc} */
    @Override
    public String[] serializableProperties() {
        return new String[] {
            "DLSeparation", "amp", "arrow", "arrowPosition", "color",
            "dash", "doubleLine", "flip", "paintArrow", "pointCount",
            "points", "strokeWidth", "wiggles", "symmetric"
        }; // 14
    }
}
