/*
	InteractiveCorr applet allows the user to select an
	ordered pair by clicking on a carteasean co-ord grid
	computes R square and least squares regression line
	Version 1.0 - 7 Oct 1999 Chris Thiel <cct@ktb.net>
			
*/

import java.lang.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.util.*;

public class guessCorr extends Applet
{
	int MAX=50;
	int n=0;
	
	String message=null;
	int x[] = new int[MAX];
	int y[] = new int[MAX];
	float xMean, yMean;
	double gb0,gb1;
    float B0, B1, R, R_square,Var_x,Var_y, SSR, gRes;
	int fudge =7;
	int i=0;
	Color buttonColor;
	int buttonWidth=50;
	int buttonHeight=20;
	Rectangle ReDo,ShowReg;
	boolean ShowAll=false;
	int Ax,Ay,By,Bx;
	
/*
	Compute is the routine called to compute the Statistical Data
*/	

	public void  compute(){
	// Now calculate regression coeffecients
    	float Sx = 0, Sy =0;
    	float Sxx = 0, Sxy = 0, Syy = 0;
    	

    	for(int i=0; i< n; i++)
    	{
    		
      		Sx += x[i]; 
      		Sy += y[i];
    	}
    	xMean = Sx / n;
    	yMean = Sy / n;
    	for(int i=0; i< n; i++)
    	{
      		Sxx += (x[i]-xMean) * (x[i]-xMean);
      		Sxy += (x[i]-xMean) * (y[i]-yMean);
      		Syy += (y[i]-yMean) * (y[i]-yMean);
      		}
    	
    	B1=Sxy/Sxx; //slope
    	B0 = yMean - B1 * xMean;//intercept
    	R_square=(Sxy*Sxy)/(Sxx*Syy);
    	R =(float)( Math.sqrt(R_square) );
    	if (B1<0) R *=  -1;
    	//Compute the R-square for guess
    	gb0 = size().height-Ay;
    	gb1 =(double)((Ay-By)/(double)(size().width));
    
    	for (int i=0; i<n ; i++){
    		gRes  += Math.pow(y[i]-(gb0+(x[i]*gb1)),2);
    	    
    	}	
    	
    	gRes = (float)(Math.sqrt(gRes));
    	// convert for display
    	gb0 = size().height-Ay;
    	gb1 =(double)((Ay-By)/(double)(size().width));
	}
	
 	public void clearAll() {
 		n = 0;
 		compute();
 		repaint();
 	}
    private void getNewRandomDots() {
    	n =MAX;
    	double MaxX = size().width;
    	double MaxY = size().height;
    	
    	Ax = 0;
    	Ay = (int)(MaxY/2);
    	Bx = (int)(MaxX);
    	By = Ay;
    	
    	double b = Math.random()*MaxY;
    	double a = (-b/MaxX)+((MaxY-b)/MaxX)*Math.random();
    	double c = Math.random()*MaxY;
    	for (int i=0; i < MAX-2; i++){
    		x[i]=(int)(1+Math.random()*MaxX);
    		y[i]=(int)(a*x[i]+b+(Math.random()-.5)*c);
    	}
    	
    	for (int i=MAX-2; i < MAX; i++){
    		x[i]=(int)(1+Math.random()*MaxX);
    		y[i]=(int)(a*x[i]+b+(Math.random()-.5)*c*2);
    	}
    	
    }
    public void init() {
    	//draw the buttons and such
    	buttonColor = new  Color( 200,250, 220);
	    setBackground(new Color(0xF0F0D0));
	    ReDo = new Rectangle ( size().width-buttonWidth-10,size().height-buttonHeight-10,buttonWidth,buttonHeight);
	    ShowReg= new Rectangle ( 10, size().height-buttonHeight-10,buttonWidth,buttonHeight);
	   
    	
    	//fill arry with 50 random points
    	getNewRandomDots();
    	compute();
		repaint();
	}
	private int CoordY(int y){
		return size().height-y;
	}
	public void paint( Graphics g ) {
		for (i=0; i< n; i++){
			g.fillOval(x[i]-2,CoordY(y[i])-2, 4,4);
		}
		g.drawString( "Click on graph to estimate a regression line", 30, 15 );
		if (n == MAX-1) {
			g.drawString( "WARNING: Maximum number of Pairs found", 5,size().height-48);
		 	g.drawString( "subsequent pairs ignored", 35,size().height-36);
		 	}
		
    	g.drawString("_",25,81);
    	g.drawString("_",25,96);
    	g.drawString("x = "+xMean,25, 90);
		g.drawString("y = "+yMean,25, 105);
		if (message != null) {
	    	g.drawString("Error in data: "+message, 10, size().height-24);
	    	g.drawString("Two numbers per line separated by space", 10, size().height-12);

			}
		//Draw Buttons
		g.setColor( buttonColor);
		g.fill3DRect(ReDo.x, ReDo.y, ReDo.width, ReDo.height,true);
		g.fill3DRect(ShowReg.x, ShowReg.y, ShowReg.width, ShowReg.height,true);
		g.setColor( Color.black);
		g.draw3DRect(ReDo.x, ReDo.y, ReDo.width, ReDo.height,true);
		g.draw3DRect(ShowReg.x, ShowReg.y, ShowReg.width, ShowReg.height,true);
		g.setColor(Color.blue);
		g.drawString("ReDo", ReDo.x+(int)(.15*buttonWidth),ReDo.y+(int)(.75*buttonHeight));
		g.drawString("Your line:",size().width-110,30);
		g.drawString("Residuals   ="+gRes,size().width-100,60);
	
		g.drawString("y = "+gb1+"x +"+gb0, size().width-100,45);
		
		if ( ShowAll )	{
			g.setColor(Color.magenta);
			g.drawLine(0, CoordY((int)(B0)), size().width, CoordY((int)(B1*size().width+B0)));
			g.drawString("Least Square Regression Line Equation:",25,30);
    		g.drawString("y  = "+B1+" * x + "+B0,25,45);
    		g.drawString("r   = "+R_square,25,60); 
    		g.drawString("^",25,43);
    		g.drawString("r  = "+R,25,75);

    		g.drawString(" Hide", ShowReg.x+(int)(.15*buttonWidth), ShowReg.y+(int)(.75*buttonHeight));
			g.drawString("2",30,57);
    	} else {
    		g.drawString(" Show", ShowReg.x+(int)(.15*buttonWidth), ShowReg.y+(int)(.75*buttonHeight));
		}
		g.setColor(Color.blue);
		g.drawLine(Ax,Ay,Bx,By);
}// of paint
/*
     * Mouse methods
     */
    public boolean mouseDown(java.awt.Event evt, int x0, int y0) {
      
        if ( ReDo.inside(x0,y0) ) {
        	getNewRandomDots();
        	ShowAll = false;
        } else {
        if ( ShowReg.inside(x0,y0) ) {
        	ShowAll = !ShowAll;
        } else {
        	if (x0 < size().width/2){
        		Ax = 0;
        		Ay = (int)(y0-
        		
        		x0*(By-y0)/(size().width-x0));
        		} else {
        		Bx = size().width;
        		By = (int)(y0+(size().width-x0)*(y0-Ay)/(x0-Ax));
        		}
        }
        } 
        
	   compute();
       repaint();
       return true;
    }
	
  	
  	
    public boolean mouseMove(java.awt.Event evt, int x, int y) {
        y= size().height-y;
        getAppletContext().showStatus("Location of mouse: (" + x + ", " + y + ")");
        
         
        return true;
    }

    public void mouseEnter() {
        repaint();
    }

    public void mouseExit() {
       
        repaint();
    }
}//of applet    
    