
#ifndef DATA_TYPES_H
#define DATA_TYPES_H


#ifndef SYSGLOBALS_H
#include <p2c/sysglobals.h>
#endif

#ifndef MAT_STUFF_H
#include "mat_stuff.h"
#endif

#ifndef CRT_STUFF_H
#include "crt_stuff.h"
#endif

#ifndef BB_STUFF_H
#include "bb_stuff.h"
#endif

#ifndef GR_STUFF_H
#include "gr_stuff.h"
#endif


typedef enum {
  o_base, 
  pr_none, pr_dot, pr_line, pr_box, pr_circle, pr_ellipse, pr_ngon, pr_text, pr_inst, pr_last
} objkinds;

typedef enum {
  l_line, l_nArrow, l_wArrow, l_polygon, l_curve
} lineType;

typedef struct path_elem {
  struct path_elem *next;
  struct object *obj;
  boolean rev;
} path_elem;

typedef struct path_head {
  struct path_head *next;
  path_elem *path;
  boolean closed, fill;
} path_head;

typedef struct base_obj {
  struct figure *parent;
  short refcount;   /* reference count */
  path_head *paths;
} base_obj;

typedef struct color_rec {
  short priority, value;
} color_rec;

typedef struct pr_inst_rec {
  /* Object to call other Bases */
  struct object *contents;
  long rot;   /* In degrees */
  long tx, ty;   /* Translation component */
  long sx, sy;   /* Scaling in x and y */
  long den;   /* Denominator (applies to sx,sy) */
  boolean matOnly;   /* Only use M? */
  boolean closed;   /* Don't show insides? */
  mat_matrix m;   /* Computed matrix */
} pr_inst_rec;   /* (set by set_instance_mat) */

typedef struct pr_dot_rec {
  long x, y;
} pr_dot_rec;

typedef struct pnt_elem {
  struct pnt_elem *next;
  long x, y;
} pnt_elem;

typedef struct pr_line_rec {
  boolean h1, h2;   /* Arrow heads at start, end */
  boolean curve;   /* Is this a curve? */
  boolean closed;   /* Is this a closed polygon? */
  short lwid;   /* Line width */
  short wwid;   /* Wing width */
  short wlen;   /* Wing length */
  pnt_elem *pnts;   /* List of points */
} pr_line_rec;

typedef struct pr_box_rec {
  /* IMPORTANT, x1<=x2 and y1<=y2 */
  long x1, y1, x2, y2;
} pr_box_rec;

typedef struct pr_circle_rec {
  long cx, cy, r;
} pr_circle_rec;

typedef struct pr_ellipse_rec {
  long cx, cy, a, b, s, l, r;   /* start, length, rotation */
  boolean pie;   /* Make like a pie-chart?? */
} pr_ellipse_rec;

typedef struct pr_ngon_rec {
  long x, y;
  short rad, sides;
} pr_ngon_rec;

typedef struct pr_text_rec {
  long x, y;
  centerType orig;   /* Default center stuff*/
  short scale;   /* Scale (in points) */
  short rot;   /* Rotation Angle*/
  short slant;   /* Slant Angle   */
  short font;   /* Which text font */
  Char words[256], TeXwords[256];
} pr_text_rec;

typedef struct object {
  struct object *next, *prev;
  bbrec bb;
  color_rec color;
  objkinds kind;
  union {
    base_obj base;
    pr_dot_rec d;
    pr_line_rec l;
    pr_box_rec b;
    pr_circle_rec c;
    pr_ellipse_rec e;
    pr_ngon_rec n;
    pr_text_rec t;
    pr_inst_rec i;
  } okind;
} object;

/* TYPE */

typedef struct point {
  long x, y;
} point;

typedef struct figure {
  struct figure *next;
  Char name[81];
  object *guts;   /* This points to an INSTANCE obj */
  Char edit_date[81];
  Char mapFile[fidleng + 1];
  short changes;   /* How many changes since last save */
  boolean active;   /* Currently being written/drawn? */
  boolean thisfile;   /* Belongs to file being written? */
  boolean written;   /* Used during save */
  short grid, linewidth, wing_length;
  /* color       : shortInt; */
  /*
  mbb_ll      : point;
  mbb_ur      : point;
  frame_ll    : point;
  frame_ur    : point;
  */
} figure;

/*brand new, modified since version on disk, same as disk*/
typedef enum {
  enfant, modif, established
} incore_status;

typedef struct fileSpec {
  struct fileSpec *next;
  Char fileName[fidleng + 1], defMapFile[fidleng + 1];
  figure *figures;
  incore_status status;
} fileSpec;


/* Defaults for arrows */

#define asc             64   /* Arrow SCale */

#define def_wlenN       (asc * 10)

/* normal arrow wing length (along line) */
#define def_wwidN       (asc * 4)   /* normal arrow wing width (perp line) */
#define def_lwidW       (asc * 4)   /* half wide-arrow/line width */
#define def_wlenW       (asc * 20)  /* wide-arrow length */
#define def_wwidW       (asc * 8)   /* wide-arrow wing size */


extern figure *curFigure;   /* Current figure */
extern fileSpec *curFile;   /* Current file */
extern fileSpec *files;   /* List of files */

extern short curColor;  /* Current Color */
extern short curLWid;  /* Wide Line stuff */
extern boolean doubleArrows;  /* Arrow information */

/* Wide Arrow stuff */
extern short curLWidW;   /* Line width */
extern short curWWidW;   /* Wing width */
extern short curWLenW;   /* Wing length */

/* Narrow Arrow stuff */
extern short curWWidN;   /* Wing width */
extern short curWLenN;   /* Wing length */

/* Text attributes */
extern centerType curTextOrig;
extern short curTextScale;   /* Scaling in Points */
extern short curTextRot;   /* Rotation angle */
extern short curTextSlant;   /* Slant angle */
extern short curTextFont;   /* Font number */

extern boolean showInstBB;  /* Show bounding box of instances? */

extern short curRots;  /* Number of possible rotations */


extern long numpnts(pnt_elem *p);
extern void restore_color(void);
extern void set_line_mbb(bbrec *bb, pnt_elem *p);
extern void set_instance_mbb(object *o, boolean recurse);
extern void set_instance_mat(object *o);
extern void set_ellipse_mbb(object *o);

extern void set_base_mbb(object *o, boolean recurse);
extern long primBytes(objkinds k);
extern object *getprim(objkinds k, long lx, long ly, long hx, long hy);
extern object *make_instance(object *cont, mat_matrix mat, boolean insert);
extern object *make_dot(long ex, long ey);
extern pnt_elem *make_pnt_elem(long x, long y);
extern object *make_line(pnt_elem *p, lineType lt);
extern object *make_line0(pnt_elem *p_p, short p_lwid, short p_wwid,
			  short p_wlen, boolean p_h1, boolean p_h2,
			  boolean p_closed, boolean p_curve);
extern object *make_box(long sx, long sy, long ex, long ey);
extern object *make_circle(long x, long y, long rad);
extern object *make_ellipse(long x, long y, long a0, long b0, long start,
			    long len, long rot);
extern object *make_text(long x0, long y0, Char *s);
extern figure *make_figure(Char *n);
extern void finishFigure(figure *fig, short g, short lw, short wl, short c,
			 short sd, short sw);
extern figure *find_figure(Char *n);
extern fileSpec *make_filespec(Char *fn, incore_status s);

extern Char *today(Char *Result);


#endif /*DATA_TYPES_H*/
