package usda.weru.weps.reports;

import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import net.sf.jasperreports.engine.JRAbstractChartCustomizer;
import net.sf.jasperreports.engine.JRChart;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItem;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.chart.renderer.category.ScatterRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.statistics.BoxAndWhiskerCalculator;
import org.jfree.data.statistics.BoxAndWhiskerItem;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
import org.jfree.data.statistics.DefaultMultiValueCategoryDataset;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.ShapeUtilities;
import usda.weru.util.ConfigData;
import usda.weru.util.Util;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class ConfidenceIntervalBoxWhiskerChartCustomizer extends JRAbstractChartCustomizer {

    /**
     *
     * @param jfc
     * @param jrc
     */
    @Override
    public void customize(JFreeChart jfc, JRChart jrc) {

        if (jfc.getPlot() instanceof CategoryPlot) {
            CategoryPlot plot = (CategoryPlot) jfc.getPlot();

            CategoryDataset data = plot.getDataset();

            List<Double> values = new ArrayList<Double>();

            double min = Double.POSITIVE_INFINITY;
            double max = Double.NEGATIVE_INFINITY;

            for (int r = 0; r < data.getRowCount(); r++) {
                for (int c = 0; c < data.getColumnCount(); c++) {
                    double value = data.getValue(r, c).doubleValue();
                    values.add(value);
                    min = Math.min(value, min);
                    max = Math.max(value, max);
                }
            }

            BoxAndWhiskerItem item = BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics(values);

            DefaultBoxAndWhiskerCategoryDataset dataset = new DefaultBoxAndWhiskerCategoryDataset();
            dataset.add(item, "loss", "loss");

            plot.setDataset(0, dataset);

            BoxAndWhiskerRenderer boxRenderer = new BoxAndWhiskerRenderer();
            //boxRenderer.setSeriesPaint(0, Color.RED);
            boxRenderer.setMaximumBarWidth(.50);
            plot.setRenderer(0, boxRenderer);

            // outliers
            DefaultMultiValueCategoryDataset outlierDataset = new DefaultMultiValueCategoryDataset();
            if (item.getOutliers() != null && !item.getOutliers().isEmpty()) {
                outlierDataset.add(item.getOutliers(), "loss", "loss");
            }

            plot.setDataset(1, outlierDataset);

            ScatterRenderer outlierRenderer = new ScatterRenderer();
            outlierRenderer.setSeriesShape(0, ShapeUtilities.createDiagonalCross(2, .5f));
            outlierRenderer.setSeriesPaint(0, Color.BLUE);
            outlierRenderer.setSeriesShapesFilled(0, true);
            plot.setRenderer(1, outlierRenderer);

            // setup the correct unit labels
            if (Util.USUnits.equals(ConfigData.getDefault().getData(ConfigData.Units))) {
                plot.getRangeAxis().setLabel("tn/ac");
            } else {
                plot.getRangeAxis().setLabel("kg/m\u00B2");
            }
            plot.getRangeAxis().setAutoRange(false);
            plot.getRangeAxis().setRangeWithMargins(min, max);

            // set the borders            
            jfc.setBorderVisible(true);

            //hide domain label
            plot.getDomainAxis().setVisible(false);

            //padding
            jfc.setPadding(new RectangleInsets(5, 10, 5, 5));

            //put the axis on the bottom
            plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);

            // add legend items for median and mean
            LegendItemCollection legend = new LegendItemCollection();
            plot.setFixedLegendItems(legend);
            plot.getFixedLegendItems().add(new LegendItem("Mean", null, null, null,
                    new Ellipse2D.Float(0, 0, 6.5f, 6.5f), Color.BLACK));
            plot.getFixedLegendItems().add(new LegendItem("Median", null, null, null,
                    new Rectangle2D.Float(0, 0, 1.25f, 10), Color.BLACK));
            plot.getFixedLegendItems().add(new LegendItem("Extreme Outlier", null, null, null,
                    ShapeUtilities.createDiagonalCross(2.5f, .5f), Color.BLUE));

        }
    }

}
