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

Histogram::Histogram() : numlayers(0) , maxheight(0) { }

Histogram::Histogram(int sx, int sy, int xs, int ys, int r) : 
Visualization(sx,sy,xs,ys), resolution(r), numlayers(0), maxheight(0) { }

// depth, color
int Histogram::AddLayer(float d, float *c) {
	int i;
	if (numlayers<MAX_LAYERS) {
		depths[numlayers] = d;
		for (i=0;i<4;i++) colors[numlayers][i] = c[i];
		numlayers++;
		return (numlayers-1);
	} else {
		printf("histogram add layer error");
		return -1;
	}
}

// layer, data
void Histogram::AddData(int l, int *d) {
	int i;
	for (i=0;i<resolution;i++) {
		data[l][i] = d[i];
		if (d[i]>maxheight) maxheight = d[i];
	}
}

void Histogram::Draw() {

	int i, j;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,resolution,0,maxheight);
			// 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);
		
	for (i=0;i<numlayers;i++) {
		glColor4f(colors[i][0],colors[i][1],colors[i][2],colors[i][3]);
		for (j=0;j<resolution;j++) {
			glBegin(GL_QUADS);
			glVertex3f((float)j,0.0,depths[i]);
			glVertex3f((float)j,(float)data[i][j],depths[i]);
			glVertex3f((float)(j+1),(float)data[i][j],depths[i]);
			glVertex3f((float)(j+1),0.0,depths[i]);
			glEnd();
		}
	}

}

void Histogram::SetNumLayers(int i) { numlayers = i; }

void Histogram::SetResolution(int i) { resolution = i; }

Labelled_Histogram::Labelled_Histogram() : current_ind(0) { }

Labelled_Histogram::Labelled_Histogram(int sx, int sy, int xs, int ys, int r) :
Visualization(sx,sy,xs,ys), H(sx+50, sy+20, xs-100, ys-20, r) , current_ind(0) { }


int Labelled_Histogram::AddLayer(float d, float *c) { return (H.AddLayer(d,c)); }

void Labelled_Histogram::AddData(int l, int *d) { H.AddData(l,d); }

void Labelled_Histogram::Draw() {

	char buf[32];
	float x;

	H.Draw();


	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,startx+xsize,0,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);

	x = (float)H.startx + (float)current_ind/(float)H.resolution * H.xsize;


	glColor3f(0.1,0.1,0.1);
	glLineWidth(1);
	glBegin(GL_LINES);
	glVertex3f(x,(float)H.starty,0.0);
	glVertex3f(x,(float)H.starty-10.0,0.0);
	glEnd();

	glBegin(GL_TRIANGLES);
	glVertex3f(x,(float)H.starty,0.0);
	glVertex3f(x-5.0,(float)H.starty-5.0,0.0);
	glVertex3f(x+5.0,(float)H.starty-5.0,0.0);
	glEnd();

	sprintf(buf,"%d",labels[current_ind]);
	glRasterPos3f(x,starty,0.0);
	NT.font.Render(buf);

}

void Labelled_Histogram::ScreenToData(int sx, int &d) {
	int i;
	d = -1;
	if (sx>H.startx && sx<(H.startx+H.xsize)) {
		i = (int)((float)(sx-H.startx)/(float)H.xsize * (float)H.resolution);
		if ((i>=0) && (i<H.resolution)) d = labels[i];
	}
}


void Labelled_Histogram::DataToScreen(int d, int &sx) {
	int i;
	sx = -1;
	for (i=0;i<H.resolution;i++) {
		if (labels[i]==d) {
			sx = H.startx + (int)((float)i/(float)H.resolution * (float)H.xsize);
			return;
		}
	}
}

void Labelled_Histogram::AddLabels(int *d) {
	for (int i=0;i<H.resolution;i++) labels[i] = d[i];
}

void Labelled_Histogram::SetNumLayers(int i) { H.SetNumLayers(i); }

void Labelled_Histogram::SetResolution(int i) { H.SetResolution(i); }

void Labelled_Histogram::Advance() { if (current_ind < H.resolution-1) current_ind++; }

void Labelled_Histogram::Back() { if (current_ind > 0) current_ind--; }

void Labelled_Histogram::SetInd(int ind) {
	for (int i=0;i<H.resolution;i++) {
		if (labels[i]==ind) current_ind = i;
	}
}


