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

import java.awt.Font;
import java.awt.Rectangle;

import net.sf.jaxodraw.AbstractJaxoBaseTest;
import net.sf.jaxodraw.JaxoTestUtils;
import net.sf.jaxodraw.graph.JaxoGraph;
import net.sf.jaxodraw.gui.handle.JaxoDefaultHandle;
import net.sf.jaxodraw.io.JaxoIO;
import net.sf.jaxodraw.object.JaxoExtendedObject;
import net.sf.jaxodraw.object.JaxoFillColorObject;
import net.sf.jaxodraw.object.JaxoList;
import net.sf.jaxodraw.object.JaxoHandle;
import net.sf.jaxodraw.object.JaxoObject;
import net.sf.jaxodraw.object.JaxoObjectList;
import net.sf.jaxodraw.object.JaxoWiggleObject;
import net.sf.jaxodraw.object.text.JaxoLatexText;
import net.sf.jaxodraw.object.text.JaxoPSText;
import net.sf.jaxodraw.util.JaxoColor;
import net.sf.jaxodraw.util.JaxoGeometry;


/**
 * Tests for JaxoGroup.
 */
public class JaxoGroupTest extends AbstractJaxoBaseTest {
    private final JaxoGroup initGroup = new JaxoGroup();
    private JaxoGroup testGroup;

    /** Constructor: calls super() and initialize a group.
     * @param testName The name of this test.
     */
    public JaxoGroupTest(String testName) {
        super(testName);
        init();
    }

    /**
     * Initialize the test group.
     *
     * @throws Exception if any.
     */
    @Override
    protected void setUp() throws Exception {
        testGroup = (JaxoGroup) initGroup.copy();
    }

    /** Tests serialization. */
    public void testSerialization() {
        JaxoTestUtils.checkSerializedEquality(testGroup);
    }

    /**
     * Test of copy method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testCopy() {
        JaxoGroup group2 = new JaxoGroup();
        group2.setState(testGroup);

        testGroup.setAmp(12);
        testGroup.setLatexTextSize(13);
        testGroup.setStrokeWidth(0.2f);
        JaxoTestUtils.checkCopyEquality(testGroup);

        assertFalse(group2.isCopy(testGroup));

        group2.setAmp(12);
        group2.setLatexTextSize(13);
        group2.setStrokeWidth(0.2f);
        assertTrue(group2.isCopy(testGroup));
    }

    /**
     * Test of getGrabbedHandle method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetGrabbedHandle() {
        JaxoHandle h = new JaxoDefaultHandle();
        Rectangle bBox = testGroup.getBounds();

        int expResult = JaxoGroup.SELECT_P1;
        int result = testGroup.getGrabbedHandle(bBox.x, bBox.y, h);
        expResult = JaxoGroup.SELECT_DY;
        result = testGroup.getGrabbedHandle(bBox.x + bBox.width, bBox.y, h);
        assertEquals(expResult, result);
        expResult = JaxoGroup.SELECT_P2;
        result =
            testGroup.getGrabbedHandle(bBox.x + bBox.width,
                bBox.y + bBox.height, h);
        assertEquals(expResult, result);
        expResult = JaxoGroup.SELECT_DX;
        result = testGroup.getGrabbedHandle(bBox.x, bBox.y + bBox.height, h);
        assertEquals(expResult, result);
        expResult = JaxoGroup.SELECT_NONE;
        result =
            testGroup.getGrabbedHandle(bBox.x, (bBox.y + bBox.height) * 3, h);
        assertEquals(expResult, result);
    }

    /**
     * Test of canBeSelected method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testCanBeSelected() {
        int handle = JaxoGroup.SELECT_P1;
        int mode = 123;
        assertTrue(testGroup.canBeSelected(handle, mode));
        handle = JaxoGroup.SELECT_P2;
        assertTrue(testGroup.canBeSelected(handle, mode));
        handle = JaxoGroup.SELECT_DX;
        assertTrue(testGroup.canBeSelected(handle, mode));
        handle = JaxoGroup.SELECT_DY;
        assertTrue(testGroup.canBeSelected(handle, mode));
    }

    /**
     * Test of smallestDistanceTo method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSmallestDistanceTo() {
        float result =
            testGroup.smallestDistanceTo(testGroup.getBounds().x,
                testGroup.getBounds().y);
        assertEquals("was: " + result, result, 0.f);
    }

    /**
     * Test of moveBy method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testMoveBy() {
        testGroup.moveBy(10, 10);

        assertEquals(testGroup.getX() - 10, initGroup.getX());
        assertEquals(testGroup.getY() - 10, initGroup.getY());
        assertEquals(testGroup.getBounds().width, initGroup.getBounds().width);
        assertEquals(testGroup.getBounds().height, initGroup.getBounds().height);
    }

    /**
     * Test of latexCommand method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testLatexCommand() {
        String expResult = "%";
        String result = testGroup.latexCommand(0.0f, null);
        assertEquals("Wrong LaTeX command!", expResult, result);
    }

    /**
     * Test of latexWidth method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testLatexWidth() {
        String expResult = "%";
        String result = testGroup.latexWidth();
        assertEquals("Wrong LaTeX width!", expResult, result);
    }

    /**
     * Test of getBounds method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetBounds() {
        Rectangle result = testGroup.getBounds();
        Rectangle expected = new Rectangle(29, 26, 720, 502);
        assertEquals("Bounding box not correct!", expected, result);

        assertNotNull(testGroup.getBounds2D());
    }

    /**
     * Test of clearGroup method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testClearGroup() {
        testGroup.clearGroup();
        assertTrue("Grouplist not empty!", testGroup.getObjectList().size() == 0);
    }

    /**
     * Test of getObList method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetObList() {
        JaxoList<JaxoObject> result = testGroup.getObjectList();
        assertEquals(31, result.size());
    }

    /**
     * Test of setObList method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetObList() {
        JaxoList<JaxoObject> obList = new JaxoObjectList<JaxoObject>();
        testGroup.setObjectList(obList);
        assertEquals(0, testGroup.getObjectList().size());
    }

    /**
     * Test of groupObListSize method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGroupObListSize() {
        int result = testGroup.size();
        assertEquals(31, result);
    }

    /**
     * Test of rescaleObject method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testRescaleObject() {
        testGroup.rescaleObject(0, 0, 2.f);

        assertEquals(57, testGroup.getX());
        assertEquals(53, testGroup.getY());
        assertEquals(1008, testGroup.getBounds().height);
        assertEquals(1437, testGroup.getBounds().width);
    }

    /**
     * Test of setStrokeWidth method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetStrokeWidth() {
        testGroup.setStrokeWidth(2.33f);
        for (int i = 0; i < this.testGroup.size(); i++) {
            JaxoObject ob = testGroup.getObjectList().get(i);
            if (ob instanceof JaxoExtendedObject) {
                assertEquals(2.33f,
                        ((JaxoExtendedObject) ob).getStrokeWidth());
            }
        }
    }

    /**
     * Test of getAmp method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetAmp() {
        int result = testGroup.getAmp();
        assertEquals(0, result);
    }

    /**
     * Test of setAmp method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetAmp() {
        testGroup.setAmp(22);
        assertEquals(testGroup.getAmp(), 22);
    }

    /**
     * Test of getTeXSize method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetTeXSize() {
        int result = testGroup.getLatexTextSize();
        assertEquals(0, result);
    }

    /**
     * Test of setTeXSize method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetTeXSize() {
        testGroup.setLatexTextSize(12);
        assertEquals(12, testGroup.getLatexTextSize());
    }

    /**
     * Test of getTextFont method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testGetTextFont() {
        assertNull(testGroup.getFont());
    }

    /**
     * Test of setTextFont method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetTextFont() {
        Font testFont = new Font("Default", 12, 8);
        testGroup.setFont(testFont);
        assertNotNull(testGroup.getFont());
        for (int i = 0; i < this.testGroup.size(); i++) {
            JaxoObject ob = testGroup.getObjectList().get(i);
            if (ob instanceof JaxoPSText) {
                assertEquals(testFont, ((JaxoPSText) ob).getFont());
            }
        }
    }

    /**
     * Test of setColor method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testSetGroupColor() {
        testGroup.setColor(JaxoColor.RED);
        assertEquals(JaxoColor.RED, testGroup.getColor());
        for (int i = 0; i < this.testGroup.size(); i++) {
            JaxoObject ob = testGroup.getObjectList().get(i);
            if (!(
                        (ob instanceof JaxoLatexText)
                        || (ob instanceof JaxoFillColorObject)
                    )) {
                assertEquals(JaxoColor.RED, ob.getColor());
            }
        }
    }

    /**
     * Test of containsWiggleObjects method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testContainsWiggleObjects() {
        assertTrue(testGroup.containsInstanceOf(JaxoWiggleObject.class));
    }

    /**
     * Test of containsLatexTexts method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testContainsLatexTexts() {
        assertTrue(testGroup.containsInstanceOf(JaxoLatexText.class));
    }

    /**
     * Test of containsPSTexts method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testContainsPSTexts() {
        assertTrue(testGroup.containsInstanceOf(JaxoPSText.class));
    }

    /**
     * Test of containsExtendedObjects method, of class net.sf.jaxodraw.object.group.JaxoGroup.
     */
    public void testContainsExtendedObjects() {
        assertTrue(testGroup.containsInstanceOf(JaxoExtendedObject.class));
    }

    private void init() {
        JaxoList<JaxoObject> groupObjects = groupObjects();
        Rectangle groupBounds = JaxoGeometry.getBounds(groupObjects);
        initGroup.setObjectList(groupObjects);
        initGroup.setX(groupBounds.x);
        initGroup.setY(groupBounds.y);
        initGroup.setX2(groupBounds.x + groupBounds.width);
        initGroup.setY2(groupBounds.y + groupBounds.height);
    }

    private JaxoList<JaxoObject> groupObjects() {
        JaxoIO io = new JaxoIO(null);
        JaxoGraph testGraph = io.open(getResourceFile("io/", "all-2.0.xml"), false);
        return testGraph.getObjectList();
    }
}
