#include <iostream.h>
#include <fstream.h>
#include <list>
#include "rectangle.H"

typedef list<Rectangle>::const_iterator RectItor;

const float THRESHOLD = .5;

//----------------------------------------------------------------------
// Member functions for Rectangle class
//----------------------------------------------------------------------

// Constructor -- sets all data members to zero.

Rectangle::Rectangle()
{
	lowX = lowY = highX = highY = 0;
}


// Constructor -- gives values to the data members.

Rectangle::Rectangle(int lx, int ly, int hx, int hy, float v)
{
	lowX = lx;
	lowY = ly;
	highX = hx;
	highY = hy;
	value = v;
}


// Computes the area of a rectangle

int Rectangle::Area() const
{
	return (highX-lowX) * (highY-lowY);
}

// Returns its value

float Rectangle::Value() const
{
	return value;
}


// A friend function of the Rectangle class that checks for overlap 
// between a pair of rectangles.  The function evaluates a function 
// whose value is TRUE if rectangles do NOT overlap, then negates it.

Boolean Overlap(/*in*/ Rectangle rec1, /*in*/ Rectangle rec2)
{
    return (!
	((rec1.highX <= rec2.lowX)  || 
	 (rec1.lowX >= rec2.highX)  ||
	 (rec1.highY <= rec2.lowY)  || 
	 (rec1.lowY >= rec2.highY)));
}


/*
// This is an alternative to the above which is logically equivalent.
// Note: this code is commented out.
Boolean Overlap(Rectangle rec1, Rectangle rec2)
{
    return (rec1.highX > rec2.lowX &&
            rec1.lowX < rec2.highX &&
	    rec1.highY > rec2.lowY &&
	    rec1.lowY < rec2.highY);
}
*/

// A friend function of the Rectangle class that computes a NEW rectangle
// that's the intersection of the two rectangles passed in.  If there's 
// no overlap, data members should be zeroed -- but the constructor for
// the rectangle class does that for us by default.  

Rectangle Intersection(/*in*/ Rectangle rec1, /*in*/ Rectangle rec2)
{
    Rectangle temp;

        if (Overlap(rec1, rec2)) {
            temp.lowX = rec1.lowX < rec2.lowX ? rec2.lowX : rec1.lowX;
            temp.lowY = rec1.lowY < rec2.lowY ? rec2.lowY : rec1.lowY;
            temp.highX = rec1.highX > rec2.highX ? rec2.highX : rec1.highX;
            temp.highY = rec1.highY > rec2.highY ? rec2.highY : rec1.highY;
	    temp.value = rec1.value * rec2.value;
        } 

        return temp;
}


//----------------------------------------------------------------------
// Code for manipulating the maps follows
//----------------------------------------------------------------------

// This function prompts the user for the name of a data file, opens it,
// and reads a series of rectangles from the file.  Each rectangle is
// described by five integers.  As rectangles are read from the file,
// they're stored into the list "rList".

void FillFromFile(/* out */ list<Rectangle> & rList)
{
    char filename[80];
    ifstream infile;
    int xl, yl, xh, yh;
    float v;

	cout << "Enter name of input file: ";
	cin >> filename;

	infile.open(filename);

	while (!infile)
	{
	    cout << "Invalid.  Please enter filename: ";
	    cin >> filename;
	    infile.open(filename);
	}
	
	infile >> xl >> yl >> xh >> yh >> v;
	while (infile)
	{
	    rList.push_back(Rectangle(xl,yl,xh,yh,v));
	    infile >> xl >> yl >> xh >> yh >> v;
	}

	cout << "Read " << rList.size() << " rectangles" << endl;
}


// Finds all intersections between the first list of rectangles and the
// second.  The resulting rectangles are left in the "out" list.

void ComputeOverlay(/* in */  list<Rectangle> in1,
		    /* in */  list<Rectangle> in2, 
		    /* out */ list<Rectangle> & out)
{
    RectItor i;
    RectItor j;

	for(i=in1.begin(); i!=in1.end(); i++)
	    for(j=in2.begin(); j!=in2.end(); j++)
	    {
		if (Overlap(*i, *j))
		    out.push_back(Intersection(*i, *j));
	    }
}


// Takes a list of rectangles, and prints out summary information.

void Summarize(/* in */ list<Rectangle> recs)
{
    RectItor i;
    int area = 0;
    int num = 0;

	for(i=recs.begin(); i!=recs.end(); i++) 
	{
	    area += (*i).Area();
	    if ((*i).Value() > THRESHOLD) num++;
	}
	    

	cout << "Number of rectangles: " << recs.size() << endl;
	cout << "Total area is " << area << endl;
	cout << num << " rectangles had values > 50%" << endl;
}

int main()
{

    list<Rectangle> input1;
    list<Rectangle> input2;
    list<Rectangle> output;

	FillFromFile(input1);	// Get first "map"
	FillFromFile(input2);	// Get second "map"

	// Compute all intersections

	ComputeOverlay(input1, input2, output);

	// Describe the results

	Summarize(output);

	return 0;
}

