import java.awt.*;
import objectdraw.*;

// Controller for a path finder.
// Andrea Danyluk, March 2002.

public class Paths extends WindowController
{
	// the grid-specific path finder
	private PathFinder grid;
	
	// the message indicating number of paths found
	private Text pathsMessage;
	
	// number of rows and columns in the grid
	private static final int ROWS = 5;
	private static final int COLS = 5;
	
	// row and column of the start location
	private static final int X_START = 2;
	private static final int Y_START = 4;
	
	// row and column of the end location
	private static final int X_END = 5;
	private static final int Y_END = 1;
	
	// dot size and spacing
	private static final int DOT_SIZE = 5;
	private static final int DOT_SPACING = 20;
	
	// location of grid graphic
	private static final Location GRID_LOCATION = new Location(10, 10);
	
	public void begin()
	{
		grid = new PathFinder(GRID_LOCATION, ROWS, COLS, DOT_SIZE, DOT_SPACING, canvas);
		pathsMessage = new Text("", GRID_LOCATION.getX(), 
		         GRID_LOCATION.getY()+ROWS*DOT_SPACING, canvas);
	}
	
	// count the number of paths from a specified start point to a
	// specified end point
	public void onMouseClick(Location point)
	{
		int numPaths = grid.allPaths(X_START, Y_START, X_END, Y_END);
		pathsMessage.setText(numPaths);
	}
	
	// clear the path finder
	public void onMouseExit(Location point)
	{
		grid.clear();
		pathsMessage = new Text("", GRID_LOCATION.getX(), 
		         GRID_LOCATION.getY()+ROWS*DOT_SPACING, canvas);
	}
}


import java.awt.*;
import objectdraw.*;

// A recursive path counter
// Andrea Danyluk, March 2002
// Sets up a grid of points and finds the number of paths from a specified
// start point to a specified end point.  All path searching is done up and to
// the right.

public class PathFinder
{
	// the location of the grid graphic
	private Location point;
	// the size and spacing of the grid dots
	private int dotSize, dotSpacing;
	// the number of rows and columns in the grid
	private int numRows, numCols;
	// the canvas
	private DrawingCanvas canvas;
	
	public PathFinder(Location point, int numRows, int numCols, 
		int dotSize, int dotSpacing, DrawingCanvas canvas)
	{
		// remember instance variable values
		this.point = point;
		this.dotSpacing = dotSpacing;
		this.dotSize = dotSize;
		this.numRows = numRows;
		this.numCols = numCols;
		this.canvas = canvas;
		
		// draw the grid
		drawGrid();
	}
	
	// count all paths from start point to end point, highlight start
	// points
	public int allPaths(int xStart, int yStart, int xEnd, int yEnd)
	{
		// first highlight the start and end points
		new FilledOval(point.getX()+(xStart-1)*dotSpacing,
			point.getY()+(yStart-1)*dotSpacing,
			dotSize, dotSize, canvas).setColor(Color.green);
		new FilledOval(point.getX()+(xEnd-1)*dotSpacing,
			point.getY()+(yEnd-1)*dotSpacing, 
			dotSize, dotSize, canvas).setColor(Color.red);
			
                // the number of paths from our neighbor to the right
                int rightPaths = 0;
                // the number of paths from our neighbor above
                int upPaths = 0;
		
                // if the start point is the same as the end point, there's
                // only one path.
                if (xStart == xEnd && yStart == yEnd)
                    return 1;
		
                // find out how many paths there are from the neighbor to the
                // right of the start point
                if (xStart < xEnd)
                     rightPaths = allPaths(xStart+1, yStart, xEnd, yEnd);
			
                // find out how many paths there are from the neighbor 
                // above of the start point
                if (yStart > yEnd)
                    upPaths = allPaths(xStart, yStart-1, xEnd, yEnd);
			
                // add up the paths from each neighbor and return
                return rightPaths + upPaths;		
        }
	
	public void clear()
	{
		// clear the canvas
		canvas.clear();
		
		// draw a new grid
		drawGrid();
	}
	
	// draw a new grid
	private void drawGrid()
	{
		int xCounter =  1;
		int yCounter = 1;
		while (xCounter <= numCols)
		{
			while (yCounter <= numRows)
			{
				new FilledOval(point.getX()+(xCounter-1)*dotSpacing, 
					point.getY()+(yCounter-1)*dotSpacing, dotSize, dotSize, canvas);
				yCounter = yCounter + 1;
			}
			yCounter = 1;
			xCounter = xCounter + 1;
		}
	}

}