
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "glut.h"
#include "glui.h"

#include "main2.h"
#include "structures.h"

#define MAX_NUM_ASCHANGES 524288

ASChange A1;
DisplayMatrix M1; // keeps number of ASChanges in each position
ASMatrix M2; // keeps cumulative number of ASChanges
DisplayMatrix M3; // keeps number of ASChanges in each position

ASChange AArray[MAX_NUM_ASCHANGES];

ASList AL1;

int currentDate = 20000101;
int firstDate = 20000101;
int maxDate = 20011131;

int numfiles;
char filenames[1000][64];
int currentfile = 0;

int selected4 = 0; // selected AS number for detail
int selected512 = 0; // selected AS number for detail

extern int showDetail;
extern int showOS;
extern int showOM;
extern int showCSM;
extern int showCMS;
extern int showCMM;
extern int showHSS;
extern int showBSS;
extern int showCSS;
extern int fade;
extern int showASDetail;

extern int show_date;

extern GLUI_Spinner *date_spinner;

extern int begin_date;
extern int date_window;

extern GLUI_Spinner *begin_date_spinner;
extern GLUI_Spinner *date_window_spinner;

extern int fixedbegin;

int BGPViewerTexMap[64][64];
GLubyte TextureBGPViewer[64][64][4];
GLuint texNameBGPViewer;



/*
float datetofloat(int d, int d2) {
	int n = 0;
	int n2 = 0;
	// day
	n += (d%100) - (firstDate%100);
	// month
	n += 31 * ((d%10000)/100 - (firstDate%10000)/100);
	// year
	n += 365 * (d/10000 - firstDate/10000);
	// day
	n2 += (d2%100) - (firstDate%100);
	// month
	n2 += 31 * ((d2%10000)/100 - (firstDate%10000)/100);
	// year
	n2 += 365 * (d2/10000 - firstDate/10000);
	return (float)n/(float)n2;
}
*/

void BGPViewer::Debug() {


/*

    FILE *fptr;
	char fname[64]; // raw data
	char fname2[64]; // matrix of num AS changes
	char fname3[64]; // matrix of cumulative
	char fname4[64]; // all AS changes
	int i,j,k;
	char buf[16];
	int cumulative;
	int b = 20000102;
	int e = 20010650;

	// for each file
	for (i=b;i<e;i++) {
		strcpy(fname,"../processed/md3-");
		sprintf(buf,"%f",i);
		strcat(fname,buf);
		sprintf(buf,"%f",i+1);
		strcat(fname,"-");
		strcat(fname,buf);
		strcpy(fname2,fname);
		strcpy(fname3,fname);
		strcpy(fname4,fname);
		strcat(fname,".a");
		strcat(fname2,".mat");
		strcat(fname3,".mat2");
		strcat(fname4,".detail");
		printf("filename %s\n",fname);
		fptr = fopen(fname,"rt");
		if (fptr!=NULL) {

			// put into M1. M1 tells how many ASChanges there are in each position

			M1.Initialize();
			while (!A1.ReadInput(fptr)) {
			   A1.PutInMatrix(&M1);
			}
			fclose(fptr);

			// count how many AS change cumulatively

			cumulative = 0;
			for (j=0;j<512;j++) {
				for (k=0;k<512;k++) {
					M2.n[j][k] = cumulative;
					cumulative += M1.n[j][k];
				}
			}
			assert(cumulative<MAX_NUM_ASCHANGES);

			// re-read the file, write all ASChanges to file

			fptr = fopen(fname,"rt");
			while (!A1.ReadInput(fptr)) {
			   A1.MatrixPos(j,k);
			   AArray[M2.n[j][k]] = A1;
			   M2.n[j][k] = M2.n[j][k] + 1;
			}
			fclose(fptr);

			printf ("maxAS %d minAS %d\n",ASChange::maxAS,ASChange::minAS);

		}
	}

  */

}


void BGPViewer::PreProcess() {

    FILE *fptr;
	char fname[64]; // raw data
	int i,j,k,ind,x,y;
	char buf[16];
	int cumulative;
	int b = 20000102;
	int e = 20011131;
	int total;
	ASChange ASC;

	// set the total number of ASChanges in each position to zero
	M1.Initialize();

	// for each file
	for (i=b;i<e;i++) {
		strcpy(fname,"../processed/md3-");
		sprintf(buf,"%f",i);
		strcat(fname,buf);
		sprintf(buf,"%f",i+1);
		strcat(fname,"-");
		strcat(fname,buf);
		strcat(fname,".a");
		printf("filename %s\n",fname);
		fptr = fopen(fname,"rt");
		if (fptr!=NULL) {
			// put into M1. M1 tells how many ASChanges there are in each position
			while (!A1.ReadInput(fptr)) {
				if ((A1.type == BSS) || (A1.type == HSS)) {
				   A1.PutInMatrix(&M1); // increments appropriate matrix position
				}
			}
			fclose(fptr);
		}			
	}

	// allocate memory in M2, a matrix of ASChange arrays

	M2.Initialize();
	for (i=0;i<512;i++) {
		for (j=0;j<512;j++) {
			if (M1.n[i][j] > 0) {
				M2.n[i][j] = new ASChange[M1.n[i][j]];
			}
		}
	}

	// re-read each file
	

	M3.Initialize(); // a temporary matrix to keep the current number of ASChanges

	// for each file
	for (i=b;i<e;i++) {
		strcpy(fname,"../processed/md3-");
		sprintf(buf,"%f",i);
		strcat(fname,buf);
		sprintf(buf,"%f",i+1);
		strcat(fname,"-");
		strcat(fname,buf);
		strcat(fname,".a");
		printf("filename %s\n",fname);
		fptr = fopen(fname,"rt");
		if (fptr!=NULL) {
			// put into M3. M3 tells current ASChanges there are in each position
			while (!A1.ReadInput(fptr)) {
				if ((A1.type == BSS) || (A1.type == HSS)) {
					A1.cdate = i;
					A1.MatrixPos(j,k);
					ind = M3.n[j][k];
					M2.n[j][k][ind] = A1;
					M3.n[j][k] = ind + 1;
				}
			}
			fclose(fptr);
		}			
	}
	


	// write all ASChanges to one of 8 * 8 files


	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			strcpy(fname,"../growthdata/mat");
			sprintf(buf,"%f",i);
			strcat(fname,buf);
			strcat(fname,"-");
			sprintf(buf,"%f",j);
			strcat(fname,buf);
			strcat(fname,".aschanges");
			fptr = fopen(fname,"wb");
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					fwrite(&(M1.n[i*64+x][j*64+y]),sizeof(int),1,fptr);
				}
			}
			total = 0;
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					total += M1.n[i*64+x][j*64+y];
				}
			}
			printf("%d ",total);
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					if (M1.n[i*64+x][j*64+y] > 0) {
						fwrite(M2.n[i*64+x][j*64+y],sizeof(ASChange),M1.n[i*64+x][j*64+y],fptr);
					}
				}
			}
			fclose(fptr);
		}
		printf("\n");
	}
	


}

void BGPViewer::ReadGrowth() {

	int i,j,ind,x,y;
	char fname[64];
	char buf[64];
	FILE *fptr;
	int n;

	M1.Initialize();
	M2.Initialize();

	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			strcpy(fname,"../growthdata/mat");
			sprintf(buf,"%f",i);
			strcat(fname,buf);
			strcat(fname,"-");
			sprintf(buf,"%f",j);
			strcat(fname,buf);
			strcat(fname,".aschanges");
			fptr = fopen(fname,"rb");
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					fread(&(M1.n[i*64+x][j*64+y]),sizeof(int),1,fptr);
				}
			}
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					if (M1.n[i*64+x][j*64+y] > 0) {
						M2.n[i*64+x][j*64+y] = new ASChange[M1.n[i*64+x][j*64+y]];
						n = fread(M2.n[i*64+x][j*64+y],sizeof(ASChange),M1.n[i*64+x][j*64+y],fptr);
					}
				}
			}
			fclose(fptr);
		}
	}

}


void BGPViewer::ReadFileContents() {

	int i,j,ind,x,y;
	char fname[64];
	char buf[64];
	FILE *fptr;
	int n;
	int total;
	ASChange ASC;

	M1.Initialize();
	M2.Initialize();

	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			strcpy(fname,"../growthdata/mat");
			sprintf(buf,"%f",i);
			strcat(fname,buf);
			strcat(fname,"-");
			sprintf(buf,"%f",j);
			strcat(fname,buf);
			strcat(fname,".aschanges");
			fptr = fopen(fname,"rb");
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					fread(&(M1.n[i*64+x][j*64+y]),sizeof(int),1,fptr);
				}
			}
			total = 0;
			for (x=0;x<64;x++) {
				for (y=0;y<64;y++) {
					total += M1.n[i*64+x][j*64+y];
				}
			}
			for (ind = 0; ind<total; ind++) {
				fread(&ASC,sizeof(ASChange),1,fptr);
			}
			fclose(fptr);
		}
	}

}


// do documentation of first program as well as this

// extend to detailed view

// have more detailed views

// extend to 3D

int BGPViewer::Animate() {

	char fname[64];
	char datepart[64];


	Draw();
/*
	if (playing) {

		if (show_date > maxDate) {
			show_date = firstDate;
			if (fixedbegin) {
				begin_date = firstDate;
				date_window = 0;
				date_window_spinner->set_int_val(date_window);
			} else {
				begin_date = date_off(firstDate,-date_window);
				begin_date_spinner->set_int_val(begin_date);
			}
		} else {
			UpdateDate(show_date);
			if (fixedbegin) {
				date_window++;
				date_window_spinner->set_int_val(date_window);
			} else {
				UpdateDate(begin_date);
				begin_date_spinner->set_int_val(begin_date);
			}
		}

	}
*/

	date_spinner->set_int_val(show_date);


	return 0;


}

void BGPViewer::MakeFileList() {

	char fname[64];
	int i;
	char buf[16];
	FILE *fptr;

	numfiles = 0;
	for(i = firstDate; i<maxDate; i++) {
		strcpy(fname,"../processed/md3-");
		sprintf(buf,"%f",i);
		strcat(fname,buf);
		sprintf(buf,"%f",i+1);
		strcat(fname,"-");
		strcat(fname,buf);
		strcat(fname,".mat");
		fptr = fopen(fname,"rb");
		if (fptr) {
			strcpy(filenames[numfiles],fname);
			numfiles++;
			fclose(fptr);
		} 
	}
	fptr = fopen("filelist.txt","wt");
	fprintf(fptr,"%d\n",numfiles);
	for (i=0;i<numfiles;i++) {
		fprintf(fptr,"%s\n",filenames[i]);
	}
	fclose(fptr);


}

void BGPViewer::ReadFileList() {

	FILE *fptr;
	int i;

	fptr = fopen("filelist.txt","rt");
	fscanf(fptr,"%d",&numfiles);
	for (i=0;i<numfiles;i++) {
		fscanf(fptr,"%s",filenames[i]);
	}
	fclose(fptr);



	fptr = fopen("aslist","rb");
	fread(&(AL1.NumDistinctAS),sizeof(int),1,fptr);
	fread(AL1.Indices,sizeof(int),65536,fptr);
	fclose(fptr);

	for (i=0;i<65536;i++) {
		if (AL1.Indices[i]!=0) printf("AS %d index %d\n",i,AL1.Indices[i]);
	}

	printf("\nnum distinct as %d\n",AL1.NumDistinctAS);

}


int BGPViewer::ReadInputFile(char *fname) {
/*
	char fname2[64];
	char fname3[64];
	FILE *fptr;
  fptr = fopen(fname,"rb");
  if (fptr!=NULL) {
	printf("reading file %s\n",fname);
	// read file of number of changes
	fread(M1.n,sizeof(int),512*512,fptr);
	fclose(fptr);
	strcpy(fname2,fname);
	strcat(fname2,"2");
	// read file of cumulative number of changes
	fptr = fopen(fname2,"rb");
	fread(M2.n,sizeof(int),512*512,fptr);
	fclose(fptr);
	strcpy(fname3,fname2);
	fname3[strlen(fname3)-4] = '\0';
	strcat(fname3,"detail");
	// read file of as changes
	fptr = fopen(fname3,"rb");
	//printf("number of aschanges read %d\n",M1.n[511][511]+M2.n[511][511]);
	fread(AArray,sizeof(ASChange),M1.n[511][511]+M2.n[511][511],fptr);
	fclose(fptr);
	return 0;
  } else {
	return 1;
  }
*/
	return 0;
}

float r[4] = { 0.0, 0.6, 0.8, 1.0 };
float g[4] = { 0.0, 0.0, 0.0, 0.0 };
float b[4] = { 1.0, 0.3, 0.0, 0.0 };

void BGPViewer::Draw() {

	int i,j;
	int val;
	int x,y;
	int ind;
	int discontinue;

	float fdate;

	glDisable(GL_LIGHTING);

	
	glEnable(GL_TEXTURE_2D);

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glBindTexture(GL_TEXTURE_2D, texNameBGPViewer);

	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0); glVertex2i(0,0);
	glTexCoord2f(0.0, 1.0); glVertex2i(0,512);
	glTexCoord2f(1.0, 1.0); glVertex2i(512,512);
	glTexCoord2f(1.0, 0.0); glVertex2i(512,0);
	glEnd();


	glDisable(GL_TEXTURE_2D);
/*
	for (i=0;i<512;i++) {
		for (j=0;j<512;j++) {
			discontinue = 0;
			for (ind=0;ind<M1.n[i][j] && !discontinue;ind++) {
				//printf("date is %d\n",M2.n[i][j][ind].cdate);
				if ((M2.n[i][j][ind].cdate > begin_date) && (M2.n[i][j][ind].cdate < show_date)) {
					fdate = datetofloat(M2.n[i][j][ind].cdate,show_date);
					glColor3f(0.6*fdate,0.2*fdate,0.0);
					glBegin(GL_POINTS);
					glVertex3f((float)i,(float)j,0.9*fdate);
					glEnd();
				}
				if (show_date == M2.n[i][j][ind].cdate) {
					glColor3f(1.0,1.0,0.0);
					glBegin(GL_POINTS);
					glVertex3i(i,j,1);
					glEnd();
					discontinue = 1;
				}
			}
		}
	}
*/
	for (i=0;i<512;i++) {
		for (j=0;j<512;j++) {
			discontinue = 0;
			for (ind=M1.n[i][j]-1;ind>=0 && !discontinue;ind--) {
				if (show_date == M2.n[i][j][ind].cdate) {
					glColor3f(1.0,1.0,0.0);
					glBegin(GL_POINTS);
					glVertex3i(i,j,1);
					glEnd();
					discontinue = 1;
				}
				if ((M2.n[i][j][ind].cdate > begin_date) && (M2.n[i][j][ind].cdate < show_date)) {
					fdate = datetofloat(M2.n[i][j][ind].cdate,show_date);
					//glColor3f(0.6*fdate,0.2*fdate,0.0);
					glColor3f(0.7*fdate,0.3,0.0);
					glBegin(GL_POINTS);
					glVertex3f((float)i,(float)j,0.9*fdate);
					glEnd();
					discontinue = 1;
				}
			}
		}
	}

/*

	glColor3f(0.3,0.3,0.3);
	glBegin(GL_LINES);
	glVertex3i(-10,0,0.5);
	glVertex3i(-10,512,0.5);
	glVertex3i(522,0,0.5);
	glVertex3i(522,512,0.5);
	glVertex3i(0,-10,0.5);
	glVertex3i(512,-10,0.5);
	glVertex3i(0,522,0.5);
	glVertex3i(512,522,0.5);
	glEnd();

	// draw the highlighted bars

	if (showASDetail) {
		glColor3f(0.0,0.8,1.0);
		glBegin(GL_LINES);
		if (selected4==0) {
			glVertex3i(-10,selected512,1);
			glVertex3i(-10,selected512+8,1);
			glVertex3i(-20,selected512-8,1);
			glVertex3i(-20,selected512+24,1);
		} else if (selected4==1) {
			glVertex3i(selected512,522,1);
			glVertex3i(selected512+8,522,1);
			glVertex3i(selected512-8,532,1);
			glVertex3i(selected512+24,532,1);
		} else if (selected4==2) {
			glVertex3i(522,512-selected512,1);
			glVertex3i(522,512-selected512-8,1);
			glVertex3i(532,512-selected512+16,1);
			glVertex3i(532,512-selected512-16,1);
		} else if (selected4==3) {
			glVertex3i(512-selected512,-10,1);
			glVertex3i(512-selected512-8,-10,1);
			glVertex3i(512-selected512+16,-20,1);
			glVertex3i(512-selected512-16,-20,1);
		}
		glEnd();
	}



	for (i=0;i<(M2.n[511][511]+M1.n[511][511]);i++) {
		if (((AArray[i].type==OS)&&(showOS))||
			((AArray[i].type==OM)&&(showOM))||
			((AArray[i].type==CSM)&&(showCSM))||
			((AArray[i].type==CMS)&&(showCMS))||
			((AArray[i].type==CMM)&&(showCMM))||
			((AArray[i].type==HSS)&&(showHSS))||
			((AArray[i].type==BSS)&&(showBSS))||
			((AArray[i].type==CSS)&&(showCSS))) {
			ind = AL1.Indices[AArray[i].AS];
			AArray[i].MatrixPos(x,y);
			if (AArray[i].type==OS) {
				glColor3f(1.0,0.0,1.0);
			} else if (AArray[i].type==CMS) {
				glColor3f(1.0,1.0,0.0);
			} else if (AArray[i].type==CSM) {
				glColor3f(0.0,1.0,1.0);
			} else if (AArray[i].type==CMM) {
				glColor3f(1.0,0.0,0.0);
			} else if (AArray[i].type==HSS) {
				glColor3f(0.0,0.0,1.0);
			} else if (AArray[i].type==BSS) {
				glColor3f(0.0,1.0,0.0);
			} else if (AArray[i].type==OM) {
				glColor3f(1.0,1.0,0.0);
			} else if (AArray[i].type==CSS) {
				glColor3f(0.3,0.8,0.5);
			}
			glBegin(GL_LINES);
			glVertex3f(x,y,1);
			if ((ind/512) % 4 == 0) {
				if ((showASDetail) && (selected4==0) && ((ind%512)>=selected512) && ((ind%512)<(selected512+8))) {
					glVertex3f(-20, (((ind % 512) - selected512) * 4) + (ind / 2048) + selected512 - 8, 1);
				} else if (!showASDetail) {
					glVertex3f(-10, ind % 512, 1);
				}
			} else if ((ind/512) % 4 == 1) {
				if ((showASDetail) && (selected4==1) && ((ind%512)>=selected512) && ((ind%512)<(selected512+8))) {
					glVertex3f((((ind % 512) - selected512) * 4) + (ind / 2048) + selected512 - 8, 532, 1);
				} else if (!showASDetail) {
					glVertex3f(ind % 512, 522, 1);
				}
			} else if ((ind/512) % 4 == 2) {
				if ((showASDetail) && (selected4==2) && ((ind%512)>=selected512) && ((ind%512)<(selected512+8))) {
					glVertex3f( 532, 512 -(((ind % 512) - selected512) * 4) - (ind / 2048) - selected512 + 16, 1);
				} else if (!showASDetail) {
					glVertex3f(522, 512 - ind % 512, 1);
				}
			} else if ((ind/512) % 4 == 3) {
				if ((showASDetail) && (selected4==3) && ((ind%512)>=selected512) && ((ind%512)<(selected512+8))) {
					glVertex3f( 512 -(((ind % 512) - selected512) * 4) - (ind / 2048) - selected512 + 16, -20, 1);
				} else if (!showASDetail) {
					glVertex3f(512 - ind % 512, -10, 1);
				}
			}
			//printf("AS %d index %d\n",AArray[i].AS,ind);
			glEnd();
		}
		if (fade) {
			if (((AArray[i].type==OS)&&(!showOS))||
				((AArray[i].type==OM)&&(!showOM))||
				((AArray[i].type==CSM)&&(!showCSM))||
				((AArray[i].type==CMS)&&(!showCMS))||
				((AArray[i].type==CMM)&&(!showCMM))||
				((AArray[i].type==HSS)&&(!showHSS))||
				((AArray[i].type==BSS)&&(!showBSS))||
				((AArray[i].type==CSS)&&(!showCSS))||
				(showASDetail)) {
				ind = AL1.Indices[AArray[i].AS];
				AArray[i].MatrixPos(x,y);
				if (AArray[i].type==OS) {
					glColor3f(0.5,0.0,0.5);
				} else if (AArray[i].type==CMS) {
					glColor3f(0.5,0.5,0.0);
				} else if (AArray[i].type==CSM) {
					glColor3f(0.0,0.5,0.5);
				} else if (AArray[i].type==CMM) {
					glColor3f(0.5,0.0,0.0);
				} else if (AArray[i].type==HSS) {
					glColor3f(0.0,0.0,0.5);
				} else if (AArray[i].type==BSS) {
					glColor3f(0.0,0.5,0.0);
				} else if (AArray[i].type==OM) {
					glColor3f(0.5,0.5,0.0);
				} else if (AArray[i].type==CSS) {
					glColor3f(0.1,0.4,0.2);
				}
				glBegin(GL_LINES);
				glVertex3f(x,y,1);
				if ((ind/512) % 4 == 0) {
					glVertex3f(-10, ind % 512, 0.5);
				} else if ((ind/512) % 4 == 1) {
					glVertex3f(ind % 512, 522, 0.5);
				} else if ((ind/512) % 4 == 2) {
					glVertex3f(522, 512 - ind % 512, 0.5);
				} else if ((ind/512) % 4 == 3) {
					glVertex3f(512 - ind % 512, -10, 0.5);
				}
				//printf("AS %d index %d\n",AArray[i].AS,ind);
				glEnd();
			}
		}
	}

*/

}



// use first 12 bits
// make a 64 X 64 texture map
void BGPViewer::MakeTextureMap() {

	int i,k,n,xupper,xlower,yupper,ylower,x,y;


	for (k=0;k<64*64;k++) {

	  xupper = yupper = 63;
	  xlower = ylower = 0;

	  for (i=0;i<5;i++) {
	    n = (k >> ((5-i)*2)) & 3;
		if (n&1) { 
		    xlower += (1+xupper-xlower)/2;
		} else {
			xupper = xlower + (1+xupper-xlower)/2 - 1;
		}
		if (n&2) {
			ylower += (1+yupper-ylower)/2;
		} else {
			yupper = ylower + (1+yupper-ylower)/2 - 1;
		}
	  }
 
	  n = k & 3;
	  if (n&1) {
		x = xupper;
	  } else {
		x = xlower;
	  }
      if (n&2) {
        y = yupper;
	  } else {
        y = ylower;
	  }

	  BGPViewerTexMap[x][y] = k;

	}

	int val;
	int s,t;

	int defaultAlignment;

	glGetIntegerv(GL_UNPACK_ALIGNMENT, &defaultAlignment);

	glEnable(GL_TEXTURE_2D);

	for (s=0; s<64; s++) {	
		for (t=0; t<64; t++) {
			val = BGPViewerTexMap[s][t]/32;
			TextureBGPViewer[s][t][0] = (GLubyte)val;
			TextureBGPViewer[s][t][1] = (GLubyte)val;
			TextureBGPViewer[s][t][2] = (GLubyte)val;
			TextureBGPViewer[s][t][3] = 255;
		}
	}


	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, &texNameBGPViewer);
	glBindTexture(GL_TEXTURE_2D, texNameBGPViewer);

	printf("BGP texture %d\n", (int)texNameBGPViewer);

	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, GL_RGBA, 64, 64, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, TextureBGPViewer);


	glDisable(GL_TEXTURE_2D);

	glPixelStorei(GL_UNPACK_ALIGNMENT, defaultAlignment);


}


// find the first 16 bits of IP Address represented by this x,y screen position
void BGPViewer::SelectIPSpace(int x, int y, DetailWindow &w) {

	int i,xupper,xlower,xmiddle,yupper,ylower,ymiddle;
	int FirstHalfIP = 0;
	int M;

	w.DetailX = w.xres * (x/w.xres);
	w.DetailY = w.yres * (y/w.yres);

	//printf("find ip of screen position %d %d\n",x,y);

	xupper = yupper = 512;
	xlower = ylower = 0;

	for (i=0;i<8;i++) {

		xmiddle = (xupper-xlower)/2 + xlower;
		ymiddle = (yupper-ylower)/2 + ylower;

		if (x >= xmiddle) {
			FirstHalfIP = FirstHalfIP | (0x8000 >> (i*2));
			xlower = xmiddle;
		} else {
			xupper = xmiddle;
		}

		if (y >= ymiddle) {
			FirstHalfIP = FirstHalfIP | (0x4000 >> (i*2));
			ylower = ymiddle;
		} else {
			yupper = ymiddle;
		}

	}

	if (w.mask > 8) {
		if (w.mask == 12) {
			sprintf(w.ipstring,"%d.%d.0.0/%d", FirstHalfIP/256, FirstHalfIP%256 & 240,w.mask);
		} else if (w.mask == 10) {
			sprintf(w.ipstring,"%d.%d.0.0/%d", FirstHalfIP/256, FirstHalfIP%256 & 192,w.mask);
		}
	} else {
		sprintf(w.ipstring,"%d.0.0.0/%d", FirstHalfIP/256,w.mask);
	}
	printf("ip address selected %s\n", w.ipstring);

}

void BGPViewer::DrawDetail(DetailWindow &win) {

	int start,end,i;

	int j,k;

	if ((win.DetailX < 0) || (win.DetailX >= 511) ||
		(win.DetailY < 0) || (win.DetailY >= 511)) {
		return;
	}
	//SelectIPSpace(win.DetailX,win.DetailY,win);
	for (j=0;j<win.xres;j++) {
		for (k=0;k<win.yres;k++) {

			for (i=0;i<M1.n[win.DetailX+j][win.DetailY+k];i++) {
				
				if (M2.n[win.DetailX+j][win.DetailY+k][i].cdate <= show_date) {
					M2.n[win.DetailX+j][win.DetailY+k][i].DrawInDetailMatrix(win.mask,win.x,win.y);
				}
			}
				/*
			start = M2.n[DetailX+j][DetailY+k];
			end = start + M1.n[DetailX+j][DetailY+k] - 1;
			for (i=start;i<=end;i++) {
				AArray[i].DrawInDetailMatrix(12);
			}
			*/
		}
	}

}


void BGPViewer::DrawTimeLine(int len) {

	float frac;

	glColor3f(0.3,0.3,0.3);
	glBegin(GL_LINES);
	glVertex3f(0.0,0.0,0.0);
	glVertex3f(len,0.0,0.0);
	glEnd();
	frac = (float)(currentfile*len)/(float)numfiles;
	glColor3f(0.7,0.7,0.7);
	glBegin(GL_LINES);
	glVertex3f(frac,-10.0,0.0);
	glVertex3f(frac,10.0,0.0);
	glEnd();

}

void BGPViewer::SelectTimeStep(float t) {
	currentfile = (int) (t * (float)numfiles);
}

void BGPViewer::SelectASDetail(int flag, int num) {
	selected4 = flag;
	selected512 = num;
	printf("detail AS %d %d\n", selected4, selected512);
}

void BGPViewer::UpdateDate(int & d) {
	if ((d%100)<31) {
		d++;
	} else if ((d%10000)<1200) {
		d-=(d%100);
		d+=101;
	} else {
		d-=(d%10000);
		d+=10101;
	}
}


void BGPViewer::BackOneDay(int & d) {
	if ((d%100)>1) {
		d--;
	} else if ((d%10000)>=101) {
		d-=100;
		d+=31;
	} else {
		d-=10000;
		d+=1231;
	}
}
