/* ===========================================================

 * JFreeChart : a free chart library for the Java(tm) platform

 * ===========================================================

 *

 * (C) Copyright 2000-2004, by Object Refinery Limited and Contributors.

 *

 * Project Info:  http://www.jfree.org/jfreechart/index.html

 *

 * This library is free software; you can redistribute it and/or modify it under the terms

 * of the GNU Lesser General Public License as published by the Free Software Foundation;

 * either version 2.1 of the License, or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;

 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 * See the GNU Lesser General Public License for more details.

 *

 * You should have received a copy of the GNU Lesser General Public License along with this

 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,

 * Boston, MA 02111-1307, USA.

 *

 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 

 * in the United States and other countries.]

 *

 * ----------------

 * XYPlotTests.java

 * ----------------

 * (C) Copyright 2003, 2004, by Object Refinery Limited and Contributors.

 *

 * Original Author:  David Gilbert (for Object Refinery Limited);

 * Contributor(s):   -;

 *

 * $Id: XYPlotTests.java,v 1.1 2004/08/31 14:42:21 mungady Exp $

 *

 * Changes

 * -------

 * 26-Mar-2003 : Version 1 (DG);

 * 22-Mar-2004 : Added new cloning test (DG);

 *

 */



package org.jfree.chart.plot.junit;



import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Stroke;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.ObjectInput;

import java.io.ObjectInputStream;

import java.io.ObjectOutput;

import java.io.ObjectOutputStream;



import junit.framework.Test;

import junit.framework.TestCase;

import junit.framework.TestSuite;



import org.jfree.chart.ChartFactory;

import org.jfree.chart.JFreeChart;

import org.jfree.chart.axis.AxisLocation;

import org.jfree.chart.axis.DateAxis;

import org.jfree.chart.axis.NumberAxis;

import org.jfree.chart.labels.StandardXYToolTipGenerator;

import org.jfree.chart.plot.PlotOrientation;

import org.jfree.chart.plot.ValueMarker;

import org.jfree.chart.plot.XYPlot;

import org.jfree.chart.renderer.xy.DefaultXYItemRenderer;

import org.jfree.chart.renderer.xy.StandardXYItemRenderer;

import org.jfree.chart.renderer.xy.XYBarRenderer;

import org.jfree.chart.renderer.xy.XYItemRenderer;

import org.jfree.data.time.Day;

import org.jfree.data.time.TimeSeries;

import org.jfree.data.time.TimeSeriesCollection;

import org.jfree.data.xy.IntervalXYDataset;

import org.jfree.data.xy.XYDataset;

import org.jfree.data.xy.XYSeriesCollection;

import org.jfree.date.SerialDate;

import org.jfree.ui.Layer;

import org.jfree.ui.Spacer;



/**

 * Tests for the {@link XYPlot} class.

 */

public class XYPlotTests extends TestCase {



    /**

     * Returns the tests as a test suite.

     *

     * @return The test suite.

     */

    public static Test suite() {

        return new TestSuite(XYPlotTests.class);

    }



    /**

     * Constructs a new set of tests.

     *

     * @param name  the name of the tests.

     */

    public XYPlotTests(String name) {

        super(name);

    }

    

    /**

     * Added this test in response to a bug report.

     */

    public void testGetDatasetCount() {

        XYPlot plot = new XYPlot();

        assertEquals(0, plot.getDatasetCount());

    }



    /**

     * Test the equals() method.

     */

    public void testEquals() {

        

        XYPlot plot1 = new XYPlot();

        XYPlot plot2 = new XYPlot();

        assertTrue(plot1.equals(plot2));    

        

        // orientation...

        plot1.setOrientation(PlotOrientation.HORIZONTAL);

        assertFalse(plot1.equals(plot2));

        plot2.setOrientation(PlotOrientation.HORIZONTAL);

        assertTrue(plot1.equals(plot2));

        

        // axisOffset...

        plot1.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 0.05, 0.05, 0.05, 0.05));

        assertFalse(plot1.equals(plot2));

        plot2.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 0.05, 0.05, 0.05, 0.05));

        assertTrue(plot1.equals(plot2));



        // domainAxis...

        plot1.setDomainAxis(new NumberAxis("Domain Axis"));

        assertFalse(plot1.equals(plot2));

        plot2.setDomainAxis(new NumberAxis("Domain Axis"));

        assertTrue(plot1.equals(plot2));



        // domainAxisLocation...

        plot1.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);

        assertFalse(plot1.equals(plot2));

        plot2.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);

        assertTrue(plot1.equals(plot2));



        // secondaryDomainAxes...

        plot1.setDomainAxis(11, new NumberAxis("Secondary Domain Axis"));

        assertFalse(plot1.equals(plot2));

        plot2.setDomainAxis(11, new NumberAxis("Secondary Domain Axis"));

        assertTrue(plot1.equals(plot2));



        // secondaryDomainAxisLocations...

        plot1.setDomainAxisLocation(11, AxisLocation.TOP_OR_RIGHT);

        assertFalse(plot1.equals(plot2));

        plot2.setDomainAxisLocation(11, AxisLocation.TOP_OR_RIGHT);

        assertTrue(plot1.equals(plot2));



        // rangeAxis...

        plot1.setRangeAxis(new NumberAxis("Range Axis"));

        assertFalse(plot1.equals(plot2));

        plot2.setRangeAxis(new NumberAxis("Range Axis"));

        assertTrue(plot1.equals(plot2));



        // rangeAxisLocation...

        plot1.setRangeAxisLocation(AxisLocation.TOP_OR_RIGHT);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeAxisLocation(AxisLocation.TOP_OR_RIGHT);

        assertTrue(plot1.equals(plot2));



        // secondaryRangeAxes...

        plot1.setRangeAxis(11, new NumberAxis("Secondary Range Axis"));

        assertFalse(plot1.equals(plot2));

        plot2.setRangeAxis(11, new NumberAxis("Secondary Range Axis"));

        assertTrue(plot1.equals(plot2));



        // secondaryRangeAxisLocations...

        plot1.setRangeAxisLocation(11, AxisLocation.TOP_OR_RIGHT);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeAxisLocation(11, AxisLocation.TOP_OR_RIGHT);

        assertTrue(plot1.equals(plot2));

        

        // secondaryDatasetDomainAxisMap...

        plot1.mapDatasetToDomainAxis(11, 11);

        assertFalse(plot1.equals(plot2));

        plot2.mapDatasetToDomainAxis(11, 11);

        assertTrue(plot1.equals(plot2));



        // secondaryDatasetRangeAxisMap...

        plot1.mapDatasetToRangeAxis(11, 11);

        assertFalse(plot1.equals(plot2));

        plot2.mapDatasetToRangeAxis(11, 11);

        assertTrue(plot1.equals(plot2));

        

        // renderer

        plot1.setRenderer(new DefaultXYItemRenderer());

        assertFalse(plot1.equals(plot2));

        plot2.setRenderer(new DefaultXYItemRenderer());

        assertTrue(plot1.equals(plot2));

        

        // secondary renderers

        plot1.setRenderer(11, new DefaultXYItemRenderer());

        assertFalse(plot1.equals(plot2));

        plot2.setRenderer(11, new DefaultXYItemRenderer());

        assertTrue(plot1.equals(plot2));

        

        // domainGridlinesVisible

        plot1.setDomainGridlinesVisible(false);

        assertFalse(plot1.equals(plot2));

        plot2.setDomainGridlinesVisible(false);

        assertTrue(plot1.equals(plot2));



        // domainGridlineStroke

        Stroke stroke = new BasicStroke(2.0f);

        plot1.setDomainGridlineStroke(stroke);

        assertFalse(plot1.equals(plot2));

        plot2.setDomainGridlineStroke(stroke);

        assertTrue(plot1.equals(plot2));

        

        // domainGridlinePaint

        plot1.setDomainGridlinePaint(Color.blue);

        assertFalse(plot1.equals(plot2));

        plot2.setDomainGridlinePaint(Color.blue);

        assertTrue(plot1.equals(plot2));

        

        // rangeGridlinesVisible

        plot1.setRangeGridlinesVisible(false);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeGridlinesVisible(false);

        assertTrue(plot1.equals(plot2));



        // rangeGridlineStroke

        plot1.setRangeGridlineStroke(stroke);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeGridlineStroke(stroke);

        assertTrue(plot1.equals(plot2));

        

        // rangeGridlinePaint

        plot1.setRangeGridlinePaint(Color.blue);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeGridlinePaint(Color.blue);

        assertTrue(plot1.equals(plot2));

                

        // rangeCrosshairVisible

        plot1.setRangeCrosshairVisible(true);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeCrosshairVisible(true);

        assertTrue(plot1.equals(plot2));

        

        // rangeCrosshairValue

        plot1.setRangeCrosshairValue(100.0);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeCrosshairValue(100.0);

        assertTrue(plot1.equals(plot2));

        

        // rangeCrosshairStroke

        plot1.setRangeCrosshairStroke(stroke);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeCrosshairStroke(stroke);

        assertTrue(plot1.equals(plot2));

        

        // rangeCrosshairPaint

        plot1.setRangeCrosshairPaint(Color.red);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeCrosshairPaint(Color.red);

        assertTrue(plot1.equals(plot2));

        

        // rangeCrosshairLockedOnData

        plot1.setRangeCrosshairLockedOnData(false);

        assertFalse(plot1.equals(plot2));

        plot2.setRangeCrosshairLockedOnData(false);

        assertTrue(plot1.equals(plot2));

        

        // range markers

        plot1.addRangeMarker(new ValueMarker(4.0));

        assertFalse(plot1.equals(plot2));

        plot2.addRangeMarker(new ValueMarker(4.0));

        assertTrue(plot1.equals(plot2));

        

        // secondary range markers

        plot1.addRangeMarker(1, new ValueMarker(4.0), Layer.FOREGROUND);

        assertFalse(plot1.equals(plot2));

        plot2.addRangeMarker(1, new ValueMarker(4.0), Layer.FOREGROUND);

        assertTrue(plot1.equals(plot2));

                

        // weight

        plot1.setWeight(3);

        assertFalse(plot1.equals(plot2));

        plot2.setWeight(3);

        assertTrue(plot1.equals(plot2));

        

    }



    /**

     * Confirm that basic cloning works.

     */

    public void testCloning() {

        XYPlot p1 = new XYPlot();

        XYPlot p2 = null;

        try {

            p2 = (XYPlot) p1.clone();

        }

        catch (CloneNotSupportedException e) {

            e.printStackTrace();

            System.err.println("XYPlotTests.testCloning: failed to clone.");

        }

        assertTrue(p1 != p2);

        assertTrue(p1.getClass() == p2.getClass());

        assertTrue(p1.equals(p2));

    }

    

    /**

     * Tests cloning for a more complex plot.

     */

    public void testCloning2() {

        XYPlot p1 = new XYPlot(

            null, new NumberAxis("Domain Axis"), new NumberAxis("Range Axis"),

            new StandardXYItemRenderer()

        );   

        p1.setRangeAxis(1, new NumberAxis("Range Axis 2"));

        p1.setRenderer(1, new XYBarRenderer());

        XYPlot p2 = null;

        try {

            p2 = (XYPlot) p1.clone();

        }

        catch (CloneNotSupportedException e) {

            e.printStackTrace();

            System.err.println("Failed to clone.");

        }

        assertTrue(p1 != p2);

        assertTrue(p1.getClass() == p2.getClass());

        assertTrue(p1.equals(p2));

    }

    

    /**

     * Tests the independence of the clones.

     */

    public void testCloneIndependence() {

        XYPlot p1 = new XYPlot(

            null, new NumberAxis("Domain Axis"), new NumberAxis("Range Axis"),

            new StandardXYItemRenderer()

        );

        p1.setDomainAxis(1, new NumberAxis("Domain Axis 2"));

        p1.setDomainAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);

        p1.setRangeAxis(1, new NumberAxis("Range Axis 2"));

        p1.setRangeAxisLocation(1, AxisLocation.TOP_OR_RIGHT);

        p1.setRenderer(1, new XYBarRenderer());

        XYPlot p2 = null;        

        try {

            p2 = (XYPlot) p1.clone();

        }

        catch (CloneNotSupportedException e) {

            e.printStackTrace();

            System.err.println("Failed to clone.");

        }

        assertTrue(p1.equals(p2));

        

        p1.getDomainAxis().setLabel("Label");

        assertFalse(p1.equals(p2));

        p2.getDomainAxis().setLabel("Label");

        assertTrue(p1.equals(p2));

        

        p1.getDomainAxis(1).setLabel("S1");

        assertFalse(p1.equals(p2));

        p2.getDomainAxis(1).setLabel("S1");

        assertTrue(p1.equals(p2));

        

        p1.setDomainAxisLocation(1, AxisLocation.TOP_OR_RIGHT);

        assertFalse(p1.equals(p2));

        p2.setDomainAxisLocation(1, AxisLocation.TOP_OR_RIGHT);

        assertTrue(p1.equals(p2));

        

        p1.getRangeAxis().setLabel("Label");

        assertFalse(p1.equals(p2));

        p2.getRangeAxis().setLabel("Label");

        assertTrue(p1.equals(p2));

        

        p1.getRangeAxis(1).setLabel("S1");

        assertFalse(p1.equals(p2));

        p2.getRangeAxis(1).setLabel("S1");

        assertTrue(p1.equals(p2));

        

        p1.setRangeAxisLocation(1, AxisLocation.TOP_OR_LEFT);

        assertFalse(p1.equals(p2));

        p2.setRangeAxisLocation(1, AxisLocation.TOP_OR_LEFT);

        assertTrue(p1.equals(p2));

        

        p1.getRenderer().setOutlinePaint(Color.cyan);

        assertFalse(p1.equals(p2));

        p2.getRenderer().setOutlinePaint(Color.cyan);

        assertTrue(p1.equals(p2));

        

        p1.getRenderer(1).setOutlinePaint(Color.red);

        assertFalse(p1.equals(p2));

        p2.getRenderer(1).setOutlinePaint(Color.red);

        assertTrue(p1.equals(p2));

        

    }

    

    /**

     * Setting a null renderer should be allowed, but is generating a null pointer exception in

     * 0.9.7.

     */

    public void testSetNullRenderer() {

        boolean failed = false;

        try {

            XYPlot plot = new XYPlot(null, new NumberAxis("X"), new NumberAxis("Y"), null);

            plot.setRenderer(null);

        }

        catch (Exception e) {

            failed = true;

        }

        assertTrue(!failed);

    }



    /**

     * Serialize an instance, restore it, and check for equality.

     */

    public void testSerialization1() {



        XYDataset data = new XYSeriesCollection();

        NumberAxis domainAxis = new NumberAxis("Domain");

        NumberAxis rangeAxis = new NumberAxis("Range");

        StandardXYItemRenderer renderer = new StandardXYItemRenderer();

        XYPlot p1 = new XYPlot(data, domainAxis, rangeAxis, renderer);

        XYPlot p2 = null;



        try {

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            ObjectOutput out = new ObjectOutputStream(buffer);

            out.writeObject(p1);

            out.close();



            ObjectInput in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));

            p2 = (XYPlot) in.readObject();

            in.close();

        }

        catch (Exception e) {

            System.out.println(e.toString());

        }

        assertEquals(p1, p2);



    }



    /**

     * Serialize an instance, restore it, and check for equality.  This test uses a {@link DateAxis}

     * and a {@link StandardXYToolTipGenerator}.

     */

    public void testSerialization2() {



        IntervalXYDataset data1 = createDataset1();

        XYItemRenderer renderer1 = new XYBarRenderer(0.20);

        renderer1.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());

        XYPlot p1 = new XYPlot(data1, new DateAxis("Date"), null, renderer1);

        XYPlot p2 = null;



        try {

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            ObjectOutput out = new ObjectOutputStream(buffer);

            out.writeObject(p1);

            out.close();



            ObjectInput in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));

            p2 = (XYPlot) in.readObject();

            in.close();

        }

        catch (Exception e) {

            System.out.println(e.toString());

        }

        assertEquals(p1, p2);



    }



    /**

     * Problem to reproduce a bug in serialization.  The bug (first reported against the 

     * {@link org.jfree.chart.plot.CategoryPlot} class) is a null pointer exception that occurs 

     * when drawing a plot 

     * after deserialization. It is caused by four temporary storage structures (axesAtTop, 

     * axesAtBottom, axesAtLeft and axesAtRight - all initialized as empty lists in the 

     * constructor) not being initialized by the readObject(...) method following deserialization. 

     * This test has been written to reproduce the bug (now fixed).

     */

    public void testSerialization3() {

        

        XYSeriesCollection dataset = new XYSeriesCollection();

        JFreeChart chart = ChartFactory.createXYLineChart(

            "Test Chart",

            "Domain Axis",

            "Range Axis",

            dataset,

            PlotOrientation.VERTICAL,

            true,

            true,

            false

        );

        JFreeChart chart2 = null;

        

        // serialize and deserialize the chart....

        try {

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            ObjectOutput out = new ObjectOutputStream(buffer);

            out.writeObject(chart);

            out.close();



            ObjectInput in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));

            chart2 = (JFreeChart) in.readObject();

            in.close();

        }

        catch (Exception e) {

            System.out.println(e.toString());

        }



        boolean passed = true;

        try {

            chart2.createBufferedImage(300, 200);

        }

        catch (Exception e) {

            passed = false;  

            e.printStackTrace();            

        }

        assertTrue(passed);

    }



    /**

     * Creates a sample dataset.

     *

     * @return Series 1.

     */

    private IntervalXYDataset createDataset1() {



        // create dataset 1...

        TimeSeries series1 = new TimeSeries("Series 1", Day.class);

        series1.add(new Day(1, SerialDate.MARCH, 2002), 12353.3);

        series1.add(new Day(2, SerialDate.MARCH, 2002), 13734.4);

        series1.add(new Day(3, SerialDate.MARCH, 2002), 14525.3);

        series1.add(new Day(4, SerialDate.MARCH, 2002), 13984.3);

        series1.add(new Day(5, SerialDate.MARCH, 2002), 12999.4);

        series1.add(new Day(6, SerialDate.MARCH, 2002), 14274.3);

        series1.add(new Day(7, SerialDate.MARCH, 2002), 15943.5);

        series1.add(new Day(8, SerialDate.MARCH, 2002), 14845.3);

        series1.add(new Day(9, SerialDate.MARCH, 2002), 14645.4);

        series1.add(new Day(10, SerialDate.MARCH, 2002), 16234.6);

        series1.add(new Day(11, SerialDate.MARCH, 2002), 17232.3);

        series1.add(new Day(12, SerialDate.MARCH, 2002), 14232.2);

        series1.add(new Day(13, SerialDate.MARCH, 2002), 13102.2);

        series1.add(new Day(14, SerialDate.MARCH, 2002), 14230.2);

        series1.add(new Day(15, SerialDate.MARCH, 2002), 11235.2);



        TimeSeriesCollection collection = new TimeSeriesCollection(series1);

        collection.setDomainIsPointsInTime(false);  // this tells the time series collection that

                                                    // we intend the data to represent time periods

                                                    // NOT points in time.  This is required when

                                                    // determining the min/max values in the

                                                    // dataset's domain.

        return collection;



    }



}

