/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math4.userguide;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.apache.commons.statistics.distribution.BinomialDistribution;
import org.apache.commons.statistics.distribution.GeometricDistribution;
import org.apache.commons.statistics.distribution.HypergeometricDistribution;
import org.apache.commons.statistics.distribution.DiscreteDistribution;
import org.apache.commons.statistics.distribution.PascalDistribution;
import org.apache.commons.statistics.distribution.PoissonDistribution;
import org.apache.commons.statistics.distribution.UniformDiscreteDistribution;
import org.apache.commons.statistics.distribution.ZipfDistribution;
import org.apache.commons.math4.userguide.ExampleUtils.ExampleFrame;

import com.xeiam.xchart.Chart;
import com.xeiam.xchart.ChartBuilder;
import com.xeiam.xchart.Series;
import com.xeiam.xchart.SeriesMarker;
import com.xeiam.xchart.StyleManager.ChartType;
import com.xeiam.xchart.StyleManager.LegendPosition;
import com.xeiam.xchart.XChartPanel;

/**
 * Displays pdf/cdf for integer distributions.
 */
public class IntegerDistributionComparison {

    public static void addPDFSeries(Chart chart, DiscreteDistribution distribution, String desc, int lowerBound, int upperBound) {
        // generates Log data
        List<Number> xData = new ArrayList<Number>();
        List<Number> yData = new ArrayList<Number>();
        for (int x = lowerBound; x <= upperBound; x += 1) {
            try {
                double probability = distribution.probability(x);
                if (! Double.isInfinite(probability) && ! Double.isNaN(probability)) {
                    xData.add(x);
                    yData.add(probability);
                }
            } catch (Exception e) {
                // ignore
                // some distributions may reject certain values depending on the parameter settings
            }
        }

        Series series = chart.addSeries(desc, xData, yData);
        series.setMarker(SeriesMarker.NONE);
        series.setLineStyle(new BasicStroke(1.2f));
    }

    public static void addCDFSeries(Chart chart, DiscreteDistribution distribution, String desc,
                                    int lowerBound, int upperBound) {
        // generates Log data
        List<Number> xData = new ArrayList<Number>();
        List<Number> yData = new ArrayList<Number>();
        for (int x = lowerBound; x <= upperBound; x += 1) {
          double density = distribution.cumulativeProbability(x);
          if (! Double.isInfinite(density) && ! Double.isNaN(density)) {
              xData.add(x);
              yData.add(density);
          }
        }

        Series series = chart.addSeries(desc, xData, yData);
        series.setMarker(SeriesMarker.NONE);
        series.setLineStyle(new BasicStroke(1.2f));
    }

    public static Chart createChart(String title, int minX, int maxX, LegendPosition position) {
        Chart chart = new ChartBuilder().width(235).height(200).build();

        // Customize Chart
        chart.setChartTitle(title);
        chart.getStyleManager().setChartTitleVisible(true);
        chart.getStyleManager().setChartTitleFont(new Font("Arial", Font.PLAIN, 10));
        chart.getStyleManager().setLegendPosition(position);
        chart.getStyleManager().setLegendVisible(true);
        chart.getStyleManager().setLegendFont(new Font("Arial", Font.PLAIN, 10));
        chart.getStyleManager().setLegendPadding(6);
        chart.getStyleManager().setLegendSeriesLineLength(6);
        chart.getStyleManager().setAxisTickLabelsFont(new Font("Arial", Font.PLAIN, 9));
        
        chart.getStyleManager().setXAxisMin(minX);
        chart.getStyleManager().setXAxisMax(maxX);
        chart.getStyleManager().setChartBackgroundColor(Color.white);
        chart.getStyleManager().setChartPadding(4);
        
        chart.getStyleManager().setChartType(ChartType.Line);
        return chart;
    }
    
    public static JComponent createComponent(String distributionName, int minX, int maxX, String[] seriesText,
                                             DiscreteDistribution... series) {
        JComponent container = new JPanel();
        container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
        
        container.add(new JLabel(distributionName));
        
        Chart chart = createChart("PDF", minX, maxX, LegendPosition.InsideNE);
        int i = 0;
        for (DiscreteDistribution d : series) {
            addPDFSeries(chart, d, seriesText[i++], minX, maxX);
        }
        container.add(new XChartPanel(chart));

        chart = createChart("CDF", minX, maxX, LegendPosition.InsideSE);
        i = 0;
        for (DiscreteDistribution d : series) {
            addCDFSeries(chart, d, seriesText[i++], minX, maxX);
        }
        container.add(new XChartPanel(chart));

        container.setBorder(BorderFactory.createLineBorder(Color.black, 1));
        return container;
    }
    
    @SuppressWarnings("serial")
    public static class Display extends ExampleFrame {
        
        private JComponent container;

        public Display() {
            setTitle("Commons-Math: Integer distributions overview");
            setSize(1320, 920);
            
            container = new JPanel();
            container.setLayout(new GridBagLayout());
            
            GridBagConstraints c = new GridBagConstraints();
            c.fill = GridBagConstraints.VERTICAL;
            c.gridx = 0;
            c.gridy = 0;
            c.insets = new Insets(2, 2, 2, 2);

            JComponent comp = null;

            comp = createComponent("Binomial", 0, 40,
                                   new String[] { "p=0.5,n=20", "p=0.7,n=20", "p=0.5,n=40" },
                                   new BinomialDistribution(20, 0.5),
                                   new BinomialDistribution(20, 0.7),
                                   new BinomialDistribution(40, 0.5));
            container.add(comp, c);

            c.gridx++;
            comp = createComponent("Geometric", 0, 10,
                                   new String[] { "p=0.2", "p=0.5", "p=0.8" },
                                   new GeometricDistribution(0.2),
                                   new GeometricDistribution(0.5),
                                   new GeometricDistribution(0.8));
            container.add(comp, c);

            c.gridx++;
            comp = createComponent("Hypergeometric", 0, 10,
                                   new String[] { "p=0.3", "p=0.5", "p=0.75" },
                                   new HypergeometricDistribution(100, 6, 20),
                                   new HypergeometricDistribution(100, 10, 20),
                                   new HypergeometricDistribution(100, 15, 20));
            container.add(comp, c);

            c.gridx++;
            comp = createComponent("Pascal", 0, 50,
                                   new String[] { "p=0.3", "p=0.5", "p=0.7" },
                                   new PascalDistribution(10, 0.3),
                                   new PascalDistribution(10, 0.5),
                                   new PascalDistribution(10, 0.7));
            container.add(comp, c);

            c.gridy++;
            c.gridx = 0;
            comp = createComponent("Poisson", 0, 20,
                                   new String[] { "λ=1", "λ=4", "λ=10" },
                                   new PoissonDistribution(1),
                                   new PoissonDistribution(4),
                                   new PoissonDistribution(10));
            container.add(comp, c);

            c.gridx++;
            comp = createComponent("Uniform", 0, 30,
                                   new String[] { "l=1,u=10", "l=5,u=20", "l=1,u=25" },
                                   new UniformDiscreteDistribution(1, 10),
                                   new UniformDiscreteDistribution(5, 20),
                                   new UniformDiscreteDistribution(1, 25));
            container.add(comp, c);

            c.gridx++;
            comp = createComponent("Zipf", 0, 15,
                                   new String[] { "n=10,e=0.5", "n=10,e=1", "n=10,e=2", "n=10,e=5" },
                                   new ZipfDistribution(10, 0.5),
                                   new ZipfDistribution(10, 1),
                                   new ZipfDistribution(10, 2),
                                   new ZipfDistribution(10, 5));
            container.add(comp, c);

            JScrollPane scrollPane = new JScrollPane(container);
            add(scrollPane);
            
        }

        @Override
        public Component getMainPanel() {
            return container;
        }

    }

    public static void main(String[] args) {
        ExampleUtils.showExampleFrame(new Display());
    }
}
