/***********************************************************************
* 
*               *****   ***    ***
*                  *   *   *  *   *
*                 *     ***    ***
*                *     *   *  *   *
*               *****   ***    ***
*
* A FREE Finite Elements Analysis Program in ANSI C for the UNIX OS.
*
* Composed and edited and copyright by 
* Professor Dr.-Ing. Frank Rieg, University of Bayreuth, Germany
*
* eMail: 
* frank.rieg@uni-bayreuth.de
* dr.frank.rieg@t-online.de
* 
* V10.0  December 12, 2001
*
* Z88 should compile and run under any UNIX OS and Motif 2.0.
*
* 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; either version 2, or (at your option)
* any later version.
*
* 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; see the file COPYING.  If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/ 
/***********************************************************************
* z88fx.c : von DXF nach Z88
* 11.9.2002 Rieg
***********************************************************************/

/***********************************************************************
* Fuer UNIX
***********************************************************************/
#ifdef FR_UNIX
#include <z88x.h>
#include <stdio.h>      /* fopen, fprintf, fclose */
#include <string.h>     /* strstr */
#endif

/***********************************************************************
* Fuer Windows95
***********************************************************************/
#ifdef FR_WIN95
#include <z88x.h>
#include <stdio.h>      /* fopen, fprintf, fclose */
#include <string.h>     /* strstr */
#endif

/***********************************************************************
*  Functions
***********************************************************************/
int wrim88x(FR_INT4,int);
int wlog88x(FR_INT4,int);
int ale88x(int);
void sub88x(FR_INT4);
int koi88x(FR_INT4);
int wria88x(void);

/***********************************************************************
* hier beginnt Function z88fx
***********************************************************************/
int z88fx(void)
{
extern FILE *fdxf,*fwlo;

extern FR_DOUBLEAY x;
extern FR_DOUBLEAY y;
extern FR_DOUBLEAY z;
extern FR_DOUBLEAY emod;
extern FR_DOUBLEAY rnue;
extern FR_DOUBLEAY qpara;
extern FR_DOUBLEAY riyy;
extern FR_DOUBLEAY eyy;
extern FR_DOUBLEAY rizz;
extern FR_DOUBLEAY ezz;
extern FR_DOUBLEAY rit;
extern FR_DOUBLEAY wt;
extern FR_DOUBLEAY wert;

extern FR_INT4AY koi;
extern FR_INT4AY koffs;
extern FR_INT4AY ifrei;
extern FR_INT4AY ityp;
extern FR_INT4AY itypfe;
extern FR_INT4AY ivon;
extern FR_INT4AY ibis;
extern FR_INT4AY intord;
extern FR_INT4AY jel;
extern FR_INT4AY iel;
extern FR_INT4AY kel;
extern FR_INT4AY nkn;
extern FR_INT4AY ifg;
extern FR_INT4AY irflag;

extern FR_CHARAY cjmode;
extern FR_CHARAY cimode;
extern FR_CHARAY ckmode;

extern FR_INT4 MAXNFG,MAXK,MAXE,MAXKOI,MAXNEG;
extern FR_INT4 ndim,nkp,ne,nfg,neg,kflag,ibflag,ipflag,niflag;
extern FR_INT4 nrb,nint,ksflag,isflag;
extern FR_INT4 ianz,ifrej;
extern FR_INT4 ICFLAG;

extern char cxx[];

char cline[256],ctext[256],cfese[10];

FR_DOUBLE xp,yp,zp;

FR_INT4 i,j,k,kofold,idummy,jdummy,IKFLAG,ip_entities,ip_z88net;

int iret;

/***********************************************************************
* start function
***********************************************************************/
wrim88x(0,TX_Z88FX);
wlog88x(0,LOG_Z88FX);

j= 0;
k= 0;
idummy= 0;
jdummy= 0;

xp= 0.;
yp= 0.;
zp= 0.;

kofold= 0; /* nur wg. compiler warnings */

/***********************************************************************
* file fdxf = Z88X.DXF oeffnen
***********************************************************************/
wlog88x(0,LOG_FX);
wrim88x(0,TX_FX);
fdxf= fopen(cxx,"r");
if(fdxf == NULL)
  {
  wlog88x(0,LOG_NOX);
  fclose(fwlo);
  return(AL_NOX);
  }
rewind(fdxf);

wlog88x(0,LOG_REAIX);
wrim88x(0,TX_REAIX);

/***********************************************************************
* Z88I1.TXT bzw. Z888NI.TXT ausfiltern
***********************************************************************/
/*---------------------------------------------------------------------*
* 1. Zeile Z88I1.TXT oder Z88NI.TXT ausfiltern
*---------------------------------------------------------------------*/
if(ICFLAG == 4 || ICFLAG == 5)
  {
  wlog88x(0,LOG_DEC1ZI1);
  wrim88x(0,TX_DEC1ZI1);
  }

if(ICFLAG == 6)
  {
  wlog88x(0,LOG_DEC1ZNI);
  wrim88x(0,TX_DEC1ZNI);
  }

IKFLAG= 0;

/*=====================================================================*
* DXF- Version feststellen
*=====================================================================*/
do
  {
  fgets(cline,256,fdxf);
  if((strstr(cline,"AC10")) != NULL) break;      /* AC10xx gefunden */
  }
while ((strstr(cline,"EOF"))== NULL);

if(strstr(cline,"AC1009")) fprintf(fwlo,"\nAC1009");
if(strstr(cline,"AC1012")) fprintf(fwlo,"\nAC1012");
if(strstr(cline,"AC1014")) fprintf(fwlo,"\nAC1014");
if(strstr(cline,"AC1015")) fprintf(fwlo,"\nAC1015");


rewind(fdxf);

/*=====================================================================*
* Aufsetzpunkt ENTITIES finden
*=====================================================================*/
ip_entities= 0;

do
  {  
  fgets(cline,256,fdxf);
  ip_entities++;
  }
while ((strstr(cline,"ENTITIES"))== NULL);

fprintf(fwlo,"\nip_entities=%ld",ip_entities);
fflush(fwlo);

/*=====================================================================*
* Z88I1.TXT oder Z88NI.TXT ?
*=====================================================================*/
do
  {
  fgets(cline,256,fdxf);

  if((strstr(cline,"Z88I1.TXT")) != NULL)
    {
    sscanf(cline,"%s %ld %ld %ld %ld %ld %ld %ld %ld",
    ctext,&ndim,&nkp,&ne,&nfg,&neg,&kflag,&ibflag,&ipflag);
    fprintf(fwlo,"\nZ88I1.TXT  %ld %ld %ld %ld %ld %ld %ld %ld",
    ndim,nkp,ne,nfg,neg,kflag,ibflag,ipflag);
    fflush(fwlo);
    IKFLAG= 1;
    goto L100;
    }
  
  if((strstr(cline,"Z88NI.TXT")) != NULL)
    {
    sscanf(cline,"%s %ld %ld %ld %ld %ld %ld %ld %ld %ld",
    ctext,&ndim,&nkp,&ne,&nfg,&neg,&kflag,&ibflag,&ipflag,&niflag);
    fprintf(fwlo,"\nZ88NI.TXT %ld %ld %ld %ld %ld %ld %ld %ld %ld",
    ndim,nkp,ne,nfg,neg,kflag,ibflag,ipflag,niflag);
    fflush(fwlo);
    IKFLAG= 2;
    goto L100;
    }
  }
while ((strstr(cline,"EOF"))== NULL);

L100:;

if((ICFLAG== 4 || ICFLAG== 5) && IKFLAG != 1)
  {
  wlog88x(0,LOG_WROIXI1);
  return(AL_WROIXI1);
  }

if(ICFLAG== 6 && IKFLAG != 2)
  {
  wlog88x(0,LOG_WROIXNI);
  return(AL_WROIXNI);
  }

/*======================================================================
* Testen, ob innerhalb der zulaessigen Grenzen
*=====================================================================*/
if(!(ndim == 2 || ndim == 3))
  {
  wlog88x(ndim,LOG_WRONGDIM);
  fclose(fwlo);
  return(AL_WRONDIM);
  }

if(nkp > MAXK)
  {
  wlog88x(MAXK,LOG_EXMAXK);
  fclose(fwlo);
  return(AL_EXMAXK);
  }

if(ne > MAXE)
  {
  wlog88x(MAXE,LOG_EXMAXE);
  fclose(fwlo);
  return(AL_EXMAXE);
  }

if((ne*20) > MAXKOI)
  {
  wlog88x(MAXKOI,LOG_EXMAXKOI);
  fclose(fwlo);
  return(AL_EXKOI);
  }

if(nfg > MAXNFG)
  {
  wlog88x(MAXNFG,LOG_EXMAXNFG);
  fclose(fwlo);
  return(AL_EXMAXNFG);
  }

if(neg > MAXNEG)
  {
  wlog88x(MAXNEG,LOG_EXMAXNEG);
  fclose(fwlo);
  return(AL_EXMAXNEG);
  }

if(!(kflag == 0 || kflag == 1))
  {
  wlog88x(kflag,LOG_WROKFLAG);
  fclose(fwlo);
  return(AL_WROKFLAG);
  }

if(!(ibflag == 0 || ibflag == 1))
  {
  wlog88x(kflag,LOG_WROIBFLAG);
  fclose(fwlo);
  return(AL_WROIBFLAG);
  }

if(!(ipflag == 0 || ipflag == 1 || ipflag == 2))
  {
  wlog88x(kflag,LOG_WROIPFLAG);
  fclose(fwlo);
  return(AL_WROIPFLAG);
  }

if(ibflag != 0 && ipflag != 0)
  {
  wlog88x(kflag,LOG_NOBEAMPLA);
  fclose(fwlo);
  return(AL_NOBEAMPLA);
  }

rewind(fdxf);

/*---------------------------------------------------------------------*
* Knoten ausfiltern
*---------------------------------------------------------------------*/
wlog88x(0,LOG_DECKNO);
wrim88x(0,TX_DECKNO);

j= 0;                                            /* Anzahl Knoten */

for(i= 1; i <= ip_entities; i++)                 /* Aufsetzpunkt ENTITIES */
  fgets(cline,256,fdxf);

do
  {
  fgets(cline,256,fdxf);

  if((strstr(cline,"Z88KNR")) != NULL)
    {
    do
      fgets(cline,256,fdxf);
    while ((strstr(cline," 10"))== NULL);        /* Aufsetzpunkt "10" */
    
    fgets(cline,256,fdxf);                       /* x lesen */
    sscanf(cline,"%lg",&xp);
    
    fgets(cline,256,fdxf);                       /* "20" leerlesen */
    fgets(cline,256,fdxf);                       /* y lesen */
    sscanf(cline,"%lg",&yp);
    
    fgets(cline,256,fdxf);                       /* "30" leerlesen */
    fgets(cline,256,fdxf);                       /* z lesen */
    sscanf(cline,"%lg",&zp);

    do
      {
      fgets(cline,256,fdxf);
      if((strstr(cline,"EOF")) != NULL) return(AL_NOPOINTS);
      }
    while ((strstr(cline,"P "))== NULL);         /* Aufsetzpunkt "P " */

    sscanf(cline,"%s %ld",ctext,&k);             /* k lesen */

    x[k]= xp;                                    /* umspeichern */
    y[k]= yp;
    z[k]= zp;

    j++;                                         /* Knoten hochzaehlen */
    } 
  }
while ((strstr(cline,"EOF"))== NULL);

/*=====================================================================
* gefundene Knoten in Z88X.LOG zur Kontrolle schreiben
*====================================================================*/
for(i=1; i<= j;i++)
  {
  fprintf(fwlo,"\n#%ld X=%lg Y=%lg Z=%lg",i,x[i],y[i],z[i]);
  fflush(fwlo);
  }

/*=====================================================================
* Kontrolle und Ausschrieb, Rewind
*====================================================================*/
if(j != nkp)                                     /* falsche Anzahl Knoten */
  {
  wlog88x(0,LOG_WROIXKNO);
  return(AL_WROIXKNO);
  }

wrim88x(j,TX_FOUKNO);
wlog88x(j,LOG_FOUKNO);

rewind(fdxf);

/*---------------------------------------------------------------------*
* Elemente ausfiltern
*---------------------------------------------------------------------*/
wlog88x(0,LOG_DECELE);
wrim88x(0,TX_DECELE);

IKFLAG= 0;

if(ICFLAG== 6)
  strcpy(cfese,"SE ");
else
  strcpy(cfese,"FE ");

for(i= 1; i <= ip_entities; i++)                 /* Aufsetzpunkt ENTITIES */
  fgets(cline,256,fdxf);

do
  {
  fgets(cline,256,fdxf);
  if((strstr(cline,cfese)) != NULL)
    {
    sscanf(cline,"%s %ld",ctext,&k);
    sscanf(cline,"%s %ld %ld",ctext,&idummy,&ityp[k]);
    if(ICFLAG != 6)
      {
      fprintf(fwlo,"\n#%ld FE=%ld",k,ityp[k]);
      fflush(fwlo);
      }

    if(ICFLAG == 6)
      {
      if(ityp[k] == 1 || ityp[k] == 10)
        {
        sscanf(cline,"%s %ld %ld %ld %ld %c %ld %c %ld %c",
        ctext,&idummy,&jdummy,&itypfe[k],
        &jel[k],&cjmode[k],&iel[k],&cimode[k],&kel[k],&ckmode[k]);
        fprintf(fwlo,"\n#%ld SE=%ld FE=%ld %ld %c %ld %c %ld %c",k,ityp[k],
        itypfe[k],jel[k],cjmode[k],iel[k],cimode[k],kel[k],ckmode[k]);
        fflush(fwlo);
        }
      else
        {
        sscanf(cline,"%s %ld %ld %ld %ld %c %ld %c",
        ctext,&idummy,&jdummy,&itypfe[k],
        &jel[k],&cjmode[k],&iel[k],&cimode[k]);
        fprintf(fwlo,"\n#%ld SE=%ld FE=%ld %ld %c %ld %c",
        k,ityp[k],itypfe[k],jel[k],cjmode[k],iel[k],cimode[k]);
        fflush(fwlo);
        }
      }
    IKFLAG++;
    } 
  }
while ((strstr(cline,"EOF"))== NULL);


/*=====================================================================
* Kontrolle und Ausschrieb, Rewind
*====================================================================*/
if(IKFLAG != ne)                                 /* falsche Anzahl Elemente */
  {
  wlog88x(0,LOG_WROIXELE);
  return(AL_WROIXELE);
  }

if(ICFLAG == 6)
  {
  wrim88x(IKFLAG,TX_FOUSELE);
  wlog88x(IKFLAG,LOG_FOUSELE);
  }
else
  {
  wrim88x(IKFLAG,TX_FOUFELE);
  wlog88x(IKFLAG,LOG_FOUFELE);
  }

rewind(fdxf);

/*=====================================================================
* aufsetzpunkt fuer koinzidenz finden
*====================================================================*/
for(i= 1; i <= ip_entities; i++)                 /* Aufsetzpunkt ENTITIES */
  fgets(cline,256,fdxf);

ip_z88net = ip_entities;

do                                               /* dann 1. LINE finden */
  {  
  fgets(cline,256,fdxf);
  if((strstr(cline,"EOF")) != NULL) return(AL_NOLAYNET);
  ip_z88net++;
  }
while ((strstr(cline,"Z88NET"))== NULL);

fprintf(fwlo,"\nip_z88net=%ld",ip_z88net);
fflush(fwlo);

/*====================================================================-
* grosse elementschleife
*====================================================================*/
for(i= 1; i <= ne; i++)
  {
  if(i== 1) koffs[1]= 1;
  else      koffs[i]= koffs[i-1] + kofold;

  sub88x(i);                                     /* Anzahl Knoten liefern */
  iret= koi88x(i);                               /* Elemente scannen */
  if(iret != 0)
    {
    wlog88x(0,LOG_TOOFEW);
    return(AL_TOOFEW);
    }

  kofold= ianz;
  }

/*====================================================================-
* ueberpruefen je element, ob 2 gleiche knoten
*====================================================================*/
for(i= 1; i <= ne; i++)
  {
  sub88x(i);

  for(j= 2; j <= ianz; j++)
    {
    for(k= 1; k < j; k++)
       {
       if(koi[koffs[i]+k-1] == koi[koffs[i]+j-1])
         {
         wlog88x(i,LOG_WROIXKOI);
         return(AL_WROIXKOI);
         }
       } 
    }
  }  

/*====================================================================-
* vektor ifrei belegen
*====================================================================*/
for(i= 1; i <= nkp; i++)
  ifrei[i]= 0;

for(i= 1; i <= ne; i++)
  {
  sub88x(i);
  for(j= 1; j <= ianz; j++)
    {
    if(ifrej > ifrei[koi[koffs[i]+j-1]])
      {
      ifrei[koi[koffs[i]+j-1]]= ifrej;
      }
    }
  }

rewind(fdxf);

/*---------------------------------------------------------------------*
* Elastizitaetsgesetze ausfiltern
*---------------------------------------------------------------------*/
wlog88x(0,LOG_DECEG);
wrim88x(0,TX_DECEG);

k= 0;
IKFLAG= 0;

for(i= 1; i <= ip_entities; i++)                 /* Aufsetzpunkt ENTITIES */
  fgets(cline,256,fdxf);

do
  {
  fgets(cline,256,fdxf);
  if((strstr(cline,"MAT ")) != NULL)
    {
    sscanf(cline,"%s %ld",ctext,&j);
    if(ibflag == 0 && ipflag == 0)
      {
      sscanf(cline,"%s %ld %ld %ld %lg %lg %ld %lg",ctext,&idummy,
      &ivon[j],&ibis[j],&emod[j],&rnue[j],&intord[j],&qpara[j]);
      fprintf(fwlo,"\nMAT %ld %ld %ld %lg %lg %ld %lg",
      j,ivon[j],ibis[j],emod[j],rnue[j],intord[j],qpara[j]);
      fflush(fwlo);
      k++;     
      }
    else
      {
      sscanf(cline,
      "%s %ld %ld %ld %lg %lg %ld %lg %lg %lg %lg %lg %lg %lg",
      ctext,&idummy,
      &ivon[j],&ibis[j],&emod[j],&rnue[j],&intord[j],&qpara[j],
      &riyy[j],&eyy[j],&rizz[j],&ezz[j],&rit[j],&wt[j]);
      fprintf(fwlo,"\nMAT %ld %ld %ld %lg %lg %ld %lg %lg %lg %lg %lg %lg %lg",
      j,ivon[j],ibis[j],emod[j],rnue[j],intord[j],qpara[j],
      riyy[j],eyy[j],rizz[j],ezz[j],rit[j],wt[j]);
      fflush(fwlo);
      k++;
      } 
    IKFLAG= 1;
    }
  }
while ((strstr(cline,"EOF"))== NULL);

if(IKFLAG == 0)
  {
  wlog88x(0,LOG_WROIXM);
  return(AL_WROIXM);
  }

rewind(fdxf);

/***********************************************************************
* Randbedingungen Z88I2.TXT ausfiltern
***********************************************************************/
if(ICFLAG == 5)
  {
/*---------------------------------------------------------------------*
* Randbedingungen Z88I2.TXT: 1.Zeile ausfiltern
*---------------------------------------------------------------------*/
  wlog88x(0,LOG_DEC1ZI2);
  wrim88x(0,TX_DEC1ZI2);

  IKFLAG= 0;

  for(i= 1; i <= ip_entities; i++)               /* Aufsetzpunkt ENTITIES */
    fgets(cline,256,fdxf);

  do
    {
    fgets(cline,256,fdxf);
    if((strstr(cline,"Z88I2.TXT")) != NULL)
      {
      sscanf(cline,"%s %ld",ctext,&nrb);
      fprintf(fwlo,"\nZ88I2.TXT %ld",nrb);
      fflush(fwlo);
      IKFLAG= 1;
      goto L200;
      }
    }
  while ((strstr(cline,"EOF"))== NULL);

  if(IKFLAG != 1)
    {
    wlog88x(0,LOG_WROIXI21Z);
    return(AL_WROIXI21Z);
    }

  L200:;
  rewind(fdxf);

/*---------------------------------------------------------------------*
* Randbedingungen Z88I2.TXT: Randbedingungen
*---------------------------------------------------------------------*/
  wlog88x(0,LOG_DECI2R);
  wrim88x(0,TX_DECI2R);

  IKFLAG= 0;

  for(i= 1; i <= ip_entities; i++)              /* Aufsetzpunkt ENTITIES */
    fgets(cline,256,fdxf);

  do
    {
    fgets(cline,256,fdxf);
    if((strstr(cline,"RBD ")) != NULL)
      {
      sscanf(cline,"%s %ld",ctext,&j);
      sscanf(cline,"%s %ld %ld %ld %ld %lg",
      ctext,&idummy,&nkn[j],&ifg[j],&irflag[j],&wert[j]);
      fprintf(fwlo,"\nRBD %ld %ld %ld %ld %lg",
      j,nkn[j],ifg[j],irflag[j],wert[j]);
      fflush(fwlo);
      IKFLAG++;
      }
    }
  while ((strstr(cline,"EOF"))== NULL);

  if(IKFLAG != nrb)                              /* falsche Anzahl RBD */
    {
    wlog88x(0,LOG_WROIXI2R);
    return(AL_WROIXI2R);
    }

  rewind(fdxf);
  }

/***********************************************************************
* Spannungsparameter Z88I3.TXT ausfiltern
***********************************************************************/
if(ICFLAG == 5)
  {
  wlog88x(0,LOG_DECI3);
  wrim88x(0,TX_DECI3);

  IKFLAG= 0;

  for(i= 1; i <= ip_entities; i++)               /* Aufsetzpunkt ENTITIES */
    fgets(cline,256,fdxf);

  do
    {
    fgets(cline,256,fdxf);
    if((strstr(cline,"Z88I3.TXT")) != NULL)
      {
      sscanf(cline,"%s %ld %ld %ld",ctext,&nint,&ksflag,&isflag);
      fprintf(fwlo,"\nZ88I3.TXT %ld %ld %ld",nint,ksflag,isflag);
      fflush(fwlo);
      IKFLAG= 1;
      goto L300;
      }
    }
  while ((strstr(cline,"EOF"))== NULL);

  if(IKFLAG != 1)
    {
    wlog88x(0,LOG_WROIXI3);
    return(AL_WROIXI3);
    }

  L300:;
  fclose(fdxf);
  }
/***********************************************************************
* Beschreiben der Z88- Files
***********************************************************************/
iret= wria88x();

/***********************************************************************
* Ende Z88FX
***********************************************************************/
wlog88x(0,LOG_EXITZ88FX);
wrim88x(0,TX_EXITZ88FX);

return(iret);
}
