#include <iostream.h>
#include <math.h>

#include "fb.h"


/* COMP236 Programmers:  

  Homework assignment 2, due Feb 16.

  This is the file you should put your algorithms in.  
  Replace the routines named 

     myClipper()
     myLineRasterizer()
     myFillRasterizer()

  with your own code.  The polygon information for input and output
  are passed to the routines.  Also, the extents of the clipping
  window are passed to the clipper.

  Minimum Assignment:

     * Write a clipper which clips a convex polygon to a rectangular window.

         A polygon edge should be clipped to the edge of the pixel square.  Since
         integer coordinates refer to the centers of the pixels, the border you
	 are clipping to will have fractional coordinates.  For instance, if
	 "xl" is 100, then the left clipping line will have x-coordinate 99.5.

     * Write a line rasterizer that rasterizes the edges of a polygon.

         The criterion for correct output is specified in Foley et al. on
         page 72, section 3.2.  Specifically, for lines of slope -1 < s < 1,
         there should be only one set pixel per column.  Similarly, for steeper
         slopes, only one pixel per row.  We won't be doing "thick" lines.

     * Write a fill rasterizer that rasterizes the interior of a polygon.

         A pixel should be set if its centerpoint falls on the edge or
         in the interior of the polygon.

     Email me (stefan) if you want clarification.

     You may refer to Foley, et al. for details on various algorithms.
     You may use any algorithms you wish, including ones of your own
     invention.  In any case, briefly describe your methods.  We don't
     care about efficiency.  Just make sure they work.  Beware of
     lines with zero or undefined slope.  Whenever you divide or
     multiply, consider the consequences of values such as zero or
     near-infinity.

  Extra Credit Opportunities:

     * Write a clipper which clips a concave polygon to a rectangular window.
     * Write a fill rasterizer for concave polygons.
     * Write a fill or line rasterizer which does antialiasing (I haven't 
         discussed antialiasing, so see Foley et al. about that if you
         haven't already learned about it).

  Test Cases:

     The buttons on the interface throw test cases at your clipper and
     rasterizers.  There are currently 8 convex test cases and 6
     concave test cases.  Try them out.  THIS IS NOT THE COMPLETE SET
     OF TESTS.  It is just something to get you started.  I may use
     other tests for evaluating the assignment.  Probably I will make
     these tests available to all of you before the assignment is due.

  Using the interface:

     I discovered that the middle button wouldn't work on my Windows
     98 machine at home, so I no longer use the middle button for
     interaction.  The file fb.cpp provides the interface -- you don't
     need to alter it for this assignment.  If you alter it, please
     put it back before turning in your assignment.  Here's how some
     of the controls are used:

     right click & drag: pan the viewing window left, right, up, down.
     right click & drag w/ shift: zoom (drag up and down).
     left click: add a vertex to a polygon you are making
     space bar: close the polygon, and display clipping and rasterization results.
	 
     button "clear framebuffer": erases the polygon, clears the fb pixels
     radiobutton "fill rasterize/line rasterize": selects which of your rasterizers to call
     checkbox "show pixel margins": whether to show the gray border around fb pixels
     checkbox "show pixel centers": whether to show a dot at pixel centers
     button "test #": execute a test polygon (defined in files "convex#.txt" and "concave#.txt")
     radiobutton "convex/concave poly tests": whether test buttons use convex or concave test files.
     button "save": pressing this and THEN pressing a test button will store the currently displayed
	            polygon as that test.

*/

void
myClipper(poly_type clip_result[100], int *num_polies, poly_type P, int xl, int xr, int yt, int yb)
{
	// this clipper is terrible.  Doesn't work at all.  Replace with your code.
	
	// this always outputs just one poly (incorrectly) 
	*num_polies = 1;

	clip_result[0].clear();

	int j;
	for(j=0; j<P.n; j++)
	{
		double x = P.x[j];
		double y = P.y[j];
		if (x < (xl)) x = xl;
		if (x > (xr)) x = xr;
		if (y < (yt)) y = yt;
		if (y > (yb)) y = yb;
			
		clip_result[0].add_pair(x,y);
	}

	clip_result[0].close();

};

// used by the bad line rasterizer
void
midraster(double x1, double y1, double x2, double y2)
{
	double dx = x1 - x2;
	double dy = y1 - y2;
	if ((dx*dx + dy*dy) < 0.5) 
	{
		fbSetPixel((int)floor(y1+0.5),(int)floor(x1+0.5), 0.6, 0.6, 0.6);
		return;
	}
	else
	{
		midraster((x1+x2)/2, (y1+y2)/2, x2, y2);
		midraster(x1, y1, (x1+x2)/2, (y1+y2)/2);
	}
}

void
myLineRasterizer(poly_type *P, int N)
{
    // this line rasterizer works badly -- replace this with your code

	int i,j;

	for(i=0; i<N; i++)
	{
		for(j=1; j<P[i].n; j++)
		{
			midraster(P[i].x[j-1], P[i].y[j-1], P[i].x[j], P[i].y[j]);
		}
	}
};

void
myFillRasterizer(poly_type *P, int N)
{
// this rasterizer does nothing.  Replace with your code
}
