#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <iostream>
#include <cmath>
using namespace std;

const int WIDTH = 800;
const int HEIGHT = 800;

const int MAXS = 120;
const double PI = 4*atan(1.0);

struct wallseg
{
	char type;
	int x, y;
	double cx, cy;
	double r;
	double ang1, ang2;
	int dx, dy;
} segs[MAXS+1];

void setCircle(wallseg& seg, int x1, int y1, int x2, int y2, int dx, int dy)
{
	double a = x2 -x1;
	double b = y2 - y1;
	double c = (x2*x2-x1*x1+y2*y2-y1*y1)/2.0;		// ax+by=c eqn of line of points equidistant from (x1,y1) and (x2,y2)

	double d = dx;
	double e = dy;
	double f = d*x1+e*y1;							// dx+ey=f eqn of line containing radius and (x1,y1)

	double den = a*e-b*d;
	if (den == 0) {
		cout << "ERROR: undefined circle starting at point " << x1 << ',' << y1 << endl;
		return;
	}
	seg.cx = (c*e - b*f)/den;
	seg.cy = (a*f - c*d)/den;
	seg.r = sqrt((seg.cx-x1)*(seg.cx-x1)+(seg.cy-y1)*(seg.cy-y1));
												// determine range of angles
	seg.ang1 = atan2(y1-seg.cy, x1-seg.cx);			// assume increasing from ang1
	seg.ang2 = atan2(y2-seg.cy, x2-seg.cx);
	double zcross = (x1-seg.cx)*dy - (y1-seg.cy)*dx;
	if (zcross < 0) {								// if z componet of cross product of radius vector with
		double tmp = seg.ang1;						//   tangent vector < 0, the decreasing from ang1
		seg.ang1 = seg.ang2;
		seg.ang2 = tmp;
	}
//	if (seg.ang1 < 0)			// don't think this is necesary
//		seg.ang1 += 2*PI;
//	if (seg.ang2 < 0)
//		seg.ang2 += 2*PI;
}

void inputRoom(int offset, int ns)
{
	for(int i=offset; i<offset+ns; i++) {
		cin >> segs[i].x >> segs[i].y >> segs[i].type;
		if (segs[i].type == 'c')
			cin >> segs[i].dx >> segs[i].dy;
	}
	segs[offset+ns] = segs[offset];
	for(int i=offset; i<offset+ns; i++) {
		if (segs[i].type == 'c') {
			setCircle(segs[i], segs[i].x, segs[i].y, segs[i+1].x, segs[i+1].y, segs[i].dx, segs[i].dy);
//cout << "circle at " << segs[i].x << ',' << segs[i].y << ": center = " << segs[i].cx <<',' << segs[i].cy << " radius = " << segs[i].r << ", arc from " << segs[i].ang1 << " to " << segs[i].ang2 << endl;
		}
		else {
			segs[i].dx = segs[i+1].x-segs[i].x;
			segs[i].dy = segs[i+1].y-segs[i].y;
		}
	}
}

void display(void)
{
	int nr, na, ng, ns;
	int tots = 0;
	int xmin, xmax, ymin, ymax;
	glClear(GL_COLOR_BUFFER_BIT);		// clear the window
	glColor3f(1.0, 1.0, 1.0);			// set color to white
	cin >> nr >> na >> ng;
	for(int i=0; i<nr; i++) {
		cin >> ns;
		inputRoom(tots, ns);
		if (tots == 0) {
			xmin = xmax = segs[0].x;
			ymin = ymax = segs[0].y;
			for(int i=1; i<ns; i++) {
				if (segs[i].x < xmin)
					xmin = segs[i].x;
				else if (segs[i].x > xmax)
					xmax = segs[i].x;
				if (segs[i].y < ymin)
					ymin = segs[i].y;
				else if (segs[i].y > ymax)
					ymax = segs[i].y;
			}
			double dx = xmax-xmin;
			double dy = ymax-ymin;
			dx = dy = 100;
			gluOrtho2D(xmin - dx/2.0, xmax + dx/2.0, ymin - dy/2.0, ymax + dy/2.0);
		}
		glBegin(GL_LINE_LOOP);
			glVertex2d(segs[tots].x, segs[tots].y);
			for(int i=0; i<ns; i++) {
				if (segs[tots+i].type == 'c') {
					double r = segs[tots+i].r;
					double cx = segs[tots+i].cx;
					double cy = segs[tots+i].cy;
					double a = segs[tots+i].ang1;
					double da = segs[tots+i].ang2 - segs[tots+i].ang1;
					int f = 1;
cout << "r, cx, cy, ang1, ang2, f = " << r << ',' << cx << ',' << cy << ',' << a << ',' << a+da << ',' << f << endl;
					if (da < 0)
						da += 2*PI;
					if (fabs(segs[tots+i].x - (cx+r*cos(a))) + fabs(segs[tots+i].y - (cy+r*sin(a))) > 0.1) {
						a = segs[tots+i].ang2;
						f = -1;
					}
						
//				if (da < 0)
//					da += 2*PI;
cout << "r, cx, cy, a, da, f = " << r << ',' << cx << ',' << cy << ',' << a << ',' << da << ',' << f << endl;
					da /= 100;
					for(int j=0; j<100; j++) {
						glVertex2d(cx + r*cos(a+f*j*da), cy + r*sin(a+f*j*da));
					}
				}
				else if (i < ns-1) 
					glVertex2d(segs[tots+i+1].x, segs[tots+i+1].y);
			}
		glEnd();
		glFlush();
		tots += ns;
	}
	glPointSize(5.0);
	glColor3f(1.0, 0.0, 0.0);			// set color to red
	glBegin(GL_POINTS);
	for(int i=0; i<na; i++) {
		double x, y, level;
		cin >> x >> y >> level;
		glVertex2d(x, y);
	}
	glEnd();
	glColor3f(0.0, 1.0, 0.0);			// set color to green
	glBegin(GL_POINTS);
	for(int i=0; i<ng; i++) {
		double x, y, level;
		cin >> x >> y >> level;
		glVertex2d(x, y);
	}
	glEnd();
	glFlush();
		
}

void myInit()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);	// black background
	glMatrixMode(GL_PROJECTION);		// set up view volume and projection
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key) {
		case 27:
		case 'q' :
			exit(0);
			break;
		default:
			break;
   }
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("first");
    glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
    myInit();
    glutMainLoop();
	return 0;
}
