#include "capture.h" 

extern int width ;
extern int height ;
extern int texWidth ;
extern int texHeight ;
extern int nbimage ;
extern int captureImage;
extern int captureImage_auto;
extern int T_TURN ;
extern GLfloat T_SPEED ;
extern float zoom ;
extern float angle_cam ;
extern GLfloat objectRotX;
extern GLfloat objectRotY;
extern int maillage;
extern int elevation;
extern float cam_x;
extern float cam_y;
extern int display_cursor;
extern GLfloat coef_elevation;
extern GLfloat zoom_elevation;
extern int NbLat;
extern double *ListCoordX;
extern double *ListCoordY;
extern double *ListCoordZ;
extern double *texture_E;
extern int tore;
/*	Donnees necessaires pour les noms de images	*/
extern char *vue;
extern char *serie;
extern int angle_tmp;

int limite_file = 1 ;
int count = 0;

 /* TGA header */
GLubyte TGAheader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // entete TGA non compresser
GLubyte infoHeader[6] ;


/* creation of the video file */
avi_t * openMovie()
{
	avi_t * file ;
	char * date = new char[30] ;
	struct tm * pdh ; 
	time_t intps ;

	intps=time(NULL); 
	pdh = localtime(&intps);
	strftime(date, 25, "video_%d_%m_%Y_%Hh%M", pdh) ;
	strcat(date, ".avi") ;
	
	file = AVI_open_output_file(date) ;
	
	char compression[4] = "RGB" ;
	AVI_set_video(file, width, height, 10.0, compression) ;
	
	printf("Debut de la capture video du fichier %s\n", date) ;
	return file ;
}


/* close of the video file */
void closeMovie(avi_t * file)
{
	AVI_close(file) ;
	puts("Fin de la capture video...") ;
}


/* take a screenshot */
void dobmp_TGA()
{
	char * date = new char[30] ;
	struct tm * pdh ; 
	time_t intps ;
	
	TRcontext *tr;
	GLubyte *buffer, *tile, *rowPtr;
	int curColumn, curTileWidth, curTileHeight;
	int bytesPerImageRow, bytesPerTileRow, bytesPerCurrentTileRow;
	int xOffset;
	
	int tileWidth = 512, tileHeight = 512, tileBorder = 0, more, i, j;
	
	intps = time(NULL) ; 
	pdh = localtime(&intps) ;
	strftime(date, 25, "image_%d_%m_%Y_%Hh%M-", pdh) ;
	char nb[5] ;
	//itoa(nbimage - captureImage + 1, nb, 10) ;
	sprintf(nb, "%d", nbimage - captureImage + 1) ;
	strcat(date, nb) ;
	strcat(date, ".tga") ;
	
	printf("Capture de l'image %s\n", date) ;

	//ouvrir le fichier
	FILE * file = fopen(date, "wb");

	//Enregistre l'entete
	fwrite(TGAheader, 1, sizeof(TGAheader), file);

	infoHeader[0] = (texWidth& 0x00FF);
	infoHeader[1] = (texWidth & 0xFF00) >> 8;
	infoHeader[2] = (texHeight& 0x00FF);
	infoHeader[3] = (texHeight & 0xFF00) >> 8;
	infoHeader[4] = 32;
	infoHeader[5] = 0;

	fwrite(infoHeader, 1, sizeof(infoHeader), file);

	fclose(file);
	
	tile = (GLubyte *)malloc(tileWidth*tileHeight*4*sizeof(GLubyte));
	buffer = (GLubyte *)malloc(texWidth*tileHeight*4*sizeof(GLubyte));
	//printf("test 1 %d %d\n",texWidth*tileHeight*4*sizeof(GLubyte), tileWidth*tileHeight*4*sizeof(GLubyte));
	
	tr = trNew();
	trTileSize(tr, tileWidth, tileHeight, tileBorder);
	trTileBuffer(tr, GL_RGBA, GL_UNSIGNED_BYTE, tile);
	trImageSize(tr, texWidth, texHeight);
	trRowOrder(tr, TR_TOP_TO_BOTTOM);
	
	if (elevation == 1)
		trOrtho(tr, -1.0*zoom_elevation, 1.0*zoom_elevation, -1.0*zoom_elevation, 1.0*zoom_elevation, 1, 10);
	else
		trOrtho(tr, -1.0, 1.0, -1.0, 1.0, 1, 10);
	//printf("test 2\n");
	
	file = fopen(date, "ab");
	
	glPixelStorei(GL_PACK_ALIGNMENT, 4);
	
	more = 1;
	while (more)
	{
		trBeginTile(tr);
		curColumn = trGet(tr, TR_CURRENT_COLUMN);
		glClearColor(0.1, 0.1, 0.1, 1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
		glEnable(GL_DEPTH_TEST);
		glPushMatrix();
		glRotatef(objectRotY, 0.0, 1.0, 0.0);
		glRotatef(objectRotX, 1.0, 0.0, 0.0);
		if (maillage == 0)
			drawListTriangles();
		else if (maillage == 1)
		{	
			if (elevation == 0)
				drawSphereEqui();
			else
				drawSphereEqui_Elevation();
		}
		glPopMatrix();
		if (display_cursor)
		{
			glPushMatrix();
			glRotatef(objectRotY, 0.0, 1.0, 0.0);
			glRotatef(objectRotX-90, 1.0, 0.0, 0.0);
			draw_mask();
			glPopMatrix();
		}
		glDisable(GL_DEPTH_TEST);
		//printf("test 3 1\n");
		more = trEndTile(tr);
		{
			bytesPerImageRow = texWidth*4*sizeof(GLubyte);
			//printf("test 3 1 1 %d\n",bytesPerImageRow);
			bytesPerTileRow = (tileWidth-2*tileBorder)*4*sizeof(GLubyte);
			//printf("test 3 1 2 %d\n",bytesPerTileRow);
			curTileWidth = trGet(tr, TR_CURRENT_TILE_WIDTH);
			//printf("test 3 1 3 %d\n",curTileWidth);
			xOffset = curColumn*bytesPerTileRow;
			//printf("test 3 1 4 %d\n",xOffset);
			bytesPerCurrentTileRow = (curTileWidth-2*tileBorder)*4*sizeof(GLubyte);
			//printf("test 3 1 5 %d\n",bytesPerCurrentTileRow);
			curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
			//printf("test 3 1 6 %d\n",curTileHeight);
			for (i=0; i<curTileHeight; i++)
			{
				memcpy(buffer+i*bytesPerImageRow+xOffset,
					tile+i*bytesPerTileRow, bytesPerCurrentTileRow);
			}
			//printf("test 3 1 7\n");
		}
		//printf("test 3 2\n");
		if (curColumn==trGet(tr, TR_COLUMNS)-1)
		{
			curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
			//printf("%d\n",curTileHeight);
			bytesPerImageRow = texWidth*4*sizeof(GLubyte);	
			//printf("%d\n",bytesPerImageRow);
			//fpixel[1] = trGet(tr, TR_CURRENT_COLUMN);		
			for (i=2*tileBorder; i<curTileHeight; i++)
			{
				rowPtr = buffer+(curTileHeight-1-i)*bytesPerImageRow;
				fwrite(rowPtr, 1, texWidth*4, file);
			} 
		}
		//printf("test 3 3\n");
	}
	
	trDelete(tr);

	//Enregistre l'image
	//fwrite(data, sizeof(float), texWidth*texHeight, file);

	fclose(file);
	
	free(tile);
	free(buffer);
	//printf("test 4\n");
	printf("Fin de la capture\n");
	
	captureImage-- ;	
	
	if( captureImage == 0 ) 
	{
		// on arrete la rotation et remet la vitesse de rotation par rapport au zoom
		T_TURN = -1;
		T_SPEED = zoom ;
	}
	
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	if (elevation==1)
		glOrtho(-1.0*zoom_elevation,1.0*zoom_elevation,-1.0*zoom_elevation,1.0*zoom_elevation,1,10);
	else
		glOrtho(-1.0,1.0,-1.0,1.0,1,10);

}

void dobmp_FITS()
{
	char * date = new char[30] ;
	struct tm * pdh ; 
	time_t intps ;
	
	TRcontext *tr;
	GLfloat *image;
	GLenum format, type;
	
	fitsfile * fptr;
	int datatype, bitpix, naxis, status = 0, N;
	long naxes[2], fpixel[2], nelements;
	
	int tileWidth = 512, tileHeight = 512, tileBorder = 0, more, i, j;
	
	intps = time(NULL) ; 
	pdh = localtime(&intps) ;
	strftime(date, 25, "image_%d_%m_%Y_%Hh%M-", pdh) ;
	char nb[5] ;
	//itoa(nbimage - captureImage + 1, nb, 10) ;
	sprintf(nb, "%d", nbimage - captureImage + 1) ;
	strcat(date, nb) ;
	strcat(date, ".fits") ;
	
	N = 1;
	format = GL_RED;
	type = GL_FLOAT;
	
	fits_create_file(&fptr, date, &status);
	
	naxis = 2;
	naxes[0] = (long)texWidth;
	naxes[1] = (long)texHeight;
	nelements = (long)texWidth*texHeight;
	datatype = TFLOAT;
	bitpix = FLOAT_IMG;
	fpixel[0] = 1;
	fpixel[1] = 1;
	
	fits_create_img(fptr, bitpix, naxis, naxes, &status);
	
	printf("Capture de l'image %s\n", date) ;
				
	image = (GLfloat *)malloc(texWidth*texHeight*N*sizeof(GLfloat));
	
	tr = trNew();
	trRowOrder(tr, TR_TOP_TO_BOTTOM);
	trTileSize(tr, tileWidth, tileHeight, tileBorder);
	trImageSize(tr, texWidth, texHeight);
	trImageBuffer(tr, format, type, image);
	
	
	if (elevation == 1)
		trOrtho(tr, -1.0*zoom_elevation, 1.0*zoom_elevation, -1.0*zoom_elevation, 1.0*zoom_elevation, 1, 10);
	else
		trOrtho(tr, -1.0, 1.0, -1.0, 1.0, 1, 10);
	
	more = 1;
	while (more)
	{
		trBeginTile(tr);
		
		glClearColor(0.1, 0.1, 0.1, 1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
		glEnable(GL_DEPTH_TEST);
		glPushMatrix();
		glRotatef(objectRotY, 0.0, 1.0, 0.0);
		glRotatef(objectRotX, 1.0, 0.0, 0.0);
		if (maillage == 0)
			drawListTriangles();
		else if (maillage == 1)
		{	
			if (elevation == 0)
				drawSphereEqui();
			else
				drawSphereEqui_Elevation();
		}
		if (tore == 1)
			drawTore();
		glPopMatrix();
		if (display_cursor)
		{
			glPushMatrix();
			glRotatef(objectRotY, 0.0, 1.0, 0.0);
			glRotatef(objectRotX-90, 1.0, 0.0, 0.0);
			draw_mask();
			glPopMatrix();
		}
		glDisable(GL_DEPTH_TEST);
		more = trEndTile(tr);
	}
	
	fits_write_pix(fptr, datatype, fpixel, nelements, image, &status);
	fits_report_error(stderr, status);

	fits_close_file(fptr, &status);

	fits_report_error(stderr, status);
	trDelete(tr);

	free(image);

	printf("Fin de la capture\n");
	
	captureImage-- ;	
	
	if( captureImage == 0 ) 
	{
		// on arrete la rotation et remet la vitesse de rotation par rapport au zoom
		T_TURN = -1;
		T_SPEED = zoom ;
	}
	
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	if (elevation==1)
		glOrtho(-1.0*zoom_elevation,1.0*zoom_elevation,-1.0*zoom_elevation,1.0*zoom_elevation,1,10);
	else
		glOrtho(-1.0,1.0,-1.0,1.0,1,10);

}

void dobmp_FITS_name(char *name)
{
	TRcontext *tr;
	GLfloat *image;
	GLenum format, type;
	
	int tmp, ele;
	
	fitsfile * fptr;
	int datatype, bitpix, naxis, status = 0, N;
	long naxes[2], fpixel[2], nelements;
	
	int tileWidth = 512, tileHeight = 512, tileBorder = 0, more, i, j;
	
	N = 1;
	format = GL_RED;
	type = GL_FLOAT;
	
	/*char nb[5] ;
	char *name = new char[30];
	char *char_tmp = new char[10];
	
	strcpy(name, vue);
	strcat(name, serie);
	strcat(name, "_a");
	if (angle_tmp<10)
		strcat(name, "0");
	sprintf(char_tmp,"%d",angle_tmp);
	strcat(name, char_tmp);
	strcat(name, "_");
	if (coef_elevation<0.09 && coef_elevation > 0.0)
		strcat(name, "00");
	else if (coef_elevation == 0.0)
		strcat(name, "0");
	ele = int(coef_elevation*100);
	sprintf(char_tmp, "%d", ele);
	strcat(name, char_tmp);
	strcat(name, "pc_");

	tmp = nbimage - captureImage_auto;
	sprintf(nb, "%d", tmp) ;
	if (tmp<10)
		strcat(name, "0");
	strcat(name, nb) ;
	strcat(name, ".fits") ;*/
	
	fits_create_file(&fptr, name, &status);
	
	naxis = 2;
	naxes[0] = (long)texWidth;
	naxes[1] = (long)texHeight;
	nelements = (long)texWidth*texHeight;
	datatype = TFLOAT;
	bitpix = FLOAT_IMG;
	fpixel[0] = 1;
	fpixel[1] = 1;
	
	fits_create_img(fptr, bitpix, naxis, naxes, &status);
	
	printf("Capture de l'image %s\n", name) ;
				
	image = (GLfloat *)malloc(texWidth*texHeight*N*sizeof(GLfloat));
	
	tr = trNew();
	trRowOrder(tr, TR_TOP_TO_BOTTOM);
	trTileSize(tr, tileWidth, tileHeight, tileBorder);
	trImageSize(tr, texWidth, texHeight);
	trImageBuffer(tr, format, type, image);
	
	
	if (elevation == 1)
		trOrtho(tr, -1.0*zoom_elevation, 1.0*zoom_elevation, -1.0*zoom_elevation, 1.0*zoom_elevation, 1, 10);
	else
		trOrtho(tr, -1.0, 1.0, -1.0, 1.0, 1, 10);
	
	more = 1;
	while (more)
	{
		trBeginTile(tr);
		
		glClearColor(0.1, 0.1, 0.1, 1.0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
		glEnable(GL_DEPTH_TEST);
		glPushMatrix();
		glRotatef(objectRotY, 0.0, 1.0, 0.0);
		glRotatef(objectRotX, 1.0, 0.0, 0.0);
		if (maillage == 0)
			drawListTriangles();
		else if (maillage == 1)
		{	
			if (elevation == 0)
				drawSphereEqui();
			else
				drawSphereEqui_Elevation();
		}
		if (tore == 1)
			drawTore();
		glPopMatrix();
		if (display_cursor)
		{
			glPushMatrix();
			glRotatef(objectRotY, 0.0, 1.0, 0.0);
			glRotatef(objectRotX-90, 1.0, 0.0, 0.0);
			draw_mask();
			glPopMatrix();
		}
		glDisable(GL_DEPTH_TEST);
		more = trEndTile(tr);
	}
	
	fits_write_pix(fptr, datatype, fpixel, nelements, image, &status);
	fits_report_error(stderr, status);

	fits_close_file(fptr, &status);

	fits_report_error(stderr, status);
	trDelete(tr);

	free(image);
	
	captureImage_auto-- ;	
	
	if( captureImage_auto == 0 ) 
	{
		// on arrete la rotation et remet la vitesse de rotation par rapport au zoom
		T_TURN = -1;
		T_SPEED = angle_cam ;
	}
	
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	if (elevation==1)
		glOrtho(-1.0*zoom_elevation,1.0*zoom_elevation,-1.0*zoom_elevation,1.0*zoom_elevation,1,10);
	else
		glOrtho(-1.0,1.0,-1.0,1.0,1,10);


}

/*void dobmp()
{
	char * date = new char[30] ;
	struct tm * pdh ; 
	time_t intps ;
	
	fitsfile * fptr;
	int datatype, bitpix, naxis, status = 0, test;
	long naxes[2], fpixel[2], nelements;
	
	int i, j;
	
	intps = time(NULL) ; 
	pdh = localtime(&intps) ;
	strftime(date, 25, "image_%d_%m_%Y_%Hh%M-", pdh) ;
	char nb[5] ;
	//itoa(nbimage - captureImage + 1, nb, 10) ;
	sprintf(nb, "%d", nbimage - captureImage + 1) ;
	strcat(date, nb) ;
	strcat(date, ".fits") ;
	
	fits_create_file(&fptr, date, &status);
	
	naxis = 2;
	naxes[0] = (long)texWidth;
	naxes[1] = (long)texHeight;
	//naxes[2] = (long)1;
	fpixel[0] = fpixel[1] = 1;
	nelements = (long)1*texWidth*texHeight;
	datatype = TFLOAT;
	bitpix = FLOAT_IMG;
	
	fits_create_img(fptr, bitpix, naxis, naxes, &status);
	fits_get_img_type(fptr, &test, &status);
	
	printf("Capture de l'image %s\n", date) ;
				
	float * rouge = new float[ texWidth * texHeight ];
	float * vert = new float[ texWidth * texHeight ];
	float * bleu = new float[ texWidth * texHeight ];
	float * data = new float[ texWidth * texHeight ];

	//Lire les donné depuis l'écran
	glReadPixels(0, 0, texWidth, texHeight, GL_RED, GL_FLOAT, rouge);
	glReadPixels(0, 0, texWidth, texHeight, GL_GREEN, GL_FLOAT, vert);
	glReadPixels(0, 0, texWidth, texHeight, GL_BLUE, GL_FLOAT, bleu);
	for (i=0; i<texWidth*texHeight; i++)
		data[i] = 0.2125*rouge[i]+0.7154*vert[i]+0.0721*bleu[i];

	//Enregistre l'image
	fits_write_pix(fptr, datatype, fpixel, texWidth*texHeight, data, &status);

	fits_close_file(fptr, &status);
	printf("status = %d\n", status);
	
	free(rouge);
	free(vert);
	free(bleu);
	free(data);

	//free(fptr);
	printf("Fin de la capture\n");
	
	captureImage-- ;	
	
	if( captureImage == 0 ) 
	{
		// on arrete la rotation et remet la vitesse de rotation par rapport au zoom
		T_TURN = -1;
		T_SPEED = zoom ;
	}
	
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	glOrtho(-1.0,1.0,-1.0,1.0,1,10);

}*/



/* add a frame to the video file */
void addFrame(avi_t * file)
{
	int i ;
	unsigned long len_file ;
	char * data = new char[3 * width * height] ;
	
	//Lire les donné depuis l'écran
	glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data) ;

	//les donné doivent etre au format RGB [ RED , GREEN , BLUE]
	//echange le Blue et le Red
	/*for(i = 0; i < (int) width * height * 3; i += 3)
	{
	//repete le XOR pour echangé les bytes 0 et 2
		data[i] ^= data[i + 2] ^= data[i] ^= data[i + 2];
	}*/
	AVI_write_frame(file,  data, (long) 3 * width * height, 0);

	// taille en Mo
	len_file = file->pos / (1024 * 1024) ;

	// avertissement tout les 100 Mo
	if(len_file > limite_file * 100)
	{
		printf("ATTENTION la video fait : %d Mo\n", len_file) ;
		limite_file++ ;
	}
}



