package usda.weru.weps.reports;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Rectangle;
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.event.PlotChangeEvent;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
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.ui.RectangleInsets;
import usda.weru.util.ConfigData;
import usda.weru.util.Util;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class ConfidenceIntervalSummaryChartCustomizer 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>();

            int lossIndex = data.getRowIndex("loss");
            int lowIndex = data.getRowIndex("low");
            int meanIndex = data.getRowIndex("mean");
            int highIndex = data.getRowIndex("high");

            int count = data.getColumnCount();

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

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

            double low = data.getValue(lowIndex, count - 1).doubleValue();
            double mean = data.getValue(meanIndex, count - 1).doubleValue();
            double high = data.getValue(highIndex, count - 1).doubleValue();

            BoxAndWhiskerItem calculated = BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics(values);

            BoxAndWhiskerItem item = new BoxAndWhiskerItem(mean, calculated.getMedian(), low, high, min, max, null, null, null);

            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);
            boxRenderer.setSeriesPaint(0, new Color(0, 255, 0, 191));
            plot.setRenderer(0, boxRenderer);

            // 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("90% Confidence", null, null, null,
                    new Rectangle(13, 7), new Color(0, 255, 0, 191), new BasicStroke(.5f), Color.BLACK));

        }
    }

}
