// Copyright 1999
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

// Shell.cpp ... Three Samples: Random Circles, Simple Quilts, Random Quilts

///////////////////////////////////////////////////////////////////////////////

// The standard include files that include traditional C and C++ headers and
// many other Core Tools headers ... see CHeaders.h for additional details

#include "IOTools.h"
#include "Graphics.h"
#include "Random.h"


void RandomColor() {
	byte r = RandomLong(0, 255);
	byte g = RandomLong(0, 255);
	byte b = RandomLong(0, 255);

	SetForeColor(r, g, b);
}


void RandomCircles() {

	cout << "Random Circles" << endl << endl;

	int count;

	while(ReadingInt("How many circles?", count)) {
		int x;
		int y;
		int radius;

		int i;

		ClearDrawing();

		for (i = 0; i < count; i++) {
			RandomColor();

			x = RandomLong(0, 299);
			y = RandomLong(0, 299);
			radius = RandomLong(5, 25);

			PaintCircle(x, y, radius);
		}
	}

	cout << endl;
}


void SimpleQuilts() {

	cout << "Simple Quilts" << endl << endl;

	int rows, cols;

	while (ReadingInt("Quilt Rows:", rows) && ReadingInt("Quilt Cols:", cols)) {
		cout << endl;

		if ((rows > 50) || (cols > 50)) {
			cout << "Too many rows or cols" << endl << endl;
			continue;
		}

		ClearDrawing();

		int row, col;
		
		for (row = 0; row < rows; row++) {
			int y1 = row * 300 / rows;
			int y2 = (row + 1) * 300 / rows;

			for (col = 0; col < cols; col++) {
				int x1 = col * 300 / cols;
				int x2 = (col + 1) * 300 / cols;

				RandomColor();
				PaintRect(x1, y1, x2, y2);
			}
		}
	}

	cout << endl;
}


void RectangleBlock(int x1, int y1, int x2, int y2) {
	RandomColor();
	FillRect(x1, y1, x2, y2);
}


void TwoTriangleBlockA(int x1, int y1, int x2, int y2) {
	// two triangles: upper left and lower right
	PolygonWidget PW;
	PW.ChangeMemory(4).SetFill();

	RandomColor();
	PW.Append(x1, y1);
	PW.Append(x2, y1);
	PW.Append(x1, y2);
	PW.ClosePolygon().Draw();

	PW.ClearPolygon();

	RandomColor();
	PW.Append(x2, y2);
	PW.Append(x2, y1);
	PW.Append(x1, y2);
	PW.ClosePolygon().Draw();
}


void TwoTriangleBlockB(int x1, int y1, int x2, int y2) {
	// two triangles: upper right and lower left
	PolygonWidget PW;
	PW.ChangeMemory(4).SetFill();

	RandomColor();
	PW.Append(x2, y1);
	PW.Append(x2, y2);
	PW.Append(x1, y1);
	PW.ClosePolygon().Draw();

	PW.ClearPolygon();

	RandomColor();
	PW.Append(x1, y2);
	PW.Append(x2, y2);
	PW.Append(x1, y1);
	PW.ClosePolygon().Draw();
}


void FourTriangleBlock(int x1, int y1, int x2, int y2) {
	PolygonWidget PW;
	PW.ChangeMemory(4).SetFill();

	int xc = (x1 + x2)/2;
	int yc = (y1 + y2)/2;

	RandomColor();
	PW.Append(xc, yc);
	PW.Append(x1, y1);
	PW.Append(x2, y1);
	PW.ClosePolygon().Draw();

	PW.ClearPolygon();

	RandomColor();
	PW.Append(xc, yc);
	PW.Append(x2, y1);
	PW.Append(x2, y2);
	PW.ClosePolygon().Draw();

	PW.ClearPolygon();

	RandomColor();
	PW.Append(xc, yc);
	PW.Append(x2, y2);
	PW.Append(x1, y2);
	PW.ClosePolygon().Draw();

	PW.ClearPolygon();

	RandomColor();
	PW.Append(xc, yc);
	PW.Append(x1, y2);
	PW.Append(x1, y1);
	PW.ClosePolygon().Draw();
}


void RandomQuiltBlock(int x1, int y1, int x2, int y2) {
	switch (RandomLong(0, 3)) {
		case 0:
			RectangleBlock(x1, y1, x2, y2);
			break;

		case 1:
			TwoTriangleBlockA(x1, y1, x2, y2);
			break;

		case 2:
			TwoTriangleBlockB(x1, y1, x2, y2);
			break;

		case 3:
			FourTriangleBlock(x1, y1, x2, y2);
			break;

		default:
			break;
	}
}


void RandomQuilts() {

	cout << "Random Quilts" << endl << endl;

	int rows, cols;

	while (ReadingInt("Quilt Rows:", rows) && ReadingInt("Quilt Cols:", cols)) {
		cout << endl;

		if ((rows > 50) || (cols > 50)) {
			cout << "Too many rows or cols" << endl << endl;
			continue;
		}

		ClearDrawing();

		int row, col;
		
		for (row = 0; row < rows; row++) {
			int y1 = row * 300 / rows;
			int y2 = (row + 1) * 300 / rows;

			for (col = 0; col < cols; col++) {
				int x1 = col * 300 / cols;
				int x2 = (col + 1) * 300 / cols;

				RandomQuiltBlock(x1, y1, x2, y2);
			}
		}
	}

	cout << endl;
}


int main(int argc, char* argv[]) {

	// Build graphics window 0
	GraphicsWindow GW0(300, 300);

	// Move the console below graphics window 0
	ConsolePlaceBelow(0);

	// Give the console the focus for user interaction
	MakeConsoleForeground();

//////////

	// initialize global random seed
	SetRandomSeed();

	// do random circles
	RandomCircles();

	// do simple quilts
	SimpleQuilts();

	// do random quilts
	RandomQuilts();

//////////

	PressReturn("\nThe main program is about to terminate\n");

	return 0;
}
