//Ajay Kulkarni-- 6.837 pset 2a
//9.23.99

import display.*;

//The class that the students will fill up with the correct algorithm.

public class Bresenham {

    /*
      Inputs: x1, y1, x2 and y2 -- the endpoints of the line. The line
				   stretches from (x1, y1) to (x2, y2)
              Grid view         -- an object representing the display

      Outputs: none, just draw the line

      Something useful: in order to draw the line, you must set a
	 	 	series of individual pixels. You can do this
	 	 	by making a call to the setPixel method of the
	 	 	Grid object. In other words, the command
	 	 	         view.setPixel(3,4); 
			would turn the pixel at position (3, 4) black.


      NOTE: If you want to have any auxiliary methods (helpers), you
	    must make sure to declare them "static" as well.

     */
    public static void BresenhamAlgorithm(int x1, int y1, 
					  int x2, int y2, Grid view) {

	// ***** YOUR CODE HERE *****
	int dx, dy, p = 0;
	int i, dt1 = 0, dt2 = 0, tk1 = 0, tk2 = 0;
	int oct, one_signed1 = 1, one_signed2 = 1;
	
	dx = x2 - x1;
	dy = y2 - y1;

	//determining what octant line segment falls
	//into. 
	//(i.e., if the first endpoint was located at
	//origin, in which octant would the second
	//endpoint be located?)

	if (dx > 0) {
	    if (dy > 0) {
		if (dx >= dy)
		    oct = 1;
		else
		    oct = 2;
	    }
	    else {
		if (dx >= (-1 * dy))
		    oct = 8;
		else
		    oct = 7;
	    }
	}
	else {
	    if (dy > 0) {
		if ((-1 * dx) >= dy)
		    oct = 4;
		else
		    oct = 3;
	    }
	    else {
		if (dx <= dy)
		    oct = 5;
		else
		    oct = 6;
	    }
	}

	//depending on octant, different params get different
	//values. this allows the use of only one for loop
	//below.

	switch (oct) {
	case 3:
	case 5:
	case 6:
	case 8: {
	    dx = x1 - x2;
	    dy = y1 - y2;
	    break;
	}
	}

	switch (oct) {
	case 1: 
	case 4: {
	    tk1 = x1;
	    tk2 = y1;
	    dt1 = dx;
	    dt2 = dy;
	    break;
	}
	
	case 2:
	case 3: {
	    tk1 = y1;
	    tk2 = x1;
	    dt1 = dy;
	    dt2 = dx;
	    break;
	}
	
	case 5:
	case 8: {
	    tk1 = x2;
	    tk2 = y2;
	    dt1 = dx;
	    dt2 = dy;
	    break;
	}

	case 6:
	case 7: {
	    tk1 = y2;
	    tk2 = x2;
	    dt1 = dy;
	    dt2 = dx;
	    break;
	}
	}
	
	switch (oct) {
	case 1:
	case 2:
	case 5:
	case 6: {
	    p = 2*dt2 - dt1;
	    break;
	}
	case 3:
	case 4:
	case 7:
	case 8: {
	    p = 2*dt2 + dt1;
	    break;
	}
	}
    
	switch (oct) {
	case 4:
	case 8: { 
	    one_signed1 = -1;
	    break;
	}
	case 3:
	case 7: {
	    one_signed2 = -1;
	    break;
	}
	}

	//Start off by displaying endpoints
	view.setPixel(x1, y1);
	view.setPixel(x2, y2);
	
	//If dt1 happens to be negative, still want following
	//for loop to run! So make it postive
	//(note: this could have been done earlier, during 
	//the definition of dt1. however, for the sake of
	//consistency, i chose to do it here.)

	if (dt1 < 0) 
	    dt1 = (-1) * dt1;

	//Note the use of only one for loop, w/ varying params

	//Also, instead of using 1 or -1, using variables
	//"one_signed1" and "one_signed2" so that i can vary
	//them for different octants and maintain only one
	//for loop.

	for (i=0; i < dt1; i++)  {
	    if (p < 0)  {
		tk1 = tk1 + one_signed1;
		p = p + 2*dt2;
	    }
	    else {
		tk1 = tk1 + one_signed1;
		tk2 = tk2 + one_signed2;
		p  = p + 2*dt2 - 2*dt1;
	    }
	    switch (oct) {
	    case 1:
	    case 4:
	    case 5:
	    case 8: {
		view.setPixel(tk1, tk2);
		break;
	    }

	    default: {
		view.setPixel(tk2, tk1);
		break;
	    }
	    }
	}
    
	
	//For debugging:
	System.out.println("Entering BresenhamAlgorithm. ");
		
    }
}









