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

import java.awt.Rectangle;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import net.sf.jaxodraw.object.JaxoList;
import net.sf.jaxodraw.object.JaxoObject;
import net.sf.jaxodraw.object.JaxoObjectList;
import net.sf.jaxodraw.object.group.JaxoGroup;
import net.sf.jaxodraw.object.line.JaxoFLine;
import net.sf.jaxodraw.object.line.JaxoGLine;
import net.sf.jaxodraw.object.loop.JaxoFLoop;
import net.sf.jaxodraw.object.loop.JaxoGLoop;
import net.sf.jaxodraw.object.text.JaxoLatexText;
import net.sf.jaxodraw.object.text.JaxoPSText;
import net.sf.jaxodraw.object.vertex.JaxoVertexT1;

/** Tests JaxoGraph. */
public class JaxoGraphTest extends TestCase {
    private JaxoGraph instance;

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

    /**
     * {@inheritDoc}
     *
     * @throws Exception if any.
     */
    @Override
    protected void setUp() throws Exception {
        this.instance = new JaxoGraph();
    }

    /**
     * Test of constructors, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testConstructors() {
        assertNotNull(instance.getSaveGraph());
        assertEquals(instance.getSaveFileName(), "");
        JaxoList<JaxoObject> list = new JaxoObjectList<JaxoObject>(JaxoSaveGraph.LIST_INIT_SIZE);

        instance = new JaxoGraph(list);
        assertNotNull(instance.getSaveGraph());
        assertEquals(instance.getSaveFileName(), "");

        instance = new JaxoGraph(list, "describe");
        assertNotNull(instance.getSaveGraph());
        assertEquals(instance.getSaveFileName(), "");
        assertEquals(instance.getDescription(), "describe");

        instance = new JaxoGraph(list, "describe", "saveMeAs");
        assertNotNull(instance.getSaveGraph());
        assertEquals(instance.getSaveFileName(), "saveMeAs");
        assertEquals(instance.getDescription(), "describe");
    }

    /**
     * Test of get/setSaveGraph method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetSetSaveGraph() {
        JaxoSaveGraph expResult = new JaxoSaveGraph();
        instance.setSaveGraph(expResult);
        assertNotSame(expResult, instance.getSaveGraph());
        assertEquals(expResult.getDescription(), instance.getSaveGraph().getDescription());
        assertEquals(expResult.getObjectList(), instance.getSaveGraph().getObjectList());
        assertEquals(expResult.getPackageList(), instance.getSaveGraph().getPackageList());
    }


    /**
     * Test of get/setObjectList method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetSetObjectList() {
        JaxoList<JaxoObject> list = new JaxoObjectList<JaxoObject>(JaxoSaveGraph.LIST_INIT_SIZE);
        instance.setObjectList(list);
        assertNotSame(list, instance.getObjectList());
        assertEquals(list, instance.getObjectList());
    }

    /**
     * Test of get/setPackageList method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetSetPackageList() {
        List<String> list = new ArrayList<String>(JaxoSaveGraph.LIST_INIT_SIZE);
        list.add("axodraw4j");
        list.add("pstricks");
        list.add("color");
        instance.setPackageList(list);
        assertNotSame(list, instance.getPackageList());
        assertEquals(list, instance.getPackageList());
    }

    /**
     * Test of set/getDescription method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetSetDescription() {
        String describe = "description";
        instance.setDescription(describe);
        assertEquals(describe, instance.getDescription());
    }

    /**
     * Test of is/setSaved methods, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testIsSetSaved() {
        assertTrue(instance.isSaved());
        instance.setSaved(false);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of get/setSaveFileName method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetSetSaveFileName() {
        String fileName = "saveMeAs";
        instance.setSaveFileName(fileName);
        assertEquals(fileName, instance.getSaveFileName());
    }

    /**
     * Test of listElementAt method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testListElementAt() {
        assertNull(instance.listElementAt(0));
        JaxoObject ob = new JaxoVertexT1();
        instance.addObject(ob);
        JaxoObject result = instance.listElementAt(0);
        assertEquals(ob, result);
    }

    /**
     * Test of listSize method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testListSize() {
        assertEquals(0, instance.listSize());
        instance.addObject(new JaxoVertexT1());
        assertEquals(1, instance.listSize());
    }

    /**
     * Test of foreground method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testForeground() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();

        assertTrue(instance.isSaved());
        instance.addObject(line);
        instance.addObject(loop);
        assertFalse(instance.isSaved());

        instance.setSaved(true);
        instance.foreground(loop);
        assertTrue(instance.isSaved());
        instance.foreground(line);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of move method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testMove() {
        instance.addObject(new JaxoGLoop());
        instance.addObject(new JaxoFLine());
        instance.setSaved(true);
        instance.move(1, 1);
        assertTrue(instance.isSaved());
        instance.move(0, 1);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of replace method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testReplace() {
        JaxoGLoop loop = new JaxoGLoop();
        instance.addObject(loop);

        instance.setSaved(true);
        instance.replace(loop, loop);
        assertTrue(instance.isSaved());

        instance.replace(loop, new JaxoFLine());
        assertFalse(instance.isSaved());
        assertTrue(instance.listElementAt(0) instanceof JaxoFLine);

        instance.setSaved(true);
        instance.replace(loop, new JaxoFLine());
        assertTrue(instance.isSaved());

        try {
            instance.replace(instance.listElementAt(0), null);
            fail("Null inserted!");
        } catch (NullPointerException e) {
            // expected
            assertNotNull(e);
        }
    }

    /**
     * Test of background method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testBackground() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();

        assertTrue(instance.isSaved());
        instance.addObject(line);
        instance.addObject(loop);
        assertFalse(instance.isSaved());

        instance.setSaved(true);
        instance.background(line);
        assertTrue(instance.isSaved());
        instance.background(loop);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of delete method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testDelete() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();

        assertTrue(instance.isSaved());
        instance.addObject(line);
        instance.setSaved(true);
        instance.delete(loop);
        assertTrue(instance.isSaved());
        instance.delete(line);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of deleteMarkedObjects method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testDeleteMarkedObjects() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();

        instance.addObject(line);
        instance.addObject(loop);
        instance.setSaved(true);
        instance.deleteMarkedObjects();
        assertEquals(2, instance.listSize());
        assertTrue(instance.isSaved());
        line.setAsMarked(true);
        instance.deleteMarkedObjects();
        assertEquals(1, instance.listSize());
        assertFalse(instance.isSaved());
        assertTrue(instance.listElementAt(0) instanceof JaxoFLoop);
    }

    /**
     * Test of deleteAll method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testDeleteAll() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();
        JaxoList<JaxoObject> collection = new JaxoObjectList<JaxoObject>(2);
        collection.add(loop);

        assertTrue(instance.isSaved());
        instance.addObject(line);
        instance.setSaved(true);
        instance.deleteAll(collection);
        assertTrue(instance.isSaved());
        collection.add(line);
        instance.deleteAll(collection);
        assertFalse(instance.isSaved());
    }

    /**
     * Test of addObject method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testAddObject() {
        assertTrue(instance.isSaved());
        instance.addObject(null);
        assertTrue(instance.isSaved());
        instance.addObject(new JaxoFLine());
        assertFalse(instance.isSaved());

        instance.setSaved(true);
        instance.addObject(0, null);
        assertTrue(instance.isSaved());
        instance.addObject(0, new JaxoFLine());
        assertFalse(instance.isSaved());
    }

    /**
     * Test of clear method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testClear() {
        instance.addObject(new JaxoFLine());
        instance.setSaved(true);
        instance.clear();
        assertFalse(instance.isSaved());
        instance.setSaved(true);
        instance.clear();
        assertTrue(instance.isSaved());
    }

    /**
     * Test of clearAll method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testClearAll() {
        instance.setSaveFileName("saveMeAs");
        instance.setSaved(true);
        instance.clearAll();
        assertFalse(instance.isSaved());
        instance.setSaved(true);
        instance.clearAll();
        assertTrue(instance.isSaved());
    }

    /**
     * Test of getBounds method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetBounds() {
        Rectangle result = instance.getBounds();
        assertNull(result);
        instance.addObject(new JaxoFLine());
        result = instance.getBounds();
        assertNotNull(result);
    }

    /**
     * Test of getBoundsExcept method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetBoundsExcept() {
        JaxoFLine line = new JaxoFLine();
        line.setLocation(100, 100);
        line.setRelWAndH(100, 100);
        line.setStrokeWidth(1.f);
        line.setPaintArrow(false);

        JaxoFLine line2 = new JaxoFLine();
        line2.setLocation(110, 110, 220, 220);
        line2.setStrokeWidth(1.f);
        line2.setPaintArrow(false);

        instance.addObject(line);
        instance.addObject(line2);

        JaxoList<JaxoObject> except = new JaxoObjectList<JaxoObject>(1);
        except.add(line2);

        Rectangle expected = new Rectangle(99, 99, 102, 102);
        Rectangle result = instance.getBoundsExcept(except);
        assertEquals("A Bounding box not correct!", expected, result);

        except.remove(0);
        expected = new Rectangle(99, 99, 122, 122);
        result = instance.getBoundsExcept(except);
        assertEquals("B Bounding box not correct!", expected, result);
    }

    /**
     * Test of copyFrom method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testCopyFrom() {
        JaxoList<JaxoObject> collection = new JaxoObjectList<JaxoObject>(2);
        collection.add(new JaxoFLoop());
        JaxoList<JaxoObject> copy = JaxoGraph.copyFrom(collection);
        assertEquals(collection.size(), copy.size());
    }

    /**
     * Test of contains method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testContains() {
        JaxoFLine line = new JaxoFLine();
        instance.addObject(line);
        JaxoGroup group = new JaxoGroup();
        assertFalse(instance.containsGroups());
        instance.addObject(group);
        assertTrue(instance.containsGroups());

        assertFalse(instance.containsPSText());
        instance.addObject(new JaxoPSText());
        assertTrue(instance.containsPSText());

        assertFalse(instance.containsLatexText());
        instance.addObject(new JaxoLatexText());
        assertTrue(instance.containsLatexText());

        assertFalse(instance.containsMarkedObjects());
        line.setAsMarked(true);
        assertTrue(instance.containsMarkedObjects());

        assertFalse(instance.containsMarkedGroups());
        group.setAsMarked(true);
        assertTrue(instance.containsMarkedGroups());

        assertEquals(2, instance.getMarkedObjects().size());
        assertEquals(2, instance.getCopyOfMarkedObjects().size());

        assertTrue(instance.hasMoreMarkedObjectsThan(1));
        assertFalse(instance.hasMoreMarkedObjectsThan(2));

        instance.setAsMarked(true);
        assertTrue(instance.hasMoreMarkedObjectsThan(instance.listSize() - 1));
        assertFalse(instance.hasMoreMarkedObjectsThan(instance.listSize()));
        instance.setAsMarked(false);
        assertFalse(instance.hasMoreMarkedObjectsThan(0));

        line.setAsMarked(true);
        int size = instance.listSize() - 1;
        assertFalse(instance.listElementAt(size) instanceof JaxoFLine);
        instance.objectsToForeground();
        assertTrue(instance.listElementAt(size) instanceof JaxoFLine);
        assertFalse(instance.listElementAt(0) instanceof JaxoFLine);
        instance.objectsToBackground();
        assertTrue(instance.listElementAt(0) instanceof JaxoFLine);

        assertTrue(instance.containsGroups());
        instance.breakAllGroups();
        assertFalse(instance.containsGroups());
    }

    /**
     * Test of copyOf method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testCopyOf() {
        instance.setSaveFileName("saveMeAs");
        JaxoGraph copy = instance.copyOf();
        assertEquals("saveMeAs", copy.getSaveFileName());
    }

    /**
     * Test of getNearestObject method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGetNearestObject() {
        assertNull(instance.getNearestObject(10, 10));
        JaxoFLine line = new JaxoFLine();
        line.setLocation(0, 0, 10, 10);
        JaxoGLine gline = new JaxoGLine();
        gline.setLocation(80, 80, 100, 100);
        instance.addObject(line);
        instance.addObject(gline);
        assertTrue(instance.getNearestObject(20, 20) instanceof JaxoFLine);
        assertTrue(instance.getNearestObject(90, 50) instanceof JaxoGLine);
    }

    /**
     * Test of groupMarkedObjects method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testGroupMarkedObjects() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();

        instance.addObject(line);
        instance.addObject(loop);
        assertEquals(2, instance.listSize());

        assertFalse(instance.groupMarkedObjects());
        line.setAsMarked(true);
        assertFalse(instance.groupMarkedObjects());
        loop.setAsMarked(true);
        assertTrue(instance.groupMarkedObjects());
        assertEquals(1, instance.listSize());
    }

    /**
     * Test of ungroupMarkedObjects method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testUngroupMarkedObjects() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();
        JaxoGroup group = new JaxoGroup();

        JaxoList<JaxoObject> list = new JaxoObjectList<JaxoObject>(2);
        list.add(new JaxoFLoop());
        list.add(new JaxoFLoop());
        group.setObjectList(list);

        instance.addObject(group);
        instance.addObject(line);
        instance.addObject(loop);

        assertFalse(instance.ungroupMarkedObjects());
        line.setAsMarked(true);
        assertFalse(instance.ungroupMarkedObjects());
        group.setAsMarked(true);
        assertTrue(instance.ungroupMarkedObjects());

        assertEquals(4, instance.listSize());
    }

    /**
     * Test of ungroup method, of class net.sf.jaxodraw.graph.JaxoGraph.
     */
    public void testUngroupObject() {
        JaxoObject line = new JaxoFLine();
        JaxoObject loop = new JaxoFLoop();
        loop.setAsMarked(true);
        JaxoGroup group = new JaxoGroup();

        JaxoList<JaxoObject> list = new JaxoObjectList<JaxoObject>(2);
        list.add(loop);
        list.add(new JaxoFLoop());
        group.setObjectList(list);

        instance.addObject(group);
        instance.addObject(line);
        instance.addObject(loop);

        assertFalse(instance.ungroup(loop));
        assertFalse(instance.ungroup(new JaxoGroup()));
        assertTrue(instance.ungroup(group));

        assertEquals(4, instance.listSize());
        assertFalse(loop.isMarked());
    }

}
