/* --------------------------------------------------------------------  */
/*                          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.         */
/* --------------------------------------------------------------------  */

/* BUGS
 */

#include <cgx.h>


extern int   offset, maxIndex;                            /* offset+steps-1 = maxIndex */
extern int   basCol[3];                     /* color indexes due to basic colormap */
extern int   width_ini, height_ini; /* Grafig-Fensterbreite/hoehe */
extern int   width_menu, height_menu;
extern int   w0, w1, w_index, w_rgb, activWindow;
extern int   width_w0, height_w0;
extern int   width_w1, height_w1;
extern int   MouseMode;                                   /* status maustasten */
extern double dtx, dty, dtz, drx, dry, drz, ds;                 /* Verschiebungen */
extern double vmem[4];                                     /* kor. bis auswahl eines neuen drehpkts */
extern GLdouble R[4][4];                                   /* Rotationsmatrix */
extern unsigned char  surfFlag;                /* zeichne nur Oberflaechenelemente (1), sonst (0)*/
extern unsigned char  modelEdgeFlag;                /* zeichne mit Modell-Ecken (1), sonst (0)*/
extern unsigned char  frameFlag;                   /* mit (1) oder ohne Rahmen um das Grafikfenster */
extern unsigned char  filenamFlag;                   /* mit (1) oder ohne filename im Menufenster */
extern unsigned char  textFlag;                   /* mit (1) oder ohne text im Menufenster */
extern unsigned char  printFlag;                     /* printf 1:on 0:off */
extern unsigned char  cullFlag;                     /* (1) enable Culling */
extern unsigned char  frameFlag;               /* mit (1) oder ohne Rahmen um das Grafigfenster */
extern unsigned char  scalaFlag;                 /* mit (1) oder ohne scala und wertetexte */ 
extern double dx ,dy;                                      /* Mauskoordinaten */
extern int   steps;                   /* Schrittweite der Farbscala, und NURB aufloesung */
extern double gtol;
extern unsigned char  picture_text[MAX_LINE_LENGTH], datin[MAX_LINE_LENGTH];
extern unsigned char  psviewer[MAX_LINE_LENGTH];
extern unsigned char  delPntFlag;                    /* 1: deleted points exists */
extern unsigned char  delLineFlag;                   /* 1: deleted lines exists */
extern unsigned char  delLcmbFlag;                   /* 1: deleted lcmbs exists */
extern unsigned char  delSurfFlag;                   /* 1: deleted surfs exists */
extern unsigned char  delBodyFlag;                   /* 1: deleted bodys exists */

extern int     num_olc;          /* nr-of-original-loadcases (lc from input-file) */

extern Scale     scale[1];
extern double     *value_n;
extern Summen    anz[1];
extern Edges     *edge;
extern Nodes     *node;
extern Elements  *e_enqire;
extern Nodes     *n_anim;
extern Datasets *lcase;

extern Alias     *alias;
extern Sets      *set;
extern Psets     *pset;
extern Points    *point;
extern Lines     *line;
extern Lcmb      *lcmb;
extern Gsur      *surf;
extern Gbod      *body;
extern Nurbs     *nurbs;
extern Materials *material; 
extern Amplitudes *amplitude; 
extern SumGeo    anzGeo[1];
extern SumAsci   sumAsci[1];

extern int       num_olc;

extern int       offset;

/* for the sequence */
extern unsigned char  sequenceFlag;                  /* 1: play a sequence of LC */
extern int seqLC[4], seq_nlc;
extern int   seq_steps;                              /* anzahl der displaylisten einer sequenz */
extern int   entity_Nr;                               /* aktiv value */
extern unsigned char  entityName[13][MAX_LINE_LENGTH];              /* Bezeichnung des aktiven values */


void plot2D(unsigned char type, int setNr )
{
  FILE *handle_out, *handle_gnu;
  int i, anz_lc=0, n, lc, entity=0;

  double **dat, *lc_time=NULL;
  unsigned char  buffer[MAX_LINE_LENGTH], **lc_description=NULL;

  static int graph_Nr=-1;

  if (seq_nlc!=3)
  {
    errMsg(" ERROR: no sequence is defined, choose the menu-entry \"Animate->Toggle Dataset Sequence\" and define a sequence\n\n");
    return;
  }

  graph_Nr++;

  if((dat=(double **)malloc((int)set[setNr].anz_n *sizeof(double *)))==NULL )
  {
    printf("\n\n ERROR: malloc failed \n\n") ;
  }
  for (i=0; i<set[setNr].anz_n; i++)
  {
    if((dat[i]=(double *)malloc((int)anz->l *sizeof(double)))==NULL )
      printf("\n\n ERROR: malloc failed \n\n") ;
  }
  

  for ( n=0; n<set[setNr].anz_n; n++)
  {
    anz_lc=0;
    for(lc=seqLC[0]; lc<seqLC[2]+1; lc+=seqLC[1]-seqLC[0])
    {
      entity         =  entity_Nr-1;
      if((lc_time=(double *)realloc(lc_time, (anz_lc+2) *sizeof(double)))==NULL )
      {
        printf("\n\n ERROR: realloc failed \n\n") ;
      }

      lc_time[anz_lc]    =  lcase[lc].value;
      if ( ( lc_description = (unsigned char **)realloc(lc_description, (anz_lc+2) * sizeof(unsigned char *))) == NULL )
        printf("\n\n ERROR: realloc failure\n\n" );
      if ( ( lc_description[anz_lc] = (unsigned char *)malloc((MAX_LINE_LENGTH) * sizeof(unsigned char))) == NULL )
        printf("\n\n ERROR: realloc failure\n\n" );

      strcpy(lc_description[anz_lc], lcase[lc].dataset_text);
      /*
      printf("|%s| |%s|\n",lc_description[anz_lc], lcase[lc].dataset_text); 
      if((lc_description[anz_lc][0]==' ')||(lc_description[anz_lc][0]==(unsigned char)NULL))
        sprintf(lc_description[anz_lc],"0");
      */
      dat[n][anz_lc] =  lcase[lc].dat[entity][set[setNr].node[n]] ;
      anz_lc++;
    }
  }

  /* create plotfile */

  sprintf(buffer, "graph_%d.out", graph_Nr);
  handle_out = fopen (buffer, "w+b" );
  if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n",
     buffer); return;}
  for (lc=0; lc<anz_lc; lc++)
  {
    fprintf (handle_out, "%-5d %-12.5e %f ", lc+1, lc_time[lc], atof(lc_description[lc]));
    for ( n=0; n<set[setNr].anz_n; n++)
      fprintf (handle_out, "%-12.5e ", dat[n][lc]);
    fprintf (handle_out, "\n");
  }
  fclose(handle_out);

  /* create special purpose plotfile2 */

  sprintf(buffer, "graph_%d.out2", graph_Nr);
  handle_out = fopen (buffer, "w+b" );
  if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n",
     buffer); return;}
  fprintf (handle_out, "# node    x   y   z   dat(LC1)  dat(LC2) .. for the same entity-nr\n");
  for (n=0; n<set[setNr].anz_n; n++)
  {
    fprintf (handle_out, "%-10d %-12.5e %-12.5e %-12.5e", set[setNr].node[n], node[set[setNr].node[n]].nx* scale->w+scale->x, node[set[setNr].node[n]].ny* scale->w+scale->y, node[set[setNr].node[n]].nz* scale->w+scale->z );
    for (lc=0; lc<anz_lc; lc++)
      fprintf ( handle_out, " %-12.5e", dat[n][lc]);
    fprintf (handle_out, "\n");
  }
  fclose(handle_out);

  /* gnuplot-command-file  */

  sprintf(buffer, "graph_%d.gnu", graph_Nr);
  handle_gnu = fopen (buffer, "w+b" );
  if (handle_gnu==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n",
     buffer); return;}
  fprintf(handle_gnu, "set term postscript landscape monochrom  \n");
  fprintf(handle_gnu, "#set term x11 \n");
  sprintf(buffer, "graph_%d.ps", graph_Nr);
  fprintf(handle_gnu, "set out \"%s\"\n", buffer);
  fprintf(handle_gnu, "set grid\n");
  fprintf(handle_gnu, "set title \"Values at Nodes (%s)\"\n", datin);
  fprintf(handle_gnu, "set ylabel \" %s \"\n", lcase[seqLC[0]].compName[entity_Nr-1]);

  sprintf(buffer, "graph_%d.out", graph_Nr);
  if((type=='N')||(type=='n'))
  {
    fprintf(handle_gnu, "set xlabel \" Dataset \"\n");
    fprintf(handle_gnu, "plot ");
    for (n=0; n<set[setNr].anz_n-1; n++)
    {
      fprintf(handle_gnu, "\"%s\" using 1:%d title 'Node=%d' with linespoints, ",
            buffer, n+4, set[setNr].node[n]);
    }
    fprintf(handle_gnu, "\"%s\" using 1:%d title 'Node=%d' with linespoints\n",
            buffer, n+4, set[setNr].node[n]);
  }
  else if((type=='T')||(type=='t'))
  {
    fprintf(handle_gnu, "set xlabel \" Time \"\n");
    fprintf(handle_gnu, "plot ");
    for (n=0; n<set[setNr].anz_n-1; n++)
    {
      fprintf(handle_gnu, "\"%s\" using 2:%d title 'Node=%d' with linespoints, ",
            buffer, n+4, set[setNr].node[n]);
    }
    fprintf(handle_gnu, "\"%s\" using 2:%d title 'Node=%d' with linespoints\n ",
            buffer, n+4, set[setNr].node[n]);
  }
  else if((type=='D')||(type=='d'))
  {
    fprintf(handle_gnu, "set xlabel \" Description \"\n");
    fprintf(handle_gnu, "plot ");
    for (n=0; n<set[setNr].anz_n-1; n++)
    {
      fprintf(handle_gnu, "\"%s\" using 3:%d title 'Node=%d' with linespoints, ",
            buffer, n+4, set[setNr].node[n]);
    }
    fprintf(handle_gnu, "\"%s\" using 3:%d title 'Node=%d' with linespoints\n ",
            buffer, n+4, set[setNr].node[n]);
  }
  else printf(" ERROR: option:%c not known, use either n, t or d\n", type);

  fclose(handle_gnu);


  sprintf(buffer, "graph_%d.ps", graph_Nr);
  printf ("write %s \n", buffer);
  sprintf(buffer, "gnuplot graph_%d.gnu", graph_Nr );
  system (buffer);
  sprintf(buffer, "%s  -landscape graph_%d.ps &", psviewer, graph_Nr );
  system (buffer);

  for (i=0; i<set[setNr].anz_n; i++)  free(dat[i]);
  free(dat);

  printf ("ready \n");
}




void graph( unsigned char *record)
{
  int  i,length, entityNr=0, nr, sum;
  unsigned char name[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH];
  unsigned char  buffer[MAX_LINE_LENGTH];

  FILE *handle_out, *handle_gnu;

  length= sscanf( record, "%s%s", name, type );
  if ((compare(type, "nr", 1)==1) || (compare(type, "time",1)==1) || (compare(type, "desc", 1)==1))
  {
    operateAlias( name, "se" );
    entityNr=getSetNr( name );
    if (entityNr<0)
    {
      errMsg(" ERROR: Set (%s) is undefined", name );
      return;
    }
    plot2D( type[0], entityNr );
  } 


  else if (compare(type, "amp", 1)==1)
  {
    if(anzGeo->amps==1)
    {
      strcpy(name,amplitude[0].name);
    }
    if(compareStrings(name, "all")>0) sum=anzGeo->amps;
    else sum=1;

    for (nr=0; nr<sum; nr++)
    {
      if(sum==1) entityNr=getAmplitudeNr( name,1 );
      else entityNr=nr;
      if (entityNr<0)
      {
        printf ("ERROR: amplitude:'%s' does not exist\n", name);
        return;
      }

      sprintf(buffer, "amplitude%d.out",nr);
      handle_out = fopen (buffer, "w+b" );
      if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", buffer); return;}
      for (i=0; i<amplitude[entityNr].n; i++)
      {
        fprintf (handle_out, "%d %e %e\n", i+1, amplitude[entityNr].x[i],amplitude[entityNr].y[i]);
      }
      fclose(handle_out);
    }

    sprintf(buffer, "amplitude.gnu");
    handle_gnu = fopen (buffer, "w+b" );
    if (handle_gnu==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n",buffer); return;}
    fprintf(handle_gnu, "set term postscript landscape monochrom  \n");
    fprintf(handle_gnu, "#set term x11 \n");
    sprintf(buffer, "amplitude.ps");
    fprintf(handle_gnu, "set out \"%s\"\n", buffer);
    fprintf(handle_gnu, "set grid\n");
    fprintf(handle_gnu, "set title \"Amplitude\"\n");
    fprintf(handle_gnu, "set ylabel \" y \"\n");
    fprintf(handle_gnu, "set xlabel \" x \"\n");
    for (nr=0; nr<sum; nr++)
    {
      if(sum==1) entityNr=getAmplitudeNr( name,1 );
      else entityNr=nr;
      sprintf(buffer, "amplitude%d.out", nr);
      fprintf(handle_gnu, "plot \"%s\" using 2:3 title '%s' with linespoints\n", buffer, amplitude[entityNr].name);
    }
    fclose(handle_gnu);


    sprintf(buffer, "amplitude.ps");
    printf ("write %s \n", buffer);
    sprintf(buffer, "gnuplot amplitude.gnu" );
    system (buffer);
    sprintf(buffer, "%s  -landscape amplitude.ps &", psviewer );
    system (buffer);
  } 


  else if (compare(type, "mat", 1)==1)
  {
    if(anzGeo->mats==1)
    {
      strcpy(name,material[0].name);
      printf("%s %s nn\n",name,material[0].name);
    }
    if(compareStrings(name, "all")>0) sum=anzGeo->mats;
    else sum=1;

    for (nr=0; nr<sum; nr++)
    {
      if(sum==1) entityNr=getMatNr( name,1 );
      else entityNr=nr;
      if (entityNr<0)
      {
        printf ("ERROR: material:'%s' does not exist\n", name);
        return;
      }

      if(material[entityNr].nela)
      {
        sprintf(buffer, "elastic%d.out",nr);
        handle_out = fopen (buffer, "w+b" );
        if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", buffer); return;}
        for (i=0; i<material[entityNr].nela; i++)
        {
          fprintf (handle_out, "%d %e %e %e\n", i+1,material[entityNr].ela[i],material[entityNr].nue[i], material[entityNr].tela[i]);
        }
        fclose(handle_out);
      }

      if(material[entityNr].nexp)
      {
        sprintf(buffer, "expansion%d.out",nr);
        handle_out = fopen (buffer, "w+b" );
        if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", buffer); return;}
        for (i=0; i<material[entityNr].nexp; i++)
        {
          fprintf (handle_out, "%d %e %e\n", i+1,material[entityNr].exp[i],material[entityNr].texp[i]);
        }
        fclose(handle_out);
      }

      if(material[entityNr].ncon)
      {
        sprintf(buffer, "conductivity%d.out",nr);
        handle_out = fopen (buffer, "w+b" );
        if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", buffer); return;}
        for (i=0; i<material[entityNr].ncon; i++)
        {
          fprintf (handle_out, "%d %e %e\n", i+1,material[entityNr].con[i],material[entityNr].tcon[i]);
        }
        fclose(handle_out);
      }

      if(material[entityNr].nsph)
      {
        sprintf(buffer, "spec_heat%d.out",nr);
        handle_out = fopen (buffer, "w+b" );
        if (handle_out==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", buffer); return;}
        for (i=0; i<material[entityNr].nsph; i++)
        {
          fprintf (handle_out, "%d %e %e\n", i+1,material[entityNr].sph[i],material[entityNr].tsph[i]);
        }
        fclose(handle_out);
      }
    }

    sprintf(buffer, "material.gnu");
    handle_gnu = fopen (buffer, "w+b" );
    if (handle_gnu==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n",buffer); return;}
    fprintf(handle_gnu, "set term postscript landscape monochrom  \n");
    fprintf(handle_gnu, "#set term x11 \n");
    sprintf(buffer, "material.ps");
    fprintf(handle_gnu, "set out \"%s\"\n", buffer);
    fprintf(handle_gnu, "set grid\n");
    fprintf(handle_gnu, "set title \"Material\"\n");


    if(material[entityNr].nela)
    {
      fprintf(handle_gnu, "set ylabel \" Elastic Modulus \"\n");
      fprintf(handle_gnu, "set xlabel \" Temperature \"\n");
      fprintf(handle_gnu, "plot ");
      for (nr=0; nr<sum-1; nr++)
      {
        if(sum==1) entityNr=getMatNr( name,1 );
        else entityNr=nr;
        sprintf(buffer, "elastic%d.out", nr);
        fprintf(handle_gnu, "\"%s\" using 4:2 title '%s' with linespoints, ", buffer, material[entityNr].name);
      }
      if(sum==1) entityNr=getMatNr( name,1 );
      else entityNr=nr;
      sprintf(buffer, "elastic%d.out", nr);
      fprintf(handle_gnu, "\"%s\" using 4:2 title '%s' with linespoints\n", buffer, material[entityNr].name);
    }


    if(material[entityNr].nexp)
    {
      fprintf(handle_gnu, "set ylabel \" Expansion Coefficient \"\n");
      fprintf(handle_gnu, "set xlabel \" Temperature \"\n");
      fprintf(handle_gnu, "plot ");
      for (nr=0; nr<sum-1; nr++)
      {
        if(sum==1) entityNr=getMatNr( name,1 );
        else entityNr=nr;
        sprintf(buffer, "expansion%d.out", nr);
        fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints, ", buffer, material[entityNr].name);
      }
      if(sum==1) entityNr=getMatNr( name,1 );
      else entityNr=nr;
      sprintf(buffer, "expansion%d.out", nr);
      fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints\n", buffer, material[entityNr].name);
    }

    if(material[entityNr].ncon)
    {
      fprintf(handle_gnu, "set ylabel \" Conductivity \"\n");
      fprintf(handle_gnu, "set xlabel \" Temperature \"\n");
      fprintf(handle_gnu, "plot ");
      for (nr=0; nr<sum-1; nr++)
      {
        if(sum==1) entityNr=getMatNr( name,1 );
        else entityNr=nr;
        sprintf(buffer, "conductivity%d.out", nr);
        fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints, ", buffer, material[entityNr].name);
      }
      if(sum==1) entityNr=getMatNr( name,1 );
      else entityNr=nr;
      sprintf(buffer, "conductivity%d.out", nr);
      fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints\n", buffer, material[entityNr].name);
    }

    if(material[entityNr].nsph)
    {
      fprintf(handle_gnu, "set ylabel \" Specific Heat \"\n");
      fprintf(handle_gnu, "set xlabel \" Temperature \"\n");
      fprintf(handle_gnu, "plot ");
      for (nr=0; nr<sum-1; nr++)
      {
        if(sum==1) entityNr=getMatNr( name,1 );
        else entityNr=nr;
        sprintf(buffer, "spec_heat%d.out", nr);
        fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints, ", buffer, material[entityNr].name);
      }
      if(sum==1) entityNr=getMatNr( name,1 );
      else entityNr=nr;
      sprintf(buffer, "spec_heat%d.out", nr);
      fprintf(handle_gnu, "\"%s\" using 3:2 title '%s' with linespoints\n", buffer, material[entityNr].name);
    }
    fclose(handle_gnu);


    sprintf(buffer, "material.ps");
    printf ("write %s \n", buffer);
    sprintf(buffer, "gnuplot material.gnu" );
    system (buffer);
    sprintf(buffer, "%s  -landscape material.ps &", psviewer );
    system (buffer);
  } 

  else printf("ERROR: type:%s not known\n\n", type);
}
