// Emacs will be in -*- Mode: c++ -*-
//
// ********** DO NOT REMOVE THIS BANNER **********
//
// SUMMARY: Language for a Finite Element Method
// RELEASE: 2.0     
// USAGE  : You may copy freely these files and use it for    
//          teaching or research. These or part of these may   
//          not be sold or used for a commercial purpose with- 
//          out our consent : fax (33)1 44 27 44 11        
//
// AUTHORS:  D. Bernardi, Y. Darmaillac F. Hecht,    
//           P. Parole O. Pironneau C. Prud'homme
// ORG    :          
// E-MAIL :   pironneau@ann.jussieu.fr     
//
// ORIG-DATE:     June-94
// LAST-MOD:      4-Feb-97 at 20:26:49 by Christophe Prud'homme
//
// DESCRIPTION:  
// DESCRIP-END.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <opclass.h>
#include <disk.h> 

#define NEXTLINE(ETIQ) {char c;while (((c = fgetc(ETIQ)) != '\n') && !feof(ETIQ));}
#define END_OF_LINE(data,i,incr) { if (dummy == incr) {dummy = 0;fprintf(data,"\n");} else dummy ++;}

extern int N;

char *
readprog (char *path)
{
  long count;
  int l = 1;
  FILE *f;
  char *tmp = NULL;

  if ((f = fopen (path, "r")) == NULL)
    {
      fprintf (stderr, "Freefem::readprog error : Cannot read %s\n", path);
      exit(-1);
    }
  count = 0;
  while (!feof (f))
    {
      fgetc (f);
      count++;
    }
  rewind (f);
  tmp = new char[count + 255];
  memset(tmp, 0, (count + 255)*sizeof(char));
  tmp[0] = '{';			/* place program between braces */
  while (!feof (f))
    {
      fgets (tmp + l, 255, f);
      /*fputs (tmp + l, stdout);*/
      l = strlen (tmp);
    }
  tmp[l] = '}';
  l++;
  fclose (f);

  return tmp;
}

int 
loadtriangulation (triangulation *t, char *path)
{
  int i;
  FILE* data;
  char *result = NULL;
  int dummy;

  if ((data = fopen (path,"r")) == NULL)
    return 1;
  /*
   * strstr is found in string.h
   *  => portability problems
   */
  if ((result = strstr (path,".amdba")) != NULL) /* amdba format */
    {
      fscanf(data,"%ld %ld",&t->np,&t->nt);
      NEXTLINE (data);

      if (t->rp) {delete [] t->rp;t->rp = NULL;} 
      if (t->tr) {delete [] t->tr;t->tr = NULL;} 
      if (t->ng) {delete [] t->ng;t->ng = NULL;}
      if (t->ngt) {delete [] t->ngt;t->ngt = NULL;}      

      t->rp = new rpoint[t->np];
      t->tr = new triangle[t->nt];
      t->ng = new int[t->np];
      t->ngt = new int[t->nt];
      
      for (i = 0; i < t->np; i++)
	fscanf (data,"%d %f %f %d",&dummy, &t->rp[i].x,&t->rp[i].y,&t->ng[i]);

      for (i = 0; i < t->nt; i++)
        {
	  fscanf (data,"%d %ld %ld %ld %d",&dummy, &t->tr[i][0],&t->tr[i][1],&t->tr[i][2],&t->ngt[i]);
	  t->tr[i][0]--;
          t->tr[i][1]--;
          t->tr[i][2]--;
        }
    }
  else if ((result = strstr (path,".am_fmt")) != NULL)/* am_fmt format */
    {
      fscanf(data,"%ld %ld",&t->np,&t->nt);
      NEXTLINE (data);

      if (t->rp) {delete [] t->rp;t->rp = NULL;} 
      if (t->tr) {delete [] t->tr;t->tr = NULL;} 
      if (t->ng) {delete [] t->ng;t->ng = NULL;}
      if (t->ngt) {delete [] t->ngt;t->ngt = NULL;}

      t->rp = new rpoint[t->np];
      t->tr = new triangle[t->nt];
      t->ng = new int[t->np];
      t->ngt = new int[t->nt];

      for (i = 0; i < t->nt; i++)
        {
	  fscanf (data,"%ld %ld %ld",&t->tr[i][0],&t->tr[i][1],&t->tr[i][2]);
	  t->tr[i][0]--;
          t->tr[i][1]--;
          t->tr[i][2]--;
        }
      for (i = 0; i < t->np; i++)
	fscanf (data,"%f %f",&t->rp[i].x,&t->rp[i].y);
      for (i = 0; i < t->nt; i++)
	fscanf (data,"%d",&t->ngt[i]);
      for (i = 0; i < t->np; i++)
	fscanf (data,"%d",&t->ng[i]);
    }
  else /* gfem format */
    {
      fscanf(data,"%ld %ld",&t->np,&t->nt);
      NEXTLINE (data);

      if (t->rp) {delete [] t->rp;t->rp = NULL;} 
      if (t->tr) {delete [] t->tr;t->tr = NULL;} 
      if (t->ng) {delete [] t->ng;t->ng = NULL;}
      if (t->ngt) {delete [] t->ngt;t->ngt = NULL;}

      t->rp = new rpoint[t->np];
      t->tr = new triangle[t->nt];
      t->ng = new int[t->np];
      t->ngt = new int[t->nt];

      for (i = 0; i < t->np; i++)
	fscanf (data,"%f %f %d",& t->rp[i].x,& t->rp[i].y,&t->ng[i]);
      for (i = 0; i < t->nt; i++)
        {
	  fscanf (data,"%ld %ld %ld %d",& t->tr[i][0],& t->tr[i][1],& t->tr[i][2],&t->ngt[i]);
          t->tr[i][0]--;
          t->tr[i][1]--;
          t->tr[i][2]--;
        }
    }
  fclose (data);
  return 0;
}

int 
savetriangulation (triangulation *t, char *path)
{
  int i;
  FILE* data;
  char *result = NULL;
  int dummy = 0;
  
  if ((data = fopen (path,"w")) == NULL)
    return 1;
  /*
   * strstr is found in string.h
   *  => portability problems
   */
  if ((result = strstr (path,".amdba")) != NULL) /* amdba format */
    {
      fprintf(data,"%ld %ld\n",t->np,t->nt);

      for (i = 0; i < t->np; i++)
        fprintf(data,"%8d %8f %8f %8d\n",i+1, t->rp[i].x,t->rp[i].y,t->ng[i]);
      
      for (i = 0; i < t->nt; i++)
        fprintf (data,"%8d %8ld %8ld %8ld %8d\n",i+1, t->tr[i][0]+1,
                 t->tr[i][1]+1, t->tr[i][2]+1, t->ngt[i]);
    }
  else if ((result = strstr (path,".am_fmt")) != NULL)/* am_fmt format */
    {
      fprintf(data,"%ld %ld\n",t->np,t->nt);

      dummy = 0;
      for (i = 0; i < t->nt; i++)
        {
          fprintf (data,"%8ld %8ld %8ld  ", t->tr[i][0] + 1,t->tr[i][1] + 1 ,t->tr[i][2] + 1 );
          END_OF_LINE(data, dummy, 1);
        }
      if (dummy) fprintf(data,"\n");
      dummy = 0;
      for (i = 0; i < t->np; i++)
        {
          fprintf (data,"%15f %15f   ",t->rp[i].x,t->rp[i].y);
          END_OF_LINE (data, dummy, 1);
        }
      if (dummy) fprintf(data,"\n");
      dummy = 0;
      for (i = 0; i < t->nt; i++)
        {
          fprintf (data,"%8d ",t->ngt[i]);
          END_OF_LINE (data, dummy, 9);
        }
      if (dummy) fprintf(data,"\n");
      dummy = 0;
      for (i = 0; i < t->np; i++)
        {
          fprintf (data,"%8d ",t->ng[i]);
          END_OF_LINE (data, dummy, 9);
        }
      if (dummy) fprintf(data,"\n");
    }
  else
    {
      fprintf(data,"%ld %ld\n",t->np,t->nt);
      
      for (i = 0; i < t->np; i++)
        fprintf(data,"%8f %8f %8d\n",t->rp[i].x,t->rp[i].y,t->ng[i]);
      for (i = 0; i < t->nt; i++)
        fprintf (data,"%8ld %8ld %8ld %8d\n",t->tr[i][0]+1,t->tr[i][1]+1,t->tr[i][2]+1,t->ngt[i]);
    }
  fclose (data);
  return 0;
}
int
savefct (creal * f, int ns, char *path)
{
  FILE* data;
  char *result = NULL;
  int i; 

  if ((data = fopen (path,"w")) == NULL)
    return 1;

  if ((result = strstr (path,".bb")) != NULL)/* bb format */
    {
      fprintf (data,"3 1 %d 2\n",ns);
      for (i = 0;i < ns;i++)
        fprintf (data,"%g\n",realpart(f[i]));
    }
  else /* gfem format */
    {
      fprintf (data,"%d\n",ns);
      for (i = 0;i < ns;i++)
	fprintf (data,"%g\n",realpart(f[i]));
    }
  
  fclose (data);
  return 0;
}

int 
saveparam (fcts * param, triangulation * t, char *path, int N)
{
  int k, ns = t->np;
  ofstream file (path);
  file.precision (8);
  file << ns << "	" << N << endl;
  for (k = 0; k < ns; k++)
    {
      if (N == 1)
	{

	  file << (param)->f1[k] << " ";
	  file << "		";
	  file << (param)->g1[k] << " ";
	  file << "		";
	  file << (param)->p1[k] << " ";
	  file << "		";
	  file << (param)->b1[k] << " ";
	  file << "		";
	  file << (param)->c1[k] << " ";
	  file << "		";
	  file << (param)->a11[k] << " ";
	  file << "		";
	  file << (param)->a21[k] << " ";
	  file << "		";
	  file << (param)->nuxx1[k] << " ";
	  file << "		";
	  file << (param)->nuxy1[k] << " ";
	  file << "		";
	  file << (param)->nuyx1[k] << " ";
	  file << "		";
	  file << (param)->nuyy1[k] << " ";
	  file << "		";
	}
      else if (N == 2)
	{
	  file << (param)->f2[k] << " ";
	  file << "		";
	  file << (param)->g2[k] << " ";
	  file << "		";
	  file << (param)->p2[k] << " ";
	  file << "		";
	  file << (param)->b2[k] << " ";
	  file << "		";
	  file << (param)->c2[k] << " ";
	  file << "		";
	  file << (param)->a12[k] << " ";
	  file << "		";
	  file << (param)->a22[k] << " ";
	  file << "		";
	  file << (param)->nuxx2[k] << " ";
	  file << "		";
	  file << (param)->nuxy2[k] << " ";
	  file << "		";
	  file << (param)->nuyx2[k] << " ";
	  file << "		";
	  file << (param)->nuyy2[k] << " ";
	  file << "		";
	}
      file << endl;
    }
  file.close ();
  return 0;
}


int 
saveconst (creal f, char *path)
{
  ofstream file (path, ios::out | ios::app);
//  file.seekoff(0,ios::end,0);
  file << f << endl;
  file.close ();
  return 0;
}

int 
loadfct (creal * f, int ns, char *path)
{
  FILE* data;
  char *result = NULL;
  int n,i,dummy1,dummy2,dummy3;

  if ((data = fopen (path,"r")) == NULL)
    return 0;

  if ((result = strstr (path,".bb")) != NULL)/* bb format */
    {
      fscanf (data,"%d %d %d %d",&dummy1,&dummy2,&n,&dummy3);
		NEXTLINE(data);
      if (n != ns)
        return 0;
      for (i = 0;i < ns;i++)
        {
          fscanf (data,"%g",&(f[i].real()));
			 NEXTLINE(data);
        }
    }
  else /* gfem format */
    {
      fscanf (data,"%d",&n);
		NEXTLINE(data);
      if (n != ns)
        return 0;
      for (i = 0;i < ns;i++) 
        {
          fscanf (data,"%g",&(f[i].real()));
			 NEXTLINE(data);
        }
    }
  fclose (data);
  return -2;
}

int readpoints(char *path, float* cr, int imax)
{
  int i = 0;
  FILE* data;

  if ((data = fopen (path,"r")) == NULL)
    return 0;
  while ((!feof(data))&&(i<imax))
        {
          fscanf (data,"%8f\t%8f",&(cr[2*i]), &(cr[2*i+1]));
		  NEXTLINE(data); i++;
        }
  fclose (data);
  if(i==imax) return -1;
   else return --i;
}
