package cz.martinstainer.chart;

import java.awt.Color;
import java.awt.BasicStroke;
import java.awt.geom.Ellipse2D;
import java.util.Random;

import cz.martinstainer.gui.ChartPanel;
import de.erichseifert.gral.data.DataSeries;
import de.erichseifert.gral.data.DataSource;
import de.erichseifert.gral.data.DataTable;
import de.erichseifert.gral.data.statistics.Statistics;
import de.erichseifert.gral.plots.XYPlot;
import de.erichseifert.gral.plots.lines.DefaultLineRenderer2D;
import de.erichseifert.gral.plots.lines.LineRenderer;
import de.erichseifert.gral.plots.points.DefaultPointRenderer2D;
import de.erichseifert.gral.plots.points.PointRenderer;
import de.erichseifert.gral.ui.DrawablePanel;
import de.erichseifert.gral.graphics.Insets2D;


public class ThroughputChart extends ChartPanel {

    /**
     * Version id for serialization.
     */
    private static final long serialVersionUID = 5228891435595348789L;
    private DataTable iperfData = new DataTable(Float.class, Float.class);
    private DataTable tperfData = new DataTable(Float.class, Float.class);
    private XYPlot plot;
    private String unit = "Mbit/s";
    private String xUnit = "Time [s]";
    private Float xUnitValue = new Float(0.0);
    private boolean custom = false;

    private double divide = 1024.0;

    @SuppressWarnings("unchecked")
    public ThroughputChart() {
        DataSeries data1 = new DataSeries("TCP", iperfData,0,1);
        DataSeries data2 = new DataSeries("QUIC", tperfData, 0,1);

        plot = new XYPlot(data1, data2);
        plot.setLegendVisible(true);
        formatFilledArea(plot, data1, COLOR2);
        formatFilledArea(plot, data2, COLOR1);
        plot.setInsets(new Insets2D.Double(10.0, 80.0, 80.0, 10.0));
        plot.getAxisRenderer(XYPlot.AXIS_Y).getLabel().setText("Throughput [" + unit + "]");
        plot.getAxisRenderer(XYPlot.AXIS_X).getLabel().setText("Time [10s]");
        plot.getAxisRenderer(XYPlot.AXIS_X).setTickSpacing(1.0);
        plot.getAxisRenderer(XYPlot.AXIS_Y).setTickSpacing(2.0);

        add(new DrawablePanel(plot));
    }

    public void recalculate(String changeToUnit) {
        this.unit = changeToUnit;
        if (this.unit == "Kbit/s") {
            this.divide = 1.0;
        }
        if (this.unit == "Mbit/s") {
            this.divide = 1024;
        }
        if (this.unit == "Gbit/s") {
            this.divide = 1024.0 * 1024.0;
        }
        plot.getAxisRenderer(XYPlot.AXIS_Y).getLabel().setText("Throughput [" + unit + "]");
        this.repaint();
    }


    public void setCustom(String xUnit, Float newXUnitValue) {
        this.custom = true;
        this.xUnitValue = newXUnitValue;
        plot.getAxisRenderer(XYPlot.AXIS_X).getLabel().setText(xUnit);
    }

    public void addValueToChartData(float time, float value, String contentType) {
        float xValue =  (float) (value / divide);
        float yValue = new Float(0.0);
        if(contentType.equals("iperf")) {
            if(custom == true) {
                yValue = (float) xUnitValue;
            } else {
                yValue = (float) (iperfData.getRowCount() + 1);
            }

            iperfData.add(yValue, xValue);
        } else if (contentType.equals("tperf")) {
            if(custom == true) {
                yValue = (float) xUnitValue;
            } else {
                yValue = (float) (tperfData.getRowCount() + 1);
            }

            tperfData.add(yValue, xValue);
        }
        double max = this.iperfData.getStatistics().get(Statistics.MAX);
        max = max + max /10.0;
        plot.getAxis(XYPlot.AXIS_Y).setRange(0.0, max);
        this.repaint();
    }

    private static void formatFilledArea(XYPlot plot, DataSource data, Color color) {
        PointRenderer point = new DefaultPointRenderer2D();
        point.setColor(color);
        plot.setPointRenderers(data, point);
        LineRenderer line = new DefaultLineRenderer2D();
        line.setColor(color);
        line.setGap(3.0);
        line.setGapRounded(true);
        plot.setLineRenderers(data, line);
    }

    public void eraseData() {
        iperfData.clear();
        tperfData.clear();
        this.custom = false;
        this.repaint();
    }

    @Override
    public String getTitle() {
        return "Stacked plots";
    }

    @Override
    public String getDescription() {
        return "An area and a line plot with synchronized actions.";
    }

}
