/*********************************************************************************/
/*																				 */
/*						Generation de textures directement sur une sphere		 */
/*																				 */
/*	Programme base sur les travaux de P.Chainais et J.J.Lin : genTexture_rand	 */
/*																				 */
/*	Emilie KOENIG												18/07/2007		 */
/*																				 */
/*********************************************************************************/

#include "main.h"


void lecture_sub(FILE *file1)
{
	int i;
	double x, y, z;
	
	printf("Maillage de subdivision\n");
	fscanf(file1, "%d\n", &nb_sommets);
	printf("%d sommets sont utilises \n", nb_sommets);
	liste_sommets = (point4d_t *)malloc(nb_sommets*sizeof(point4d_t));
	for (i=0; i<nb_sommets; i++)
	{
		fscanf(file1, "%lf %lf %lf\n", &x, &y, &z);
		liste_sommets[i].x = x*Ray;
		liste_sommets[i].y = y*Ray;
		liste_sommets[i].z = z*Ray;
		liste_sommets[i].t = 1.0;
	}
		// Lecture des triangles
	fscanf(file1, "%d\n", &nb_triangles);
	printf("%d triangles sont utilises\n", nb_triangles);
	liste_trianglesInd = (triangleInd_t *)malloc(nb_triangles*sizeof(triangleInd_t));
	for (i=0; i<nb_triangles; i++)
		fscanf(file1, "%d %d %d\n", &liste_trianglesInd[i][0], &liste_trianglesInd[i][1], &liste_trianglesInd[i][2]);
		// Lecture des listes triees pour la recherche dichotomique
	fscanf(file1, "%d\n", &nb_sommets);
	liste_triee_x = (int *)malloc(nb_sommets*sizeof(int));
	liste_triee_y = (double *)malloc(nb_sommets*sizeof(double));
	for (i=0; i<nb_sommets; i++)
		fscanf(file1, "%d %lf\n", &liste_triee_x[i], &liste_triee_y[i]);
}


void lecture_equi(FILE *file1)
{
	int i;
	double x, y, z;
	
	printf("Maillage equiangulaire\n");
	fscanf(file1, "%d\n", &nb_sommets);
	nb_sommets = CARRE(nb_sommets);
	printf("%d sommets sont utilises\n", nb_sommets);
	liste_sommets = (point4d_t *)malloc(nb_sommets*sizeof(point4d_t));
	for (i=0; i<nb_sommets; i++)
	{
		fscanf(file1, "%lf %lf %lf\n", &x, &y, &z);
		liste_sommets[i].x = x*Ray;
		liste_sommets[i].y = y*Ray;
		liste_sommets[i].z = z*Ray;
		liste_sommets[i].t = 1.0;
	}
	liste_triee_y = (double *)malloc(nb_sommets*sizeof(double));
	for (i=0; i<nb_sommets; i++)
		fscanf(file1, "%lf\n", &liste_triee_y[i]);
}


void lecture_healpix(FILE *file1)
{
	int i;
	double x, y, z;
	
	printf("Maillage HEALPix\n");
	fscanf(file1, "%d\n", &nb_sommets);
	printf("%d sommets sont utilises\n", nb_sommets);
	liste_sommets = (point4d_t *)malloc(nb_sommets*sizeof(point4d_t));
	for (i=0; i<nb_sommets; i++)
	{
		fscanf(file1, "%lf %lf %lf\n", &x, &y, &z);
		liste_sommets[i].x = x*Ray;
		liste_sommets[i].y = y*Ray;
		liste_sommets[i].z = z*Ray;
		liste_sommets[i].t = 1.0;
	}
	liste_triee_y = (double *)malloc(nb_sommets*sizeof(double));
	for (i=0; i<nb_sommets; i++)
		fscanf(file1, "%lf\n", &liste_triee_y[i]);
	liste_phi = (double *)malloc(nb_sommets*sizeof(double));
	for (i=0; i<nb_sommets; i++)
		fscanf(file1, "%lf\n", &liste_phi[i]);
}


void ecriture_sub(FILE *file2)
{
	int i;
	FILE *file_autre;
	
	fprintf(file2, "%d\n", nb_triangles);
	for (i=0; i<nb_triangles; i++)
	{
		fprintf(file2, "%f %f %f %f %f %f %f %f %f %f %f %f\n",
			liste_sommets[liste_trianglesInd[i][0]].x/Ray, liste_sommets[liste_trianglesInd[i][0]].y/Ray, liste_sommets[liste_trianglesInd[i][0]].z/Ray, liste_sommets[liste_trianglesInd[i][0]].t,
			liste_sommets[liste_trianglesInd[i][1]].x/Ray, liste_sommets[liste_trianglesInd[i][1]].y/Ray, liste_sommets[liste_trianglesInd[i][1]].z/Ray, liste_sommets[liste_trianglesInd[i][1]].t,
			liste_sommets[liste_trianglesInd[i][2]].x/Ray, liste_sommets[liste_trianglesInd[i][2]].y/Ray, liste_sommets[liste_trianglesInd[i][2]].z/Ray, liste_sommets[liste_trianglesInd[i][2]].t);
	}
	
	file_autre = fopen("autre","w");
	if (!file_autre)
	{
		fprintf(stderr, "Erreur d'ouverture du fichier %s\n", file_autre);
		exit(1);
	}
	for (i=0; i<nb_sommets; i++)
	{
		fprintf(file_autre, "%f %f %f %f\n",
			liste_sommets[i].x/Ray, liste_sommets[i].y/Ray, liste_sommets[i].z/Ray, liste_sommets[i].t);
	}
	fclose(file_autre);
	file_autre = fopen("autre_ind","w");
	if (!file_autre)
	{
		fprintf(stderr, "Erreur d'ouverture du fichier %s\n", file_autre);
		exit(1);
	}
	for (i=0; i<nb_triangles; i++)
	{
		fprintf(file_autre, "%d %d %d\n",
			liste_trianglesInd[i][0], liste_trianglesInd[i][1], liste_trianglesInd[i][2]);
	}
	fclose(file_autre);
}


void ecriture_equi(FILE *file2)
{
	int i;

	fprintf(file2, "%d\n", (int)sqrt(nb_sommets));
	//Coordonnees des points de chaque anneau
	for (i=0; i<nb_sommets; i++)
	{
		fprintf(file2, "%f %f %f %f\n", liste_sommets[i].x/Ray, liste_sommets[i].y/Ray, liste_sommets[i].z/Ray, liste_sommets[i].t);
	}

}


void ecriture_healpix(FILE *file2)
{
	int i;

	fprintf(file2, "%d\n", nb_sommets);
	//Coordonnees des points de chaque anneau
	for (i=0; i<nb_sommets; i++)
	{
		fprintf(file2, "%f %f %f %f\n", liste_sommets[i].x/Ray, liste_sommets[i].y/Ray, liste_sommets[i].z/Ray, liste_sommets[i].t);
	}
	for (i=0; i<nb_sommets; i++)
	{
		fprintf(file2, "%f\n", liste_triee_y[i]);
	}
	for (i=0; i<nb_sommets; i++)
	{
		fprintf(file2, "%f\n", liste_phi[i]);
	}

}



/* Fonction de tirage d'une varaible aleatoire gaussienne centree de variance 1 */
double randn(void) {

  /* variables locales */

  double x1,x2,w;
  static unsigned char valeur_disponible=0;
  static double autre_valeur;


  if (!valeur_disponible) {

    /* tirage de deux valeurs suivant une loi normale */
    /* centree reduite et retour d'une d'elle         */

    do {
      x1=2.*randu()-1.;
      x2=2.*randu()-1.;
      w=CARRE(x1)+CARRE(x2);
    } while (w>=1.);
    w=sqrt((-2.*log(w))/w);
    autre_valeur=x1*w;
    valeur_disponible=1;
    return x2*w;

  } else {

    /* retour d'une valeur precedemment calculee */

    valeur_disponible=0;
    return autre_valeur;

  }
}

/**********************************************************************************/
/*	Programme principal															  */
/**********************************************************************************/

int main (int argc, char **argv)
{
	/* Donnees d'entree */
	char fentree[100], fsortie[100];
	FILE *file1, *file2;

	/* Donnees du fichier d'entree */
	int indic=0;

	
	int i = 0, tmp, nb_texture;
		
	double max, min;
	
	char * date;
	time_t intps;


	/**		Analyse des parametres d'entree		**/
	printf("Analyse des parametres\n");

	Ray = 1.0; r_min = 0.01; C = 1.0; param1 = 0.4; param2 = 0.1; L = 1.0;
	loi = 2; version = 1; motif = 1; graine = (unsigned long) 0;
	nb_texture = 1;
	
		// Lecture des entrees
	while ( ++i < argc )
	{
		if ( strcmp( argv[i], "-f" ) == 0 )
		{
			strcpy( fentree, argv[++i] );
			indic += 1;
		}
		if ( strcmp( argv[i], "-Ray" ) == 0 )
			Ray = atof( argv[++i] );
		if (strcmp(argv[i], "-L") == 0)
			L = atof(argv[++i]);
		if ( strcmp( argv[i], "-r" ) == 0 )
			r_min = atof( argv[++i] );
		if (strcmp(argv[i], "-l") == 0)
			loi = atof(argv[++i]);
		if (strcmp(argv[i], "-p") == 0)
		{
			param1 = atof(argv[++i]);
			param2 = atof(argv[++i]);
		} 
		if (strcmp(argv[i], "-m") == 0)
			motif = atof(argv[++i]);
		if (strcmp(argv[i], "-c") == 0)
			C = atof(argv[++i]);
		if (strcmp(argv[i], "-v") == 0)
			version = atof(argv[++i]);
		if (strcmp(argv[i], "-g") == 0)
			graine = atof(argv[++i]);
	}
	
		// Erreur si pas assez d'entrŽes
	if ( indic != 1 )
	{
		fprintf(stderr, "Usage complet : -Ray Ray -L L -r rmin -l loi -p param1 param2 -m motif -c C -v version -f input -g graine\n");
		fprintf(stderr, "Usage minimum : -f input\n");
		fprintf(stderr, "      Ray		: rayon de la sphere\n");
		fprintf(stderr, "      L		: grande echelle de la texture\n");
		fprintf(stderr, "      rmin		: resolution des details\n");
		fprintf(stderr, "      loi		: loi de distribution des multiplieurs : \n");
		fprintf(stderr, "						0 = defaut = log-Poisson\n");
		fprintf(stderr, "                      1 = log-normale\n");
		fprintf(stderr, "                      2 = log-exponentielle\n");
		fprintf(stderr, "                      3 = log-Bessel\n");
		fprintf(stderr, "      param	: parametres de la loi de distribution \n");
		fprintf(stderr, "      motif	: motif \n");
		fprintf(stderr, "      C		: concentration \n");
		fprintf(stderr, "      version	: version du calcul de la zone d'influence \n");
		fprintf(stderr, "      input	: fichier d'entree\n");
		fprintf(stderr, "      graine	: initialisation tirage de variable alŽatoire\n");
		exit( 1 );
	}
	if (indic ==1)
	{
		printf("rayon = %f\n L = %f\n   r_min = %f\n      loi = %d, parametres = (%f, %f)\n         motif = %d\n            version = %d\n", Ray, L, r_min, loi, param1, param2, motif, version);
	}


	
	/**		Lecture du fichier d'entree		**/
	printf("Lecture du fichier d'entree\n");
		// Ouverture du fichier
	file1 = fopen(fentree,"r");
	if (!file1)
	{
		fprintf(stderr, "Erreur d'ouverture du fichier %s\n", fentree);
		exit(1);
	}
		// Lecture des coordonnees des sommets
	
	fscanf(file1, "%d\n", &maillage);
	switch (maillage)
	{
		case SUBDIVISION :
			lecture_sub(file1);
			break;
		case EQUIANGULAIRE :
			lecture_equi(file1);
			break;
		case HEALPIX :
			lecture_healpix(file1);
			break;
	}
	fclose(file1);
	
	printf("Nombre de textures a generer : ");
	scanf("%d", &nb_texture);

	/**		Generation de la texture		**/
	for (tmp = 0; tmp<nb_texture; tmp ++)
	{
		printf("Generation de la texture nb %d\n", tmp+1);
		
		synthese(maillage);

		/**		Ecriture du fichier pour la visualisation		**/
		printf("Ecriture du fichier pour la visualisation\n");
	
		max = 0;
		min = 500;
		for(i=0; i<nb_sommets; i++)
		{
			if (liste_sommets[i].t >= max)
				max = liste_sommets[i].t;
			if (liste_sommets[i].t <= min)
				min = liste_sommets[i].t;
		}
		for(i=0; i<nb_sommets-1; i++)
			liste_sommets[i].t = (liste_sommets[i].t-min)/(max-min);
	
		date = (char *)calloc(30, sizeof(char));
		intps = time(NULL);
		strftime(date, 25, "texture_%d_%Hh%M", localtime(&intps));
		file2 = fopen(date,"w");
		if (!file2)
		{
			fprintf(stderr, "Erreur d'ouverture du fichier %s\n", fsortie);
			exit(1);
		}
		fprintf(file2, "%d\n", 4);
		fprintf(file2, "%d\n", maillage);
		switch (maillage)
		{
			case SUBDIVISION :
				ecriture_sub(file2);
				break;
			case EQUIANGULAIRE :
				ecriture_equi(file2);
				break;
			case HEALPIX :
				ecriture_healpix(file2);
				break;
		}
		fclose(file2);

	
		strftime(date, 25, "texture_%d_%Hh%M.log", localtime(&intps));
		file2 = fopen(date,"w");
		
		graine = get_mt();
		printf("graine = %lu \n",graine);
		
		if (maillage == SUBDIVISION)
			fprintf(file2, " maillage : %s\n", "maillage de subdivision");
		else if (maillage == EQUIANGULAIRE)
			fprintf(file2, " maillage : %s	B : %d\n", "maillage equiangulaire", (int)(sqrt(nb_sommets)/2));
		else if (maillage == HEALPIX)
			fprintf(file2, " maillage : %s\n", "maillage HEALPix");
		
		fprintf(file2, " Rayon : %f\n rmin : %f\n graine : %lu\n",  Ray, r_min, graine);
	
		if(loi == LOG_POISSON)
			fprintf(file2, " loi : %s\n", "log-Poisson");
		else if(loi == LOG_NORMAL)
			fprintf(file2, " loi : %s\n", "log-normale");
		else if(loi == LOG_EXP)
			fprintf(file2, " loi : %s\n", "log-exponentielle");
		else if(loi == LOG_BESSEL)
			fprintf(file2, " loi : %s\n", "log-Bessel");
	
		fprintf(file2, " parametres : %f %f\n", param1, param2);
	
		if (motif == DISQUE)
			fprintf(file2, " motif : %s\n", "disque");
		else if (motif == COS)
			fprintf(file2, " motif : %s\n", "shaper cos carre");
		else if (motif == EXP)
			fprintf(file2, " motif : %s\n", "shaper exponeniel");
		fclose(file2);

		free(date);
	}
	
	free(liste_trianglesInd);
	free(liste_sommets);
	free(liste_triee_x);
	free(liste_triee_y);

	return 0;
}


