/* --------------------------------------------------------------------  */
/*                          CALCULIX                                     */
/*                   - GRAPHICAL INTERFACE -                             */
/*                                                                       */
/*     A 3-dimensional pre- and post-processor for finite elements       */
/*              Copyright (C) 1996 Klaus Wittig                          */
/*                                                                       */
/*     This program is free software; you can redistribute it and/or     */
/*     modify it under the terms of the GNU General Public License as    */
/*     published by the Free Software Foundation; version 2 of           */
/*     the License.                                                      */
/*                                                                       */
/*     This program is distributed in the hope that it will be useful,   */
/*     but WITHOUT ANY WARRANTY; without even the implied warranty of    */ 
/*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      */
/*     GNU General Public License for more details.                      */
/*                                                                       */
/*     You should have received a copy of the GNU General Public License */
/*     along with this program; if not, write to the Free Software       */
/*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
/* --------------------------------------------------------------------  */

#include <extUtil.h>

#define TEST     0

#define INI_FIELD_SIZE 100000



int readfrd( unsigned char *datin, Summen *anz, Nodes **nptr, Elements **eptr, Datasets **lptr )
{
  FILE *handle;
  int i=0, j=0, nodeflag=0, elemflag=0;
  int n;  /* used in format_flag */ 

  int  ncomps, maxcomps=0;
  unsigned char rec_str[MAX_LINE_LENGTH];
  int  node_field_size, elem_field_size;
  int  e_nmax=1, e_nmin=1;
  int  length, flag, format_flag;
  int  ipuf, nodenr=0;

  unsigned char **dat, **compName;
  int           *ictype, *icind1, *icind2, *iexist; 

  int anz_p=-1;
  unsigned char **pheader=NULL;

  Nodes     *node=NULL;
  Elements  *elem=NULL;
  Datasets  *lcase=NULL;


  if ( (lcase = (Datasets *)malloc( 1 * sizeof(Datasets))) == NULL )
    printf("\n\n ERROR: malloc failed\n\n") ;

  node_field_size=INI_FIELD_SIZE;
  do
  {
    if ( (node = (Nodes *)realloc( (Nodes *)node, (node_field_size+1) * sizeof(Nodes))) == NULL )
    {
      printf("WARNING: in readfrd() is INI_FIELD_SIZE:%d to large and is reduced\n", node_field_size );
      node_field_size/=2;
    }
    if(node_field_size<100)
    {
      printf("\n\n ERROR: not enough memory in readfrd()\n\n");
      exit(-1);
    }
    for(i=0; i<node_field_size; i++) node[i].indx=-1;
  }while(!node);

  elem_field_size=INI_FIELD_SIZE;
  do
  {
    if((elem = (Elements *)realloc( (Elements *)elem, (elem_field_size+1) * sizeof(Elements))) == NULL )
  	{
      printf("WARNING: in readfrd() is INI_FIELD_SIZE:%d to large and is reduced\n", elem_field_size );
      elem_field_size/=2;
    }
    if(elem_field_size<100)
    {
      printf("\n\n ERROR: not enough memory in readfrd()\n\n");
      exit(-1);
    }
  }while(!elem);

  anz->u=anz->n=anz->e=anz->l=-1;
  length = 1;
  format_flag=0;

  /* Open the files and check to see that it was opened correctly */
  handle = fopen (datin, "r");
  if ( handle== NULL )  { printf ("ERROR: The input file \"%s\" could not be opened.\n\n", datin); return(-1); }
  else  printf (" file:%s opened\n", datin);


  printf (" reading frd format\n");
  length = frecord( handle, rec_str);
  rec_str[length]=(unsigned char)NULL;
  flag = stoi(rec_str,4,5);
  if (flag == 1 )
  {
    stos(rec_str,7,12,anz->model);
    printf (" MODEL NAME:  %s", anz->model);
  }
  else
  {
    printf ("\n\nFATAL ERROR: no proper file-format found.\n\n");
    return (-1);
  }

  while(length)
  {
    read_again:;
    length = frecord( handle, rec_str);
    if (rec_str[length] == (unsigned char)EOF) break;
    printf ("\nrecord: %s\n", rec_str);

    flag = stoi(rec_str,1,5);
    format_flag = stoi(rec_str,74,75);
    printf ("OPCODE:%d IFORMT:%d\n", flag, format_flag );

    if(flag == 9999) goto read_again;
    if(( (nodeflag==1)&&(flag == 2) ) || ( (elemflag==1)&&(flag == 3) ))
    {
      printf ("found a second mesh. This mesh will be ignored\n");
      flag=-1;
    }
    if(flag == 1)
    {
      /* model name */
      if(rec_str[5]=='C')
        stos( rec_str, 7, 12, anz->model);

      /* User Header used to store general information */
      if(rec_str[5]=='U')
      {
        anz->u++;
        if(!anz->u)
        { if(( anz->uheader=(unsigned char **)malloc( sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n") ; }
        else if(( anz->uheader=(unsigned char **)realloc((unsigned char **)anz->uheader, (anz->u+1)*sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failed\n\n") ;
        if(( anz->uheader[anz->u]=(unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n") ;
        strcpy(anz->uheader[anz->u],rec_str);
      }

      /* Project Header used to store additional Dataset information */
      if(rec_str[5]=='P')
      {
        anz_p++;
        if(!anz_p)
        { if(( pheader=(unsigned char **)malloc( sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n") ; }
        else if(( pheader=(unsigned char **)realloc((unsigned char **)pheader, (anz_p+1)*sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failed\n\n") ;
        if(( pheader[anz_p]=(unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n") ;
        strcpy(pheader[anz_p],rec_str);
      }
    }
    else if(flag == 2)
    {
      /* store the pheaders which are leading this block */
      anz->p=anz_p+1;
      anz->pheader=pheader;
      anz_p=-1;
      pheader=NULL;

      printf ("reading Nodes\n");
      anz->nmax=-MAX_INTEGER;  anz->nmin= MAX_INTEGER; nodeflag=1;
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);
        anz->n++;
        if (flag == -3) break;
        if (!format_flag) node[anz->n].nr = stoi(rec_str,4,8);
        else              node[anz->n].nr = stoi(rec_str,4,13);
        if (node[anz->n].nr>=node_field_size)
	{
          node_field_size=node[anz->n].nr+100;
          if ( (node = (Nodes *)realloc((Nodes *)node, (node_field_size+1) * sizeof(Nodes))) == NULL )
          {
            printf("\n\n ERROR: realloc failed, nodenr:%d\n\n", node[anz->n].nr) ;
            return(-1);
          }
          for(i=node[anz->n].nr; i<node_field_size; i++) node[i].indx=-1;
        }
        /* save only nodes which are not already stored */
        if(node[node[anz->n].nr].indx<0)
        {
          node[node[anz->n].nr].indx=anz->n;
          if (!format_flag)
          {
            node[node[anz->n].nr].nx = stof(&rec_str[8],1,12);
            node[node[anz->n].nr].ny = stof(&rec_str[20],1,12);
            node[node[anz->n].nr].nz = stof(&rec_str[32],1,12);
          }
          else
          {
            node[node[anz->n].nr].nx = stof(&rec_str[13],1,12);
            node[node[anz->n].nr].ny = stof(&rec_str[25],1,12);
            node[node[anz->n].nr].nz = stof(&rec_str[37],1,12);
          }
          if (node[anz->n].nr >  anz->nmax)  anz->nmax=node[anz->n].nr;
          if (node[anz->n].nr <  anz->nmin)  anz->nmin=node[anz->n].nr;
#if TEST
        printf (" n=%d x=%lf y=%lf z=%lf \n",  node[anz->n].nr,
          node[node[anz->n].nr].nx, node[node[anz->n].nr].ny,
          node[node[anz->n].nr].nz); 
#endif
        } 
      } while(flag != -3);
      node_field_size=anz->nmax+1;
      if((node = (Nodes *)realloc( (Nodes *)node, node_field_size * sizeof(Nodes))) == NULL )
        printf("\n\n ERROR: realloc failed\n\n") ;
      else
        printf ("\n %d nodes reallocated \n",anz->nmax);
    }

    else if(flag == 3)
    {
      printf ("reading Elements\n");
      anz->emax=-MAX_INTEGER;  anz->emin=MAX_INTEGER; elemflag=1;
      e_nmax=-MAX_INTEGER;  e_nmin=MAX_INTEGER;
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);
        anz->e++;

        if (flag == -3) break;
        else if ((flag == -1)||(flag == -2))
        {
          if (anz->e>=elem_field_size)
          {
            elem_field_size=anz->e+100;
            if((elem=(Elements *)realloc((Elements *)elem,(elem_field_size+1)*sizeof(Elements)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed, elem-index:%d\n\n", anz->e);
              return(-1);
            }
          }
          if (!format_flag)
          {
	    elem[anz->e].nr = stoi(&rec_str[3], 1, 5);
	    elem[anz->e].type = stoi(&rec_str[8], 1, 5);
	    elem[anz->e].group = stoi(&rec_str[13], 1, 5);
	    elem[anz->e].mat = stoi(&rec_str[18], 1, 5);
          }
          else
          {
	    elem[anz->e].nr = stoi(&rec_str[3], 1, 10);
	    elem[anz->e].type = stoi(&rec_str[13], 1, 5);
	    elem[anz->e].group = stoi(&rec_str[18], 1, 5);
	    elem[anz->e].mat = stoi(&rec_str[23], 1, 5);
          }
          ipuf=0;
          if (elem[anz->e].nr >  anz->emax)  anz->emax=elem[anz->e].nr;
          if (elem[anz->e].nr <  anz->emin)  anz->emin=elem[anz->e].nr;
          if (elem[anz->e].type == 1)      ipuf = 8;   /* HEXA8  */
          else if (elem[anz->e].type == 2) ipuf = 6;   /* PE6   */
          else if (elem[anz->e].type == 3) ipuf = 4;   /* TET4   */
          else if (elem[anz->e].type == 4) ipuf = 20;  /* HEXA20 */
          else if (elem[anz->e].type == 5) ipuf = 15;  /* PE15  */
          else if (elem[anz->e].type == 6) ipuf = 10;  /* TET10  */
          else if (elem[anz->e].type == 7) ipuf = 3;   /* TRI3   */
          else if (elem[anz->e].type == 8) ipuf = 6;   /* TRI6   */
          else if (elem[anz->e].type == 9) ipuf = 4;   /* QUAD4  */
          else if (elem[anz->e].type == 10) ipuf = 8; /* QUAD8  */
          else if (elem[anz->e].type == 11) ipuf = 2;  /* BEAM2   */
          else if (elem[anz->e].type == 12) ipuf = 3;  /* BEAM3   */
#if TEST
          printf ("\n%i e=%d typ=%d mat=%d \n", flag, elem[anz->e].nr,
                    elem[anz->e].type, elem[anz->e].group, elem[anz->e].mat );
#endif
          length = frecord( handle, rec_str );
          if (ipuf==0)
          {
            printf (" element:%d is from unknown type:%d\n", elem[anz->e].nr, elem[anz->e].type);
          }
          else
          {
            anz->etype[elem[anz->e].type]++;
            /* read the node-lines */
            if (!format_flag)
            {
              j=0;
              for (i=0; i<ipuf; i++)
              {
		elem[anz->e].nod[i] = stoi(&rec_str[3+j*5], 1, 5);
                if (j<14) j++;
                else
                {
                  if (i<ipuf-1) length = frecord( handle, rec_str ); j=0;
                }
              }
            }
            else
            {
              j=0;
              for (i=0; i<ipuf; i++)
              {
                elem[anz->e].nod[i] = stoi(&rec_str[3+j*10], 1, 10);
                if (j<9) j++;
                else
                {
                  if (i<ipuf-1) length = frecord( handle, rec_str ); j=0;
                }
              }
            }
          }
        }
        else
        {
          printf ("ERROR: flag:%d is not expected, must be -1 or -2!\n%s", flag, rec_str );
          exit(-1);
        }
      } while(flag != -3);
      elem_field_size=anz->e+1;
      if ( (elem = (Elements *)realloc((Elements *)elem, elem_field_size * sizeof(Elements))) == NULL )
        printf("\n\n ERROR: in readfrd realloc failed\n\n") ;
      else
        printf ("\n %d elements reallocated \n", anz->e);
    }

    else if(flag == 100)
    {
      anz->l++;

      /* store the pheaders which are leading this block */
      lcase[anz->l].npheader=anz_p+1;
      lcase[anz->l].pheader=pheader;
      anz_p=-1;
      pheader=NULL;

      printf ("\nreading Dataset No:%d\n",anz->l+1);
      if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (anz->l+2) * sizeof(Datasets))) == NULL )
      { printf("\n\n ERROR: malloc failure\n\n" ); exit(1); }

      stos( rec_str, 7, 12, lcase[anz->l].dataset_name);
      lcase[anz->l].value=stof( rec_str, 13, 24 );
      stos( rec_str, 37, 56, lcase[anz->l].dataset_text);
      lcase[anz->l].analysis_type=stoi( rec_str, 57, 58 );
      lcase[anz->l].step_number=stoi( rec_str, 59, 63 );
      if(strlen(rec_str)>72 )
      {
        stos(rec_str,64,73,lcase[anz->l].analysis_name);
      }
      else
      {
        strcpy(lcase[anz->l].analysis_name,"");
      }
      ncomps=0;
      if (!format_flag) n=8;
      else n=13;
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);

        if(flag == -1)
        {
          if (format_flag) nodenr = stoi(rec_str,4,13); else nodenr = stoi(rec_str,4,8); 
          if (nodenr>anz->nmax)
          {
            printf("WARNING: found node:%d in Dataset higher than in geometry allocated:%d\n", nodenr, anz->nmax);
          }
          else if ( lcase[anz->l].irtype == 1 )
	  {
            if(maxcomps==6)
            {
              i=6;
              if ( format_flag)
              {
                lcase[anz->l].dat[0][nodenr]= stof(&rec_str[  13  ], 1, 12);
                lcase[anz->l].dat[1][nodenr]= stof(&rec_str[  25  ], 1, 12);
                lcase[anz->l].dat[2][nodenr]= stof(&rec_str[  37  ], 1, 12);
                lcase[anz->l].dat[3][nodenr]= stof(&rec_str[  49  ], 1, 12);
                lcase[anz->l].dat[4][nodenr]= stof(&rec_str[  61  ], 1, 12);
                lcase[anz->l].dat[5][nodenr]= stof(&rec_str[  73  ], 1, 12);
              }
              else
              {
                lcase[anz->l].dat[0][nodenr]= stof(&rec_str[  8   ], 1, 12);
                lcase[anz->l].dat[1][nodenr]= stof(&rec_str[  20  ], 1, 12);
                lcase[anz->l].dat[2][nodenr]= stof(&rec_str[  32  ], 1, 12);
                lcase[anz->l].dat[3][nodenr]= stof(&rec_str[  44  ], 1, 12);
                lcase[anz->l].dat[4][nodenr]= stof(&rec_str[  56  ], 1, 12);
                lcase[anz->l].dat[5][nodenr]= stof(&rec_str[  68  ], 1, 12);
              }
            }
            else for(i=0; i<maxcomps; i++) lcase[anz->l].dat[i][nodenr]= stof(&rec_str[n+i*12], 1, 12);
	    /* printf("%d", nodenr); for (i=0; i<maxcomps; i++) printf(" %f",lcase[anz->l].dat[i][nodenr] ); printf("\n"); */
	  }
          else i=0;
	}
        else if(flag == -2)
	{
          if (!format_flag) n=8;
          else n=13;
          j=0;
          do
          {
            lcase[anz->l].dat[i][nodenr]= stof(&rec_str[n+j*12], 1, 12);
            i++;j++;
          }while((j<6)&&(i<lcase[anz->l].ncomps));
        }
        else if (flag == -4)
        {
          stos( rec_str, 6, 13, lcase[anz->l].name);
          lcase[anz->l].ncomps = stoi(rec_str,14,18);
          lcase[anz->l].irtype = stoi(rec_str,19,23);

          if(lcase[anz->l].ncomps<6) maxcomps=lcase[anz->l].ncomps;
          else maxcomps=6;

          if( lcase[anz->l].irtype > 2 )
          {
            printf(" Found ELEMENT DATA, this is not suported!\n");
            anz->l--;
            goto next;
          }

          if ( (lcase[anz->l].nmax = (int *)malloc( (lcase[anz->l].ncomps) * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].nmin = (int *)malloc( (lcase[anz->l].ncomps) * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].max = (float *)malloc( (lcase[anz->l].ncomps) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].min = (float *)malloc( (lcase[anz->l].ncomps) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].dat = (float **)malloc( (lcase[anz->l].ncomps) * sizeof(float *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].compName = (unsigned char **)malloc( (lcase[anz->l].ncomps) * sizeof(unsigned char *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].icname = (unsigned char **)malloc( (lcase[anz->l].ncomps) * sizeof(unsigned char *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          for(i=0; i<(lcase[anz->l].ncomps); i++)
	  {
            if ( (lcase[anz->l].dat[i] = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
              printf("\n\n ERROR: malloc failure\n\n" );	               
            if ( (lcase[anz->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
               printf("\n\n ERROR: malloc failed\n\n" );
            if ( (lcase[anz->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
               printf("\n\n ERROR: malloc failed\n\n" );
            lcase[anz->l].max[i]=-MAX_FLOAT;
            lcase[anz->l].min[i]=MAX_FLOAT;
            for(j=0; j<=anz->nmax; j++) lcase[anz->l].dat[i][j]=0.;
	  }
          if ( (lcase[anz->l].ictype = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].icind1 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].icind2 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[anz->l].iexist = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
        }
        else if(flag == -5)
        {
          if(ncomps<lcase[anz->l].ncomps)
	  {
            stos(rec_str, 6, 13, lcase[anz->l].compName[ncomps]);
            lcase[anz->l].ictype[ncomps] = stoi(rec_str,19,23);
            lcase[anz->l].icind1[ncomps] = stoi(rec_str,24,28);
            lcase[anz->l].icind2[ncomps] = stoi(rec_str,29,33);
            lcase[anz->l].iexist[ncomps] = stoi(rec_str,34,38);

            /* requests for additional components are not supported so far */
            lcase[anz->l].icname[ncomps]=NULL;
            if(lcase[anz->l].iexist[ncomps]==1) { lcase[anz->l].ncomps--; ncomps--; }
	  }
          else
	  {
	    rec_str[14]=(char)NULL;
	    printf(" WARNING: unallocated component:%d \"%s\"\n", ncomps, &rec_str[5]);
	  }
          ncomps++;
        }
        else if(flag == -6)
        {
          length= strsplt( rec_str, ' ', &dat);
          ipuf=atoi(dat[2]);
          if ( (compName = (unsigned char **)malloc( ipuf * sizeof(unsigned char *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          for(i=0; i<ipuf; i++)
	  {
            if ( (compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
               printf("\n\n ERROR: malloc failed\n\n" );
	  }
          for (i=0; i<ipuf; i++) strcpy(compName[i], lcase[anz->l].compName[ atoi(dat[i+3])-1 ]);
          for (i=0; i<ipuf; i++) strcpy(lcase[anz->l].compName[i],compName[i]);
          if ( (ictype = (int *)malloc( ipuf * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (icind1 = (int *)malloc( ipuf * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (icind2 = (int *)malloc( ipuf * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (iexist = (int *)malloc( ipuf * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          for (i=0; i<ipuf; i++) ictype[i] = lcase[anz->l].ictype[atoi(dat[i+3])-1];
          for (i=0; i<ipuf; i++) lcase[anz->l].ictype[i] =ictype[i];
          for (i=0; i<ipuf; i++) icind1[i] = lcase[anz->l].icind1[atoi(dat[i+3])-1];
          for (i=0; i<ipuf; i++) lcase[anz->l].icind1[i] =icind1[i];
          for (i=0; i<ipuf; i++) icind2[i] = lcase[anz->l].icind2[atoi(dat[i+3])-1];
          for (i=0; i<ipuf; i++) lcase[anz->l].icind2[i] =icind2[i];
          for (i=0; i<ipuf; i++) iexist[i] = lcase[anz->l].iexist[atoi(dat[i+3])-1];
          for (i=0; i<ipuf; i++) lcase[anz->l].iexist[i] =iexist[i];
	  
          for(i=0; i<length; i++) free(dat[i]);
          free(dat); 
	  
          for(i=0; i<ipuf; i++) free(compName[i]);
          free(compName); 
          free(ictype); 
          free(icind1); 
          free(icind2); 
          free(iexist); 
	}

      }while(flag!=-3);
      for(j=0; j<anz->n; j++)
      {
        for(i=0; i<lcase[anz->l].ncomps; i++)
        {
          if(lcase[anz->l].dat[i][node[j].nr] > lcase[anz->l].max[i])
          {
            lcase[anz->l].max[i]=lcase[anz->l].dat[i][node[j].nr];
            lcase[anz->l].nmax[i]=node[j].nr;
          }
          if(lcase[anz->l].dat[i][node[j].nr] < lcase[anz->l].min[i])
          {
            lcase[anz->l].min[i]=lcase[anz->l].dat[i][node[j].nr];
            lcase[anz->l].nmin[i]=node[j].nr;
          }
        }
      }
    }

    else if(flag == 4)
    {
      anz->l++;
      printf ("\nreading Dataset No:%d\n",anz->l+1);
      if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (anz->l+2) * sizeof(Datasets))) == NULL )
      { printf("\n\n ERROR: malloc failure\n\n" ); exit(1); }

      lcase[anz->l].value=stof( rec_str, 13, 25 );
      strcpy(lcase[anz->l].name,"DISP    ");
      lcase[anz->l].ncomps = 3;
      lcase[anz->l].irtype = 1;

      if ( (lcase[anz->l].nmax = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].nmin = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].max = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].min = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].dat = (float **)malloc( lcase[anz->l].ncomps * sizeof(float *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].compName = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icname = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        if ( (lcase[anz->l].dat[i] = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );	               
        if ( (lcase[anz->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        if ( (lcase[anz->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        lcase[anz->l].max[i]=-MAX_FLOAT;
        lcase[anz->l].min[i]=MAX_FLOAT;
        for(j=0; j<=anz->nmax; j++) lcase[anz->l].dat[i][j]=0.;
      }
      if ( (lcase[anz->l].ictype = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind1 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind2 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].iexist = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );

      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        lcase[anz->l].ictype[i] = 2;
        lcase[anz->l].icind1[i] = i+1;
        lcase[anz->l].icind2[i] = 0;
        lcase[anz->l].iexist[i] = 0;
      }

      strcpy(lcase[anz->l].compName[0], "x       ");
      strcpy(lcase[anz->l].compName[1], "y       ");
      strcpy(lcase[anz->l].compName[2], "z       ");
       
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);
        if(flag == -1)
        {
          if (!format_flag) nodenr = stoi(rec_str,4,8);
          else              nodenr = stoi(rec_str,4,13);
          if (nodenr>anz->nmax)
          {
            printf("WARNING: found node:%d in Dataset higher than in geometry allocated:%d\n", nodenr, anz->nmax);
          }
          else if (!format_flag) 
          {
            for(i=0; i<lcase[anz->l].ncomps; i++)
              lcase[anz->l].dat[i][nodenr]= stof(&rec_str[8+i*12], 1, 12);
          }
          else  
          {
            for(i=0; i<lcase[anz->l].ncomps; i++)
              lcase[anz->l].dat[i][nodenr]= stof(&rec_str[13+i*12], 1, 12);
          }
        }
      }while(flag!=-3);
      for(n=0; n<anz->n; n++)
      {
        nodenr=node[n].nr;
        for(i=0; i<lcase[anz->l].ncomps; i++)
        {
          if(lcase[anz->l].dat[i][nodenr] > lcase[anz->l].max[i])
          {
            lcase[anz->l].max[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmax[i]=nodenr;
          }
          if(lcase[anz->l].dat[i][nodenr] < lcase[anz->l].min[i])
          {
            lcase[anz->l].min[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmin[i]=nodenr;
          }
        }
      }
    }

    else if(flag == 5)
    {
      anz->l++;
      printf ("\nreading Dataset No:%d\n",anz->l+1);
      if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (anz->l+2) * sizeof(Datasets))) == NULL )
      { printf("\n\n ERROR: malloc failure\n\n" ); exit(1); }

      lcase[anz->l].value=stof( rec_str, 13, 25 );
      strcpy(lcase[anz->l].name,"STRESS  ");
      lcase[anz->l].ncomps = 6;
      lcase[anz->l].irtype = 1;

      if ( (lcase[anz->l].nmax = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].nmin = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].max = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].min = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].dat = (float **)malloc( lcase[anz->l].ncomps * sizeof(float *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].compName = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icname = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        if ( (lcase[anz->l].dat[i] = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );	               
        if ( (lcase[anz->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        if ( (lcase[anz->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        lcase[anz->l].max[i]=-MAX_FLOAT;
        lcase[anz->l].min[i]=MAX_FLOAT;
        for(j=0; j<=anz->nmax; j++) lcase[anz->l].dat[i][j]=0.;
      }
      if ( (lcase[anz->l].ictype = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind1 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind2 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].iexist = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );

      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        lcase[anz->l].ictype[i] = 4;
        lcase[anz->l].iexist[i] = 0;
      }
      lcase[anz->l].icind1[0] = 1;
      lcase[anz->l].icind2[0] = 1;
      lcase[anz->l].icind1[1] = 2;
      lcase[anz->l].icind2[1] = 2;
      lcase[anz->l].icind1[2] = 3;
      lcase[anz->l].icind2[2] = 3;
      lcase[anz->l].icind1[3] = 1;
      lcase[anz->l].icind2[3] = 2;
      lcase[anz->l].icind1[4] = 2;
      lcase[anz->l].icind2[4] = 3;
      lcase[anz->l].icind1[5] = 3;
      lcase[anz->l].icind2[5] = 1;

      strcpy(lcase[anz->l].compName[0], "xx      ");
      strcpy(lcase[anz->l].compName[1], "yy      ");
      strcpy(lcase[anz->l].compName[2], "zz      ");
      strcpy(lcase[anz->l].compName[3], "xy      ");
      strcpy(lcase[anz->l].compName[4], "yz      ");
      strcpy(lcase[anz->l].compName[5], "zx      ");
       
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);
        if(flag == -1)
        {
          if (!format_flag) nodenr = stoi(rec_str,4,8);
          else              nodenr = stoi(rec_str,4,13);
          if (nodenr>anz->nmax)
          {
            printf("WARNING: found node:%d in Dataset higher than in geometry allocated:%d\n", nodenr, anz->nmax);
          }
          else
          {
            /* new line */
            length = frecord( handle, rec_str);
            if (rec_str[length] == (unsigned char)EOF) break;
            if (!format_flag) 
            {
              for(i=0; i<lcase[anz->l].ncomps; i++)
                lcase[anz->l].dat[i][nodenr]= stof(&rec_str[8+i*12], 1, 12);
            }
            else  
            {
              for(i=0; i<lcase[anz->l].ncomps; i++)
                lcase[anz->l].dat[i][nodenr]= stof(&rec_str[13+i*12], 1, 12);
            }
          }
        }
      }while(flag!=-3);
      for(n=0; n<anz->n; n++)
      {
        nodenr=node[n].nr;
        for(i=0; i<lcase[anz->l].ncomps; i++)
        {
          if(lcase[anz->l].dat[i][nodenr] > lcase[anz->l].max[i])
          {
            lcase[anz->l].max[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmax[i]=nodenr;
          }
          if(lcase[anz->l].dat[i][nodenr] < lcase[anz->l].min[i])
          {
            lcase[anz->l].min[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmin[i]=nodenr;
          }
        }
      }
    }

    else if((flag == 7)||(flag == 9))
    {
      anz->l++;
      printf ("\nreading Dataset No:%d\n",anz->l+1);
      if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (anz->l+2) * sizeof(Datasets))) == NULL )
      { printf("\n\n ERROR: malloc failure\n\n" ); exit(1); }

      lcase[anz->l].value=stof( rec_str, 13, 25 );
      strcpy(lcase[anz->l].name,"TEMP    ");
      lcase[anz->l].ncomps = 1;
      lcase[anz->l].irtype = 1;

      if ( (lcase[anz->l].nmax = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].nmin = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].max = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].min = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].dat = (float **)malloc( lcase[anz->l].ncomps * sizeof(float *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].compName = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icname = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        if ( (lcase[anz->l].dat[i] = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );	               
        if ( (lcase[anz->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        if ( (lcase[anz->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
           printf("\n\n ERROR: malloc failed\n\n" );
        lcase[anz->l].max[i]=-MAX_FLOAT;
        lcase[anz->l].min[i]=MAX_FLOAT;
        for(j=0; j<=anz->nmax; j++) lcase[anz->l].dat[i][j]=0.;
      }
      if ( (lcase[anz->l].ictype = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind1 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].icind2 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );
      if ( (lcase[anz->l].iexist = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
        printf("\n\n ERROR: malloc failure\n\n" );

      for(i=0; i<lcase[anz->l].ncomps; i++)
      {
        lcase[anz->l].ictype[i] = 1;
        lcase[anz->l].icind1[i] = i+1;
        lcase[anz->l].icind2[i] = 0;
        lcase[anz->l].iexist[i] = 0;
      }

      strcpy(lcase[anz->l].compName[0], "Value   ");

      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        flag = stoi(rec_str,1,3);
        if(flag == -1)
        {
          if (!format_flag) nodenr = stoi(rec_str,4,8);
          else              nodenr = stoi(rec_str,4,13);
          if (nodenr>anz->nmax)
          {
            printf("WARNING: found node:%d in Dataset higher than in geometry allocated:%d\n", nodenr, anz->nmax);
          }
          else if (!format_flag) 
          {
            for(i=0; i<lcase[anz->l].ncomps; i++)
              lcase[anz->l].dat[i][nodenr]= stof(&rec_str[8+i*12], 1, 12);
          }
          else  
          {
            for(i=0; i<lcase[anz->l].ncomps; i++)
              lcase[anz->l].dat[i][nodenr]= stof(&rec_str[13+i*12], 1, 12);
          }
        }
      }while(flag!=-3);
      for(n=0; n<anz->n; n++)
      {
        nodenr=node[n].nr;
        for(i=0; i<lcase[anz->l].ncomps; i++)
        {
          if(lcase[anz->l].dat[i][nodenr] > lcase[anz->l].max[i])
          {
            lcase[anz->l].max[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmax[i]=nodenr;
          }
          if(lcase[anz->l].dat[i][nodenr] < lcase[anz->l].min[i])
          {
            lcase[anz->l].min[i]=lcase[anz->l].dat[i][nodenr];
            lcase[anz->l].nmin[i]=nodenr;
          }
        }
      }
    }

    else
    {
  next:;
      printf (" overread Block: %s\n", rec_str);
      do
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        /* printf ("\n record:%d %s\n", length, rec_str);   */
        if (length != 0)
        {
          flag = stoi(rec_str,1,5);
        }
      } while(flag != -3);
    }
  }

  for(i=0; i<anz_p; i++) free(pheader[i]); free(pheader);

  anz->u++;
  anz->l++;
  fclose(handle);

  if ( e_nmax > (anz->nmax) )
  {
    printf ("\nWARNING: element requestes a nodename higher than allocated\n\n");
    printf (" e_nmax=%d e_nmin=%d\n", e_nmax, e_nmin );
  }
  if ( e_nmin < 1 )
  {
    printf ("\nWARNING: element requestes a nodename lower than allocated\n\n");
    printf (" e_nmax=%d e_nmin=%d\n", e_nmax, e_nmin );
  }
  elemChecker( anz, node, elem);

  *nptr = node; *eptr = elem; *lptr = lcase;
  return(1);
}

