package normal;


import java.awt.*;
import javax.swing.*;
//import cern.jet.stat.*;
import java.awt.geom.Point2D;
import edu.csusb.danby.graph.*;

/**
 * This class graphs a normal curve and shows the area
 * under the curve specified
 * 
 * @author Charles S. Stanton
 * @version Mon Jul 29 19:10:03 PDT 2002
 */
public class NormalGraphData  implements PdfPlotable {
    static final float c = (float)(1.0/(Math.sqrt(2.0*Math.PI)));
    
    float mu, sigma, x1, x2;
    //add a few extra points near zero so that the graph is smoother
    float[] normalAbcissa ={	4.000000000f, 3.800000000f, 3.600000000f, 
                            3.400000000f, 3.200000000f, 3.000000000f,
                            2.800000000f, 2.600000000f, 2.400000000f, 
                            2.200000000f, 2.000000000f, 1.800000000f,		
                            1.600000000f, 1.400000000f, 1.200000000f, 
                            1.100000000f, 1.000000000f, .900000000f, 
                            .800000000f, .700000000f, .600000000f, 
                            .500000000f, .400000000f, .300000000f,
                            .200000000f, .100000000f, 0.f};
    float[] normalOrdinate = {.1338302258e-3f, .2919469256e-3f, .6119019298e-3f, 
                            .1232219168e-2f, .2384088201e-2f, .4431848411e-2f,
                        .7915451578e-2f, .1358296922e-1f, .2239453029e-1f,
                        .3547459283e-1f, .5399096648e-1f, .7895015828e-1f, 
                        .1109208346f, .1497274656f, .1941860549f, .2178521769f,
                     .2419707244f, .2660852498f, .2896915527f, .3122539332f,
                    .3332246028f, .3520653266f, .3682701402f, .3813878153f,
                    .3910426938f, .3969525473f, .3989422802f};

    boolean inverseSelected;
    int tailChoice; //PDFPlotable.LEFT_TAIL, PDFPlotable.RIGHT_TAIL, or PDFPlotable.BOTH_TAILS
    
    /**
    * constructs standard mu=0 sigma = 1<code>NormalGraphData</code>
    *
    */
    public NormalGraphData(){
        mu =0;
        sigma = 1;
        x1 = -21.01f;
        x2 =1.01f;
    }
    
    /**
    * constructs <code>NormalGraphData</code>
    *
    * @param mu is the mean
    * @param sigma is the standard deviation
    * @parm aX0 is the left end of the probability interval
    * @param aX1 is the right end of the probability interval
    */
    public NormalGraphData( float aMu, float aSigma, float aX1, float aX2){
        this( aMu, aSigma, aX1, aX2, false, PdfPlotable.BOTH_TAILS);
    }
    
    /**
    * constructs <code>NormalGraphData</code>
    *
    * @param mu is the mean
    * @param sigma is the standard deviation* @param n is the degrees of freedom
    * @parm aX0 is the left end of the probability interval
    * @param aX1 is the right end of the probability interval
    * @param aInverseSelected sets the inverse mode
    * @param aTailChoice sets the tail choice for inverse mode
    */
    public NormalGraphData( float aMu, float aSigma, float ax1, float ax2,
                                     boolean aInverseSelected, int aTailChoice){
        mu = aMu;
        sigma = aSigma;
        
        x1 = ax1;
        x2 = ax2;
        inverseSelected = aInverseSelected;
        tailChoice = aTailChoice;
    }

    private float f(float x){
        return (float)(c/Math.sqrt(sigma)*Math.exp(-1*(x-mu)*(x-mu)/(2*sigma*sigma)));
        }

    public Point2D.Float[] getPlotPoints() { 
        Point2D.Float[] returnData = new Point2D.Float[53];
        //add a few extra points near zero so that the graph is smoother
        for (int i=0; i<27; i++) {
            returnData[i] = new Point2D.Float( -1*normalAbcissa[i]*sigma+mu, normalOrdinate[i]/(float)Math.sqrt(sigma));
            returnData[53-i-1] = new Point2D.Float( normalAbcissa[i]*sigma+mu, normalOrdinate[i]/(float)Math.sqrt(sigma));
        }
        return returnData;
    }
    // PdfPlotable viewport methods
    public float getLowX(){return -4.0f*sigma+mu;}
    public float getHighX(){ return 4.0f*sigma+mu;}
    public float getLowY(){ return 0.0f;} //usually should be 0
    public float getHighY()	{return 0.5f/(float)Math.sqrt(sigma);}
    // PdfPlotable interval methods 
    public Point2D.Float getLowXInterval() {return new Point2D.Float(x1,f(x1));} 

    public Point2D.Float getHighXInterval() {return new Point2D.Float(x2, f(x2));}
    // PdfPlotable String information
    public String getXAxisLabel(){return "x";}
    public String getTitle()	{
        String title = new String("Normal Plot, mu = "+mu+" sigma = "+sigma);
        return title;
    }
    public void reset(){;}
    public boolean isInverseSelected(){return inverseSelected;}
    public void setInverseSelected(boolean aInverseSelected){ inverseSelected = aInverseSelected;}
    public int getTailChoice(){return tailChoice;}
    public void setTailChoice(int aTailChoice){ tailChoice=aTailChoice;}
    public void setX1(float aX1){ x1 = aX1;}
    public void setX2(float aX2){ x2 = aX2;}
    public void setMu(float aMu){ mu = aMu;}
    public void setSigma(float aSigma){ sigma = aSigma;}
}
