/* Viewing Sources */


/*
Nhan Le

PascalTriangleApp.java

<applet code="PascalTriangleApplet" width="300" height="400">
</applet>

-unoptimized, maybe use a different datastructure for node access if performance not satisfactory
-the number of rows limited only to the amount a memory available
-layout should be reworked
 */


import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.math.*;

class IntWrapper{
    public BigInteger value;
    IntWrapper(int i){
	this.value = new BigInteger(new Integer(i).toString());
    }
    IntWrapper(BigInteger i){
	this.value = i;
    }
    public String toString(){
	return (""+value);
    }
}

class PascalTriangle{
    private Vector  vRows[];
    private int     iRows;
    private StringBuffer  pascaltriangle;

    PascalTriangle(){this(15);}//initialize to something if no arguments are passed to constructor
    PascalTriangle(int rows){
	this.iRows = rows;
	vRows = new Vector[iRows];
	pascaltriangle= new StringBuffer("");
	for(int i=0; i<iRows; i++)
	    vRows[i]  = new Vector();
	compute();
    }
    private void compute(){
	//init the "root node"
	vRows[0].addElement(new IntWrapper(0));
	vRows[0].addElement(new IntWrapper(1));
	vRows[0].addElement(new IntWrapper(0));

	int x=0,y=0;
	for(x=1; x<iRows; x++){
	    vRows[x].addElement(new IntWrapper(0));
	    for(y=1; y<vRows[x-1].size(); y++){
		BigInteger i1 = ((IntWrapper)vRows[x-1].elementAt(y-1)).value;
		BigInteger i2 = ((IntWrapper)vRows[x-1].elementAt(y)).value;
		vRows[x].addElement(new IntWrapper(i1.add(i2)));
	    }
	    vRows[x].addElement(new IntWrapper(0));
	    vRows[x-1].removeElementAt(0);
	    vRows[x-1].removeElementAt(vRows[x-1].size()-1);
	}
	vRows[x-1].removeElementAt(0);
	vRows[x-1].removeElementAt(vRows[x-1].size()-1);

    }
    public String toString(){//for integration with other classes - 'recomputes' each time so method should be called only once
	for(int i=0; i<iRows; i++){
		Enumeration e = vRows[i].elements();
		//pascaltriangle+=("row " +i+ ": ");
		while(e.hasMoreElements())
			pascaltriangle.append(e.nextElement()+ " ");
		pascaltriangle.append("\n");
	}
	return pascaltriangle.toString();
    }
    public String getInfo(){
	return "PascalTriangle version 0.99\nNhan Le\[email protected]";
    }
}


class Node{
    private int x;
    private int y;
    private BigInteger b;
    Node(){this(0,0,new BigInteger("0"));}
    Node(int x, int y, BigInteger b){setXY(x,y);setB(b);}
    public BigInteger getValue(){return b;}
    public int getX(){return x;}
    public int getY(){return y;}
    public Point getXY(){return new Point(x,y);}
    public void setXY(int x, int y){this.x=x;this.y=y;}
    public void setB(BigInteger b){this.b=b;}
}


public class PascalTriangleApplet extends Applet
implements MouseMotionListener{
    private Integer numRows;
    private Vector  rows;
    private Vector  coordinates;
    private Panel   pTriangle;
    private Color   bgcolor;
    private String  number;
    private Graphics gbuffer;
    private Image    ibuffer;
    public void init(){
	ibuffer = createImage(300,400);

	addMouseMotionListener(this);
	bgcolor = new Color(245,245,245);

	setBackground(bgcolor);

	numRows =  new Integer("50");

	rows = new Vector();

	StringTokenizer st  =
		new StringTokenizer(
		new PascalTriangle(numRows.intValue()).toString(),"\n");

	while(st.hasMoreTokens())
		rows.addElement(st.nextToken());
	coordinates = new Vector();
	initNodes();
	number="overshadow mouse over node";
    }
    public void paint(Graphics g){
	if(gbuffer==null)
	    gbuffer = ibuffer.getGraphics();

	int w2=0;
	int y2=50;
	for(int r=1; r<=numRows.intValue(); r++){
	    for(int c=1; c<=r; c++)
		drawNodeRow((getSize().width/2)-(w2/2),y2,c);
	    w2+=4;
	    y2+=5;
	}
	gbuffer.setColor(bgcolor);
	gbuffer.fillRect(10,getSize().height-10-30,300,30);
	gbuffer.setColor(Color.red);
	gbuffer.setFont(new Font("courier new",Font.PLAIN,18));
	gbuffer.drawString(number,10,getSize().height-10);

	g.drawImage(ibuffer,0,0,this);
    }
    public void update(Graphics g){
	paint(g);
    }
    private void initNodes(){
	Enumeration e = rows.elements();

	int w2=0;
	int y2=50;
	for(int r=1; r<=numRows.intValue(); r++){
	    String s = (String)e.nextElement();
	    StringTokenizer st = new StringTokenizer(s," ");
	    for(int c=1; c<=r; c++){
		    coordinates.addElement(
		    new Node(((getSize().width/2)-(w2/2))+(4*c)
			,y2
			,new BigInteger(st.nextToken())));
	    }
	    w2+=4;
	    y2+=5;
	}

    }
    private void drawNodeRow(int x, int y,int c){
	gbuffer.setColor(Color.blue);
	for(int i=0; i<c; i++)
	    gbuffer.drawRect(x-2+(4*c),y-2,4,4);
    }
    public void mouseDragged(MouseEvent me){
    }
    public void mouseMoved(MouseEvent me){
	Point p = me.getPoint();

	Enumeration e = coordinates.elements();
	while(e.hasMoreElements()){
	    Node n = (Node)e.nextElement();
	    if(((p.x>=n.getX()-2) && (p.x<=n.getX()+2))
	       && ((p.y>=n.getY()-2) && (p.y<=n.getY()+2))){
		number = n.getValue().toString();
		repaint();
		break;
	    }
	}
    }
}

/* sources by Nhan Le */
/* [email protected] */
/* [email protected] */
/* [email protected] */
/* if you find the sources useful or if you want to make any modifications, just email me */
/* html generated using GNU source-highlight 1.8 =-) */