package montecarlo;

import ptolemy.plot.Plot;

public class Histogram  {
	private double deltaX, xMin, xMax;
	private int nValues, sum;
	private int[] counts;
	private double[] histogram;
    private double xvalues[];
    private Plot plot;  //Histogram.Plot inner class
    
    public Histogram(int n, double x0, double x1) {
	    nValues = n;
	    xMin = x0;
	    xMax = x1;
	    counts = new int[nValues];
	    histogram = new double[nValues];
        xvalues = new double[n];
	    deltaX = (x1 - x0)/(double)nValues;
	    reset();
	}
	
	public void reset() {                //resets all histogram values and counts to zero
	    sum = 0;
	    for(int i=0; i<nValues; i++) {
	        histogram[i] = 0.0; 
	        counts[i] = 0;
	        xvalues[i] = xMin + (i+0.5)*deltaX;
	    }
	}
	
	public void addValues(double[] x) {  //updates histogram through addition of multiple new values
	    for(int j=0; j<x.length; j++) {addValue(x[j]);}
	}
	
    public void addValue(double x) {     //takes new value and updates histogram
	    int i = (int)Math.floor(((x-xMin)/deltaX));
	    i = (i >= nValues) ? nValues-1 : i;  // i = Max(i,nValues)
	    i = (i < 0) ? 0 : i;                 // i = Max(i,0);
	    counts[i]++;
	    sum++;
    }
    	    
    public double[] getHistogram() {      //returns an array representing the present histogram
        if(sum == 0) {return histogram;}
	    for(int i=0; i<nValues; i++) {
	        histogram[i] = (double)counts[i]/((double)sum*deltaX);
	    }
	    return histogram;
    }
    public double[] getX() {return xvalues;}
    
    public Plot getPlot() {                //returns a Plot capable of displaying the histogram
        if(plot == null) plot = new Plot();
        return plot;
    }
    
    public class Plot extends ptolemy.plot.Plot {
        
        public Plot() {
            setTitle("Histogram");
            setYRange(0, 1);
            setXRange(xMin, xMax);
//            setPointsPersistence(nPoints);
            setImpulses(true); 
            setMarksStyle("none");
            update();
        }
        
        public void update() {  //redraws plot with current values of histogram
            clear(false);
            repaint();
            double[] hist = getHistogram();
            double[] x = getX();
            for(int i=0; i<hist.length; i++) {
//                System.out.println(x[i]+"  "+hist[i]);
                addPoint(0, x[i],hist[i],false);
            }
            repaint();
        }
    }
    
}
