/****************************************************************************/
/* This file is part of FreeFEM.                                            */
/*                                                                          */
/* FreeFEM is free software: you can redistribute it and/or modify          */
/* it under the terms of the GNU Lesser General Public License as           */
/* published by the Free Software Foundation, either version 3 of           */
/* the License, or (at your option) any later version.                      */
/*                                                                          */
/* FreeFEM 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 Lesser General Public License for more details.                      */
/*                                                                          */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with FreeFEM. If not, see <http://www.gnu.org/licenses/>.          */
/****************************************************************************/
/* SUMMARY : ...                                                            */
/* LICENSE : LGPLv3                                                         */
/* ORG     : LJLL Universite Pierre et Marie Curie, Paris, FRANCE           */
/* AUTHORS : Pascal Frey                                                    */
/* E-MAIL  : pascal.frey@sorbonne-universite.fr                             */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _GRAFIC_H_
#define _GRAFIC_H_

#define MAX_LIST 4
#define MAXISO 5

#define C_ON (1 << 0)
#define C_EDIT (1 << 1)
#define C_VOL (1 << 2)
#define C_UPDATE (1 << 3)
#define C_FREEZE (1 << 4)
#define C_CAP (1 << 5)
#define C_REDO (1 << 6)
#define C_HIDE (1 << 7)

/* view modes */
#define S_BDRY (1 << 0)
#define S_FILL (1 << 1)
#define S_COLOR (1 << 2)
#define S_MAP (1 << 3)
#define S_MATERIAL (1 << 4)
#define S_ALTITUDE (1 << 5)
#define S_DISPL (1 << 6)

#define MONO 0
#define LEFT 1
#define RIGHT 2

enum {
  WIRE = S_BDRY,
  HIDDEN = S_BDRY + S_FILL,
  DEPTH = S_BDRY + S_COLOR,
  FILL = S_FILL + S_COLOR,
  SHADED = S_BDRY + S_FILL + S_COLOR,
  SIZEMAP = S_BDRY + S_FILL + S_MAP
};

enum { LTria, LQuad, LTets, LHexa, LEdges, LPoint };

enum { PERSPECTIVE, CAMERA, ORTHO };

enum { X_AXIS = 0, Y_AXIS, Z_AXIS };

enum { VECTOR, CONE };

/* items */
#define S_AXIS (1 << 0)
#define S_BOX (1 << 1)
#define S_GRID (1 << 2)
#define S_GEOM (1 << 3)
#define S_ISO (1 << 4)
#define S_PALETTE (1 << 5)
#define S_NUMP (1 << 6)
#define S_NUMF (1 << 7)

/* type */
#define S_FLAT (1 << 0)    /* render with facet normals */
#define S_SCISSOR (1 << 1) /* scissoring mode */
#define S_FOLLOW (1 << 2)  /* picking mode */
#define S_NORMAL (1 << 3)
#define S_OPPOS (1 << 4)
#define S_DECO (1 << 5)
#define S_PATH (1 << 6)
#define S_RESET (1 << 7)

/* iso-values */
#define MAX_ISO 5
#define S_ISOLINE (1 << 1)
#define S_ISOSURF (1 << 2)
#define S_STREAML (1 << 3)
#define S_STREAMR (1 << 4)
#define S_VECTOR (1 << 5)
#define S_CRITP (1 << 6)
#define S_PARTICLE (1 << 7)

typedef struct sperspective {
  float fovy, depth;
  float matrix[16], alpha, gamma;
  int rubix, rubfx, rubiy, rubfy;
  ubyte pmode, rubber;
} Persp;
typedef Persp *pPersp;
typedef struct triangle {
  float a[3], b[3], c[3];
  float va, vb, vc;
  float na[3], nb[3], nc[3];
} triangle;
typedef struct material {
  float amb[4], emi[4], dif[4], spe[4], shininess;
  float ext[6];
  GLint list;
  int depmat[MAX_LIST];
  int ref, sort;
  char name[128];
  ubyte flag;
} Material;
typedef Material *pMaterial;
typedef struct _cell {
  int id;
  int x, y;
  float min, max;
  float value;
  float step;
  char *info;
  char *format;
} cell;
typedef struct transform {
  float pos[3];                   /* current mouse position */
  float angle, axis[3];           /* rotation angle + axis */
  float panx, pany, opanx, opany; /* screen translation */
  float matrix[16], oldmat[16];   /* transformation matrix */
  float rot[16], tra[16];
  int mstate, mbutton, manim;
} Transform;
typedef Transform *pTransform;
typedef struct cube {
  pTransform cubetr;
  float cmi[3], cma[3];
  ubyte active;
} Cube;
typedef Cube *pCube;
typedef struct clip {
  pTransform cliptr;
  double eqn[4];
  ubyte active;
} Clip;
typedef Clip *pClip;
typedef struct camera {
  GLfloat eye[3]; /* Position of the camera */
  GLfloat speed[3], spmod, altinc;
  int vecup;
} Camera;
typedef Camera *pCamera;

/* scene parameters */
typedef struct sparam {
  float back[4], line[4], edge[4], sunpos[4], clip[6];
  float cm, dpi, coeff, cumtim, cumpertime, maxtime, pertime, dt;
  float eyesep, linewidth, pointsize;
  short xi, yi, xs, ys;
  int nbmat;
  char pscolor[10];
  ubyte sunp, linc, advtim, nbpart;
} Param;

/* trajectory */
typedef struct straj {
  int np;
  float *pt;
  float *tg;
  float sec;
  GLuint tlist;
} Trajet;

/* streamlines */
typedef struct sstream {
  double size, norm;
  float xmin, xmax, ymin, ymax, zmin, zmax;
  float *listp;
  float stpt[4][3], stcol[4];
  int stnp, stiso[4];
  short nbstl;
  ubyte typtrack;
} Stream;
typedef Stream *pStream;
typedef struct strgrd {
  pTransform strtr;
  GLuint grid;
  ubyte active;
} Strgrd;
typedef Strgrd *pStrgrd;
typedef struct siso {
  float val[MAXISO + 2];
  float col[MAXISO + 2];
  ubyte palette, ptyp;
} Iso;
typedef struct scene {
  pTransform view;
  pClip clip;
  pCube cube;
  pPersp persp;
  pCamera camera;
  pMaterial material;
  pStream stream;
  /*pStrgrd    stg;*/
  Param par;
  Trajet path;
  Iso iso;
  float dmin, dmax;       /* scene size */
  float shrink;           /* shrink value */
  float cx, cy, cz;       /* center of scene */
  GLuint dlist[MAX_LIST]; /* display lists */
  GLuint mlist[MAX_LIST]; /* metric lists */
  GLuint ilist[MAX_LIST]; /* iso-surfaces */
  GLuint clist[MAX_LIST];
  GLuint cmlist[MAX_LIST]; /* clipped elts */
  GLuint vlist[MAX_LIST];  /* vector list */
  GLuint *slist, cplist;   /* streamlines */
  GLuint glist, nlist;     /* geometry lists */
  GLuint grid;
  GLuint picklist;
  int *matsort;
  short idwin, idmesh; /* window, mesh id */
  short master, slave;
  ubyte item; /* display items */
  ubyte mode; /* render mode */
  ubyte type;
  ubyte isotyp;
  ubyte picked;
} Scene;
typedef Scene *pScene;

#endif

#ifdef __cplusplus
}
#endif
