
#include <stdio.h>
#include "glut.h"
#include "scatterplot.h"


Scatterplot3D::Scatterplot3D() : num_points(0) , x_rot(0.0) , y_rot(0.0) { }

Scatterplot3D::Scatterplot3D(int sx, int sy, int xs, int ys) : Visualization(sx,sy,xs,ys) , num_points(0) , 
x_rot(0.0) , y_rot(0.0) { }

void Scatterplot3D::Draw() {

	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective( // field of view in degree  , aspect ratio  , Z near , Z far 
					45.0, 1.0, 1.0, 100.0);	
	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);	
	gluLookAt(0.5,2.0,2.0,  // eye  
				0.5,0.5,0.5,      // center 
				0.0, 1.0, 0.0);      // up is in postive Y direction 
	glPushMatrix();


	glTranslatef(0.5,0.5,0.5);
	glRotatef(y_rot,1.0,0.0,0.0);
	glRotatef(x_rot,0.0,1.0,0.0);
	glTranslatef(-0.5,-0.5,-0.5);

	DrawPlot();

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texNameProjXY);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0); glVertex3i(0,0,0);
	glTexCoord2f(1.0, 0.0); glVertex3i(0,1,0);
	glTexCoord2f(1.0, 1.0); glVertex3i(1,1,0);
	glTexCoord2f(0.0, 1.0); glVertex3i(1,0,0);
	glEnd();
	glBindTexture(GL_TEXTURE_2D, texNameProjYZ);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0); glVertex3i(0,0,0);
	glTexCoord2f(1.0, 0.0); glVertex3i(0,0,1);
	glTexCoord2f(1.0, 1.0); glVertex3i(0,1,1);
	glTexCoord2f(0.0, 1.0); glVertex3i(0,1,0);
	glEnd();
	glDisable(GL_TEXTURE_2D);

}

void Scatterplot3D::DrawPlot() {
	int i;

	Cube C;
	for (i=0;i<num_points;i++) {
		glColor3f(point_colors[i][0],point_colors[i][1],point_colors[i][2]);
		C.Init(point_coords[i][0],point_coords[i][1],point_coords[i][2],0.02);
		C.Draw();
	}



}

void Scatterplot3D::AddPoint(float *coords, float *color, float size) {
	int i;
	if (num_points < MAX_SCATTERPLOT_POINTS) {
		for (i=0;i<3;i++) {
			point_coords[num_points][i] = coords[i];
			point_colors[num_points][i] = color[i];
			point_sizes[num_points] = size;
		}
		num_points++;
	}
}

void Scatterplot3D::MakeTexMaps() {

	int i;		
	int s,t,u;
	int defaultAlignment;

	glGetIntegerv(GL_UNPACK_ALIGNMENT, &defaultAlignment);
	glEnable(GL_TEXTURE_2D);

	// initialize the texture maps to opaque black
	for (s=0; s<SCATTERPLOT_TEXRES; s++) {	
		for (t=0; t<SCATTERPLOT_TEXRES; t++) {
			for (i=0;i<3;i++) {
				TextureProjXY[s][t][i] = 0;
				TextureProjXZ[s][t][i] = 0;
				TextureProjYZ[s][t][i] = 0;
			}
			TextureProjXY[s][t][3] = 255;
			TextureProjXZ[s][t][3] = 255;
			TextureProjYZ[s][t][3] = 255;
		}
	}
	// for each point (0-1 coords), project to each plane (0-255 coords)
	for (i=0; i<num_points;i++) {
		s = (int)(point_coords[i][0] * (float)SCATTERPLOT_TEXRES);
		t = (int)(point_coords[i][1] * (float)SCATTERPLOT_TEXRES);
		u = (int)(point_coords[i][2] * (float)SCATTERPLOT_TEXRES);
		if ((s>=0) && (s<SCATTERPLOT_TEXRES) && 
			(t>=0) && (t<SCATTERPLOT_TEXRES) &&
			(u>=0) && (u<SCATTERPLOT_TEXRES)) {
			TextureProjXY[s][t][0] = 255;
			TextureProjXY[s][t][1] = 255;
			TextureProjXY[s][t][2] = 255;
			TextureProjXZ[s][u][0] = 255;
			TextureProjXZ[s][u][1] = 255;
			TextureProjXZ[s][u][2] = 255;
			TextureProjYZ[t][u][0] = 255;
			TextureProjYZ[t][u][1] = 255;
			TextureProjYZ[t][u][2] = 255;
		}
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, &texNameProjXY);
	glGenTextures(1, &texNameProjXZ);
	glGenTextures(1, &texNameProjYZ);

	glBindTexture(GL_TEXTURE_2D, texNameProjXY);	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, SCATTERPLOT_TEXRES, SCATTERPLOT_TEXRES, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, TextureProjXY);

	glBindTexture(GL_TEXTURE_2D, texNameProjXZ);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, SCATTERPLOT_TEXRES, SCATTERPLOT_TEXRES, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, TextureProjXZ);

	glBindTexture(GL_TEXTURE_2D, texNameProjYZ);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, SCATTERPLOT_TEXRES, SCATTERPLOT_TEXRES, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, TextureProjYZ);

	glPixelStorei(GL_UNPACK_ALIGNMENT, defaultAlignment);

}

