import display.*;

public class CohenSutherland {
    
    //vp.top doesnt work so the coords are hardcoded here:
    public static final int LEFT = -100;
    public static final int RIGHT = 100;
    public static final int TOP = 100;
    public static final int BOTTOM = -100;
    
    /*
      Inputs: the original line from (x1,y1) to (x2,y2), and a
      viewport The viewport object has four public instance variables,
      which can be accessed by: 
      var1 = viewport.top; 
      var2 = viewport.bottom; 
      var3 = viewport.left; 
      var4 = viewport.right;

      Output: a LineSegment object 
            You can create a LineSegment object by making the call
			      LineSegment ls = new LineSegment()

            Having created it, you must set five values: 
	    x1, y1, x2, y2    the coordinates of each of the
                              endpoints of the clipped line You set
                              these values by including the line
                              ls.setEndPoints(x1, y1, x2, y2); 
			      or alternatively, by setting each of
                              the endpoints individually: 
			      ls.x1 = x1;
                              ls.y1 = y1; 
			      etc.

	    clipType          The clip type can be set to three
	                      values:

			      "internal" if the input line segment
			      falls entirely within the clip region,
			      otherwise:

                              "clipped" if it was determined that
                              some part of the input line segment does
                              fall within the boundaries defined by the
                              clip region, otherwise:

			      "external" if NO part of the input
			      line segment falls within the clip region
			      (i.e. the entire line was clipped.)
                              
			      You can set these values by including
			      the java statements:
                                    ls.setClipType("internal");
			      OR
                                    ls.setClipType("clipped");
                              OR
                                    ls.setClipType("external");
    
	NOTE: If you want to have any auxiliary methods (helpers), you
	must make sure to declare them "static" as well.
    */

    public static LineSegment ClipSegment(double x1, double y1, double x2, double y2, Viewport vp) {
	
	
	// ******* YOUR CODE HERE *********

	//for debugging:
	System.out.println("Entering Cohen-Sutherland");
	
	LineSegment ls = new LineSegment();
	String codes[] = new String[2];
	boolean done = false;
	boolean clipped = false;
	
	while (!done) {
	        
	    codes[0] = new String(outcode(x1, y1, TOP, BOTTOM, LEFT, RIGHT));
	    codes[1] = new String(outcode(x2, y2, TOP, BOTTOM, LEFT, RIGHT));
	     
	    //if inside swap points and code
	    if (inside(x1,y1)&&(inside(x2,y2))){ 
		double tmp = x1; x1 = x2; x2 = tmp;
		tmp = y1; y1 = y2; y2 = tmp;
		String tmpStr = codes[0]; codes[0] = codes[1]; codes[1] = tmpStr;
	    }
	    if ((codes[0].equals("0000")) && (codes[1].equals("0000"))) {
		if (clipped) ls.setClipType("clipped");
		else ls.setClipType("internal");
		done = true;
		continue;
	    }
      
	    if (!(get_and_code(codes[0], codes[1]).equals("0000"))) {
		ls.setClipType("external");
		done = true;
		continue;
	    }
	    
	    double slope = 0;
	    if (x1!=x2)
		slope = (y2-y1)/(x2-x1);
	    
	    if (codes[0].charAt(3) == '1') {   // to the left 
		// compute intersection
		y1 += (LEFT - x1)*slope;
		x1 = LEFT;
		clipped = true;
	    }  // left
	    else if (codes[0].charAt(2) == '1') {  // to the right
		y1 += (RIGHT - x1)*slope;
		x1 = RIGHT;
		clipped = true;
	    }  // right
	    else if (codes[0].charAt(1) == '1') {  // below
		if (x2 != x1) x1 += (BOTTOM - y1)/slope;
		y1 = BOTTOM;
		clipped = true;
	    }
	    else if (codes[0].charAt(0) == '1') {  // top
		if (x2 != x1) x1 += (TOP - y1)/slope;
		y1 = TOP;
		clipped = true;
	    }
	  
	}
	ls.setEndPoints(x1, y1, x2, y2); 
	return ls;
    }    
	
    /*
      This method, given a point (x,y) and some clip region
      boundaries, should produce the binary clip codes for the
      Cohen-Sutherland algorithm.  
    */
    public static String outcode(double x, double y,
			      double top, double bottom, 
			      double left, double right) {

	StringBuffer resultString = new StringBuffer("0000");
	if (x < left) resultString.setCharAt(3, '1');
	if (x > right) resultString.setCharAt(2, '1');
	if (y < bottom) resultString.setCharAt(1, '1');
	if (y > top) resultString.setCharAt(0, '1');
	return (resultString.toString());
    }	
    
    public static String get_and_code(String code0, String code1)
    {
	StringBuffer and_code = new StringBuffer("0000");
	
	for(int i=0; i<4; i++) {
	    if ((code0.charAt(i) == '1') && (code1.charAt(i) == '1'))
		and_code.setCharAt(i, '1');
	}
	return (and_code.toString());
    }  

    public static boolean inside(double x, double y){
	if ((-200<x)&&(x<200)&&(-200<y)&&(y<200))
	    return (true);
	else
	    return (false);
    }
    
}





