
#include <math.h>
#include "glut.h"
#include "arcs.h"
#include "spline.h"

ArcViz::ArcViz(int sx, int sy, int xs, int ys) : Visualization(sx,sy,xs,ys) , num_paths(0) { 
	linearNodeColors[0][0] = 1.0; linearNodeColors[0][1] = 0.0; linearNodeColors[0][2] = 0.0;
	linearNodeColors[1][0] = 0.0; linearNodeColors[1][1] = 1.0; linearNodeColors[1][2] = 0.0;
	linearNodeColors[2][0] = 0.0; linearNodeColors[2][1] = 0.0; linearNodeColors[2][2] = 1.0;
	linearNodeColors[3][0] = 1.0; linearNodeColors[3][1] = 0.5; linearNodeColors[3][2] = 0.0;
	linearNodeColors[4][0] = 1.0; linearNodeColors[4][1] = 0.0; linearNodeColors[4][2] = 1.0;
	linearNodeColors[5][0] = 0.5; linearNodeColors[5][1] = 0.5; linearNodeColors[5][2] = 0.5;
	linearNodeColors[6][0] = 0.0; linearNodeColors[6][1] = 1.0; linearNodeColors[6][2] = 0.5;

};

void ArcViz::DrawCircleSegment(float x1, float x2, float y, int cind1, int cind2) {


	float ang1, ang2;
	float midx, midy;
	float theta, theta1, theta2;
	float r;
	float cx, cy;
	float len;
	float frac;

	if (x2 < x1 + 0.01) return;

	midx = 0.5 * (x1 + x2);
	midy = y + archeight;

	ang1 = atan((midx-x1)/(midy-y));
	ang2 = PI - 2.0 * ang1;

	len = (midx-x1)/tan(ang2);
	r = len + (midy - y);
	cx = midx;
	cy = y - len;

	theta1 = atan(len/(x2-midx));
	theta2 = PI - theta1;

	glBegin(GL_LINE_STRIP);
	for (theta = theta1; theta <= theta2; theta += 0.001) {
		frac = (theta-theta1)/(theta2-theta1);
		glColor3f(((1.0-frac)*linearNodeColors[cind2][0])+(frac*linearNodeColors[cind1][0]),
			((1.0-frac)*linearNodeColors[cind2][1])+(frac*linearNodeColors[cind1][1]),
			((1.0-frac)*linearNodeColors[cind2][2])+(frac*linearNodeColors[cind1][2]));
		glVertex3f(cx + r * cos(theta),cy + r * sin(theta),0.0);
	}
	glEnd();


}



void ArcViz::Draw() {

	int i, j, cind1, cind2;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(startx, startx+xsize ,starty,starty+ysize);
			// left, right, bottom, top
	glViewport(startx, starty, xsize, ysize);
			// startx, starty, xsize, ysize
			// coordinates begin from lower left corner of window
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
    glDisable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);

	
	glPointSize(5);	
	glLineWidth(2);
	for (i=0;i<num_paths;i++) {
		for (j=0;j<pathlens[i]-1;j++) {
			cind1 = pathcolors[i][j];
			cind2 = pathcolors[i][j+1];
			glBegin(GL_POINTS);
			glColor3f(linearNodeColors[cind1][0],linearNodeColors[cind1][1],linearNodeColors[cind1][2]);
			glVertex3f(pathxs[i][j],pathy[i],0.1);
			glColor3f(linearNodeColors[cind2][0],linearNodeColors[cind2][1],linearNodeColors[cind2][2]);
			glVertex3f(pathxs[i][j+1],pathy[i],0.1);
			glEnd();
			DrawCircleSegment(pathxs[i][j],pathxs[i][j+1],pathy[i],cind1,cind2);
		}
	}

}


void ArcViz::AddPath() { 
	if (num_paths<MAX_ARCPATHS) {
		pathlens[num_paths] = 0;
		num_paths++; 
	}
}

void ArcViz::AddNode(int p, int id, int c_ind, float x) {
	if ((p>=0) && (p<num_paths)) {
		if (pathlens[p] < MAX_ARCPATHLEN - 1) {
			pathxs[p][pathlens[p]] = startx + 0.9 * x * xsize;
			pathnodelabels[p][pathlens[p]] = id;
			pathcolors[p][pathlens[p]] = c_ind;
			pathlens[p]++;
		}
	}
}

void ArcViz::SetPathY(int p, float y) {
	if ((p>=0) && (p<num_paths)) {
		pathy[p] = y;
	}
}



