/* --------------------------------------------------------------------  */
/*                          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 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[MAX_LOADCASES], 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[MAX_LOADCASES];
  unsigned char  buffer[MAX_LINE_LENGTH], lc_description[MAX_LOADCASES][MAX_LINE_LENGTH];

  static int graph_Nr=-1;

  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;
      lc_time[anz_lc]    =  lcase[lc].value;
      strcpy(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 %s ", lc, lc_time[lc], 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) .. \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  length, setNr;
  unsigned char setname[MAX_LINE_LENGTH], type[MAX_LINE_LENGTH];

  if (seq_nlc!=3)
  {
    printf(" ERROR: no sequence is defined, choose the menu-entry \"Animate->Toggle Dataset Sequence\" and define a sequence\n\n\a");
    return;
  }
  length= sscanf( record, "%s%s", setname, type );
  operateAlias( setname, "se" );
  setNr=getSetNr( setname );
  if (setNr<0)
  {
    printf(" ERROR: Set (%s) is undefined\a\n", setname );
    return;
  }
  plot2D( type[0], setNr ); 
}
