/*************************************************************************************/
static gdouble** readOneFile(gchar* fileName, gint n0, gint* nP, gdouble* dt)
{
	gint nPoints = 0;
	gdouble** Dipole= NULL;
	FILE* file;
	gchar t[BSIZE];
	gint i;
	gint k;
	file = fopen(fileName,"rb");
	if(!file) printf("I cannot open '%s'\n",fileName);
	if(!file) return 0;
	k = 0;
	*nP = 0;
	*dt = 0;
	while(!feof(file))
	{
		if(!fgets(t,BSIZE,file))break;
		if(strstr(t,"Maximum Steps") && strstr(t,"="))
		{
			nPoints = atoi(strstr(t,"=")+1);
		}
		if(strstr(t," Time Step") && strstr(t,"="))
		{
			*dt = atof(strstr(t,"=")+1);
		}
		if(nPoints>0 && *dt>0) break;
	}
	rewind(file);
	if(nPoints == 0 && nPoints<n0) { return NULL;}
	Dipole =   malloc(nPoints*sizeof(gdouble*));
        for(k=0;k<nPoints;k++) Dipole[k] = malloc(3*sizeof(gdouble));
	k = 0;
	while(!feof(file))
	{
		if(!fgets(t,BSIZE,file))break;
		if(strstr(t,"Dipole        ="))
		{
			gchar* tt = strstr(t,"=")+1;
			gchar dum[16];
			gint j;
			if(k<n0) { k++; continue;}
			for(i=0;i<strlen(t);i++) if(t[i]=='D' || t[i] == 'd') t[i] = 'e';
			for(j=0;j<3;j++)
			{
				gint ii = 15;
				dum[ii] = '\0';
				for(i=0;i<ii;i++) dum[i] = tt[i];
				Dipole[k-n0][j] = atof(dum);
				dum[ii] = '\0';
				tt += ii;
			}
			k++;
		}
		else continue;
		if(k==nPoints) break;
	}
	if(k!=nPoints) printf("Warning : k != nPoints in %s file\n",fileName);
	fclose(file);
	*nP = nPoints-n0;
	return Dipole;
}
/********************************************************************************/
static gint doAutoCorr(gdouble** Dipole, gdouble* X, gint M)
{
	int m,n,j;
	for (m = 0; m < M; m++) X[m] = 0.0;
	// This algorithm was adapted from the formulas given in
	// J. Kohanoff Comp. Mat. Sci. 2 221-232 (1994). The estimator 
	// formulation used here is unbiased and statistically consistent, 
   	// 
   	// Looping through all time origins to collect an average -
   	// 
	int NCorr = 3*M/4;
	int Nav = M - NCorr;
   	for (m = 0; m < NCorr; m++)
      	for (n = 0; n < Nav; n++)
            for (j = 0; j < 3; j++)
               X[m] += Dipole[n + m][j] * Dipole[n][j];
   	for (m = 0; m < NCorr; m++) X[m] /= Nav;
	return NCorr;
}
/********************************************************************************/
static gboolean read_admp_dipole_dipole_file(GabeditFileChooser *filesel, gint response_id)
{
	gchar* fileName = NULL;
	GtkWidget* entryN = NULL;
	gint n0      = 1;
	gdouble* X = NULL;
	gdouble* Y = NULL;
	gdouble* Ytmp = NULL;
	gdouble** Dipole = NULL;
	gdouble dt;
	gint M = 0;
	gint MC = 0;
	gint k;
	GtkWidget* xyplot;
	GtkWidget* window;
	GSList* lists = NULL;
	GSList* cur = NULL;
	gint nf = 0;
	if(response_id != GTK_RESPONSE_OK) return FALSE;

	lists = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(filesel));
	
	entryN = g_object_get_data (G_OBJECT (filesel), "EntryN");
	if(!entryN) return FALSE;
	n0     = atoi(gtk_entry_get_text(GTK_ENTRY(entryN)));
	if(n0<0) n0 = 0;

	create_popup_win(_("Please wait"));
	cur = lists;
	nf = 0;
	while(cur != NULL)
	{
		fileName = (gchar*)(cur->data);
		nf++;
		if(cur==lists)
		{
			Dipole = readOneFile(fileName, n0, &M, &dt);
			if(M<2) 
			{
    				Message(_("Error\n The number of steps <2 !\n"),_("Error"),TRUE);
				return FALSE;
			}
			X = g_malloc(M*sizeof(gdouble));
			Y = g_malloc(M*sizeof(gdouble));
			for(k=0;k<M;k++) X[k] = dt*k;
			MC = doAutoCorr(Dipole, Y, M);
			for(k=0;k<M;k++) g_free(Dipole[k]);
			g_free(Dipole);
		}
		else  
		{
			gint m = 0;
			gint mc = 0;
			gdouble dt0;
			Dipole = readOneFile(fileName, n0, &m, &dt0);
	
			if(m!=M || M<2) 
			{
    				Message(_("Error\n The number of steps is not same in all files\n"),_("Error"),TRUE);
				return FALSE;
			}

			Ytmp = g_malloc(m*sizeof(gdouble));
			mc = doAutoCorr(Dipole, Ytmp, m);
			for(k=0;k<M;k++) g_free(Dipole[k]);
			g_free(Dipole);
			for(k=0;k<MC;k++) Y[k] += Ytmp[k];
			g_free(Ytmp);
		}

		cur = cur->next;
	}
	if(nf>0) for(k=0;k<MC;k++) Y[k] /= nf;


	window = gabedit_xyplot_new_window(_("Dipole-Dipole autocorrelation"),NULL);
	xyplot = g_object_get_data(G_OBJECT (window), "XYPLOT");
	gabedit_xyplot_add_data_conv(GABEDIT_XYPLOT(xyplot),MC, X,  Y, 1.0, GABEDIT_XYPLOT_CONV_NONE,NULL);
	gabedit_xyplot_set_range_xmin (GABEDIT_XYPLOT(xyplot), 0.0);
	g_free(X); 
	g_free(Y);

	return TRUE;
}
