
#ifndef PARCOORDS_H
#define PARCOORDS_H


int findredblue(int p, Group *gptr) {
	int r, a, anyhasred, hasred, hri;
	r = 1; // assume red
	anyhasred = 0;
	for (a=0;a<Group::ncatdims;a++) {
		// check that there's some red
		hasred = 0;
		for (hri=0;hri<S.catrange[a];hri++) {
			if (projParallel[p][a][hri]==1) { hasred = 1; anyhasred = 1; }
		}
		// if any axis is blue, then it is blue
		if (hasred&&(projParallel[p][a][gptr->catcoords[a] - S.mins[a]]==0)) r = 0;
	}
	if (anyhasred == 0) r = 0; // if there are no reds at all in all axes, then blue
	return r;
}

class ParCoords {

private:

	int numaxes;
	float f;

public:

	ParCoords() : numaxes(0) { };

	void SetNumAxes(int n) {
		numaxes = n;
		f = 1.0/(float)(numaxes-1);
	};

	void RenderAxes(int p) {
		int i,j,k;
		char buffer[64];
		glLineWidth(1);
		for (i=0;i<numaxes;i++) {
			glColor3f(0.0,1.0,0.3);
			glBegin(GL_LINES);
			glVertex3f(f*(float)i,0.0,0.1);
			glVertex3f(f*(float)i,1.0,0.1);
			glEnd();
			for (j=0;j<S.catrange[i];j++) {
				glBegin(GL_LINES);
				if (projParallel[p][i][j]==0) {
					glColor3f(0.0,0.0,1.0);
				} else {
					glColor3f(1.0,0.0,0.0);
				}
				glVertex3f(f*(float)i,((float)j+0.25)/(float)S.catrange[i],1.0);
				glVertex3f(f*(float)i,((float)j+0.75)/(float)S.catrange[i],1.0);
				glEnd();

				if (showlabels) {
					strcpy(buffer,S.catmap[i][j]);
					glColor3f(0.0,0.0,0.0);
					for (k=0;k<strlen(buffer);k++) {
						glRasterPos3f(f*(float)i+0.01*(float)k,((float)j+0.25)/(float)S.catrange[i],1.0);
						glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10,buffer[k]);
					}
				}

			}
		}
	};

	
	void RenderZoomAxes(int p, int a, float s, float e) {
		int i,j,k;
		char buffer[128];
		glLineWidth(1);
		for (i=0;i<numaxes;i++) {
			glColor3f(0.0,1.0,0.3);
			glBegin(GL_LINES);
			glVertex3f(f*(float)i,0.0,0.1);
			glVertex3f(f*(float)i,1.0,0.1);
			glEnd();
			for (j=0;j<S.catrange[i];j++) {
				if (projParallel[p][i][j]==0) {
					glColor3f(0.0,0.0,1.0);
				} else {
					glColor3f(1.0,0.0,0.0);
				}
				if ((i==a)&&((e-s)>0.01)) {
					glBegin(GL_LINES);
					glVertex3f(f*(float)i,((((float)j+0.25)/(float)S.catrange[i])-s)/(e-s),1.0);
					glVertex3f(f*(float)i,((((float)j+0.75)/(float)S.catrange[i])-s)/(e-s),1.0);
					glEnd();
					if (showlabels) {
						strcpy(buffer,S.catmap[i][j]);
						glColor3f(0.0,0.0,0.0);
						for (k=0;k<strlen(buffer);k++) {
							glRasterPos3f(f*(float)i+0.01*(float)k,((((float)j+0.25)/(float)S.catrange[i])-s)/(e-s),1.0);
							glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10,buffer[k]);
						}
					}
				} else {
					glBegin(GL_LINES);
					glVertex3f(f*(float)i,((float)j+0.25)/(float)S.catrange[i],1.0);
					glVertex3f(f*(float)i,((float)j+0.75)/(float)S.catrange[i],1.0);
					glEnd();
					if (showlabels) {
						strcpy(buffer,S.catmap[i][j]);
						glColor3f(0.0,0.0,0.0);
						for (k=0;k<strlen(buffer);k++) {
							glRasterPos3f(f*(float)i+0.01*(float)k,((float)j+0.25)/(float)S.catrange[i],1.0);
							glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10,buffer[k]);
						}
					}
				}
			}
		}
	};



	void RenderZoom(int a, float s, float e) {
		glColor3f(0.0,0.0,0.0);
		glLineWidth(1);
		glBegin(GL_LINES);
		glVertex3f(f*(-0.1+(float)a),s,1.0);
		glVertex3f(f*(0.1+(float)a),s,1.0);
		glVertex3f(f*(-0.1+(float)a),e,1.0);
		glVertex3f(f*(0.1+(float)a),e,1.0);
		glEnd();
	};


	void Render(Group *gptr) {
		int i;
		int c;

		glLineWidth(1);
		c = gptr->category;
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


		if (R.highlightclass >= 0) {
			if (gptr->category==R.highlightclass) {
				glColor4f(0.8,0.0,0.0,0.5);
			} else {
				glColor4f(0.8,0.8,0.8,0.2);
			}
		} else {
			glColor4f(RadVizColors[c][0],RadVizColors[c][1],RadVizColors[c][2],0.1);
		}

		if (R.nocolor) glColor4f(0.0,0.0,0.0,1.0);

		if ((R.highlightclass >= 0)&&(gptr->category==R.highlightclass)) {
			if (!R.NoShowHighClass) {
				for (i=0;i<numaxes-1;i++) {
					glBegin(GL_LINES);
					glVertex3f(f*(float)i,gptr->parcoords[i],0.0);
					glVertex3f(f*(float)(i+1),gptr->parcoords[i+1],0.0);
					glEnd();
				}
			}
		} else {
			for (i=0;i<numaxes-1;i++) {
				if (R.background) {
					glBegin(GL_LINES);
					glVertex3f(f*(float)i,gptr->parcoords[i],0.0);
					glVertex3f(f*(float)(i+1),gptr->parcoords[i+1],0.0);
					glEnd();
				} else {
					glBegin(GL_LINES);
					glVertex3f(f*(float)i,gptr->parcoords[i],gptr->parcoords[i]);
					glVertex3f(f*(float)(i+1),gptr->parcoords[i+1],gptr->parcoords[i+1]);
					glEnd();
				}
			}
		}

		glDisable(GL_BLEND);
	};

	
	void RenderAuxiliary(Group *gptr, int a, float s, float e) {
		int i;
		int c;
		glLineWidth(1);
		c = gptr->category;
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(RadVizColors[c][0],RadVizColors[c][1],RadVizColors[c][2],0.1);
		for (i=0;i<numaxes-1;i++) {
			if ((i==a)&&((e-s)>0.01)) {
				glBegin(GL_LINES);
				glVertex3f(f*(float)i,(gptr->parcoords[i]-s)/(e-s),gptr->parcoords[i]);
				glVertex3f(f*(float)(i+1),gptr->parcoords[i+1],gptr->parcoords[i+1]);
				glEnd();
			} else if (((i+1)==a)&&((e-s)>0.01)) {
				glBegin(GL_LINES);
				glVertex3f(f*(float)i,gptr->parcoords[i],gptr->parcoords[i]);
				glVertex3f(f*(float)(i+1),(gptr->parcoords[i+1]-s)/(e-s),gptr->parcoords[i+1]);
				glEnd();
			} else {
				glBegin(GL_LINES);
				glVertex3f(f*(float)i,gptr->parcoords[i],gptr->parcoords[i]);
				glVertex3f(f*(float)(i+1),gptr->parcoords[i+1],gptr->parcoords[i+1]);
				glEnd();
			}
		}
		glDisable(GL_BLEND);
	};

};

#endif

