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

import java.awt.Color;
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 JaxoBlob. */
public class JaxoBlobTest extends AbstractJaxoFillObjectTest {
    private JaxoBlob blob = new JaxoBlob();

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

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

    private void init() {
        blob.setLocation(100, 100);
        blob.setRelWAndH(100, 100);
        blob.setStrokeWidth(1.f);
        blob.setRotationAngle(0);
        blob.setColor(JaxoColor.GREEN);
        blob.setFillColor(JaxoColor.YELLOW);
    }

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

    /** Tests serialization. */
    public void testSerialization() {
        blob.setLocation(120, 130);
        blob.setRelWAndH(10, -100);
        blob.setStrokeWidth(5.f);
        blob.setRotationAngle(50);
        blob.setColor(JaxoColor.BROWN);
        blob.setFillColor(JaxoColor.RED);
        JaxoTestUtils.checkSerializedEquality(blob);
    }

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

        blob.setLocation(120, 130);
        blob.setRelWAndH(10, -100);
        blob.setStrokeWidth(5.f);
        blob.setRotationAngle(50);
        blob.setColor(JaxoColor.BROWN);
        blob.setFillColor(JaxoColor.RED);
        JaxoTestUtils.checkCopyEquality(blob);

        assertFalse(blob2.isCopy(blob));

        blob2.setLocation(120, 130);
        blob2.setRelWAndH(10, -100);
        blob2.setStrokeWidth(5.f);
        blob2.setRotationAngle(50);
        blob2.setColor(JaxoColor.BROWN);
        blob2.setFillColor(JaxoColor.RED);
        assertTrue(blob2.isCopy(blob));

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

    }

    /** Tests identity. */
    public void testIdentity() {
        JaxoBlob blob2 = blob;
        assertEquals(blob, blob2);
    }

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

        String expected = "\\COval(100,100)(100,100)(0){Green}{Yellow}";
        String actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setRelWAndH(-100, -100);
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setRelWAndH(100, -100);
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setRelWAndH(-100, 100);
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setRelWAndH(100, 100);
        blob.setColor(JaxoColor.BLACK);
        blob.setFillColor(JaxoColor.GRAYSCALE225);
        expected = "\\GOval(100,100)(100,100)(0){0.882}";
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setFilled(false);
        expected = "\\Oval(100,100)(100,100)(0)";
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);
        blob.setFilled(true);

        dim.setSize(224, 224);
        blob.setRotationAngle(50);
        expected = "\\GOval(100,124)(100,100)(-50){0.882}";
        actual = blob.latexCommand(1.f, dim);
        assertEquals("Latex commands do not match!", expected, actual);

        blob.setRelWAndH(0, 0);
        expected = "%";
        actual = blob.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 = "\\COval(100,100)(100,100)(-50){Green}{Yellow}";
        blob = (JaxoBlob) axo.getJaxoObject(command);
        checkBlobParameters(JaxoColor.GREEN, JaxoColor.YELLOW, 50);

        command = "\\GOval(100,100)(100,100)(0){0.882}";
        blob = (JaxoBlob) axo.getJaxoObject(command);
        checkBlobParameters(JaxoColor.BLACK, JaxoColor.GRAYSCALE225, 0);

        // test CCirc and GCirc commands (only used in imports)
        command = "\\CCirc(100,100){100}{Green}{Yellow}";
        blob = (JaxoBlob) axo.getJaxoObject(command);
        checkBlobParameters(JaxoColor.GREEN, JaxoColor.YELLOW, 0);

        command = "\\GCirc(100,100){100}{0.882}";
        blob = (JaxoBlob) axo.getJaxoObject(command);
        checkBlobParameters(JaxoColor.BLACK, JaxoColor.GRAYSCALE225, 0);

        command = "\\Oval(100,100)(100,100)(0)";
        blob = (JaxoBlob) axo.getJaxoObject(command);
        assertFalse("Blob should not be filled!", blob.isFilled());

    }

    private void checkBlobParameters(Color color, Color fillcolor, int angle) {
        assertEquals("Blob doesn't have the right color!", color,
            blob.getColor());
        assertEquals("Blob doesn't have the right fill color!", fillcolor,
            blob.getFillColor());
        assertTrue("Blob doesn't have the right stroke!",
            Math.abs(blob.getStrokeWidth() - 1.f) < 0.0001f);
        assertEquals("Blob doesn't have the right x!", 100, blob.getX());
        assertEquals("Blob doesn't have the right y!", -100, blob.getY());
        assertEquals("Blob doesn't have the right rotangle!", angle,
            blob.getRotationAngle());
    }

    /** Tests the getBounds() method. */
    public void testGetBounds() {
        Rectangle bBox = blob.getBounds();
        Rectangle expected = new Rectangle(-1, -1, 202, 202);
        assertEquals("Bounding box not correct!", expected, bBox);
        blob.setRotationAngle(45);
        blob.setFilled(false);
        bBox = blob.getBounds();
        expected.setRect(-11, -11, 222, 222);
        assertEquals("Blob Bounding box not correct!", expected, bBox);

        assertNotNull(blob.getBounds2D());
    }

    /** Tests getGrabbedHandle. */
    public void testGetGrabbedHandle() {
        blob.setRelWAndH(100, 100);
        checkHandle(200, 200, JaxoBlob.SELECT_P2);
        checkHandle(500, 500, JaxoBlob.SELECT_NONE);
        checkHandle(100, 100, JaxoBlob.SELECT_P1);

    }

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

        assertTrue("createNewObject did not return a Blob!",
            (ob instanceof JaxoBlob));

        blob = (JaxoBlob) ob;
        assertEquals("Blob doesn't have the right x!", 50, blob.getX());
        assertEquals("Blob doesn't have the right y!", 50, blob.getY());
        assertEquals("Blob doesn't have the right color!",
            JaxoColor.getColor(JaxoPrefs.getStringPref(JaxoPrefs.PREF_COLOR)),
            blob.getColor());
        assertEquals("Blob doesn't have the right fill color!",
            JaxoColor.GRAYSCALE225, blob.getFillColor());
        assertTrue("Blob doesn't have the right stroke!",
            blob.strokeIs(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH)));
        assertEquals("Blob doesn't have the right rotangle!", 0,
            blob.getRotationAngle());
    }

    /** Tests canBeSelected. */
    public void testCanBeSelected() {
        blob.setLocation(100, 100, 200, 200);

        int mode = JaxoConstants.MOVE;
        int handle = JaxoBlob.SELECT_P1;
        assertTrue("P1 in MOVE mode", blob.canBeSelected(handle, mode));
        handle = JaxoBlob.SELECT_P2;
        assertTrue("P2 in MOVE mode", blob.canBeSelected(handle, mode));

        mode = JaxoConstants.RESIZE;
        handle = JaxoBlob.SELECT_P1;
        assertFalse("P1 in RESIZE mode", blob.canBeSelected(handle, mode));
        handle = JaxoBlob.SELECT_P2;
        assertTrue("P2 in RESIZE mode", blob.canBeSelected(handle, mode));
    }

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

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

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

    private void check20Object(String message, JaxoBlob object) {

        assertEquals(message, 508, object.getX());
        assertEquals(message, 113, object.getY());
        assertEquals(message, 550, object.getX2());
        assertEquals(message, 127, object.getY2());

        assertTrue(message, object.strokeIs(1.4f));
        assertEquals(message, 5, object.getRotationAngle());

        assertEquals(message, JaxoColor.PINE_GREEN, object.getColor());
        assertEquals(message, JaxoColor.LAVENDER, object.getFillColor());
        assertTrue(message, object.isFilled());
    }

    /** {@inheritDoc} */
    public String[] serializableProperties() {
        return new String[] {
            "color", "fillColor", "filled", "pointCount",
            "points", "strokeWidth", "rotationAngle"
        }; // 7
    }
}
