
/*
       File:             apict.h
       Author:           Mary Soon Lee
       Created:          16 Jan 96
       Modified:         24 Feb96

       Description: Header file for code supporting apicts, the
                    structures used to store pictures.  Elements of
                    these pictures may be circles, lines, strings,
                    rectangles, and discs (solid circles).  

                    The current version also supports documents,
                    doc_sections, and document_lists.  This code
                    may later be moved to a separate file.
*/

#ifndef APICT_H
#define APICT_H

#include "ambs.h"
#include "amma.h"
#include "expo.h"

#define MAX_APICT_STR_LEN 100

/* The structure to represent a line */
typedef struct ap_line
{
  double x1;
  double x2;
  double y1;
  double y2;
  int color;
} ap_line;

typedef struct ap_lines
{
  ap_line *l1;
  struct ap_lines *rest_lines;
} ap_lines;

/* The structure to represent a circle */
typedef struct ap_circle
{
  double x;   /* The x-coordinate of the center */
  double y;   /* The y-coordinate of the center */
  double r;   /* The radius */
  int color;
} ap_circle;

typedef struct ap_circles
{
  ap_circle *c1;
  struct ap_circles *rest_circles;
} ap_circles;

/* The structure to represent a string */
typedef struct ap_string
{
  double x;   /* The x-coordinate of the start */
  double y;   /* The y-coordinate of the start */
  char str[MAX_APICT_STR_LEN + 1];
  int color;
} ap_string;

typedef struct ap_strings
{
  ap_string *s1;
  struct ap_strings *rest_strings;
} ap_strings;

/* The structure to represent a rectangle */
typedef struct ap_rect
{
  double x;   /* The x-coordinate of the bottom left */
  double y;   /* The y-coordinate of the bottom left */
  double w;   /* The width */
  double h;   /* The height */
  int color;
} ap_rect;

typedef struct ap_rects
{
  ap_rect *r1;
  struct ap_rects *rest_rects;
} ap_rects;

/* The structure to represent a disc */
typedef struct ap_disc
{
  double x;   /* The x-coordinate of the center */
  double y;   /* The y-coordinate of the center */
  double r;   /* The radius */
  int color;
} ap_disc;

typedef struct ap_discs
{
  ap_disc *d1;
  struct ap_discs *rest_discs;
} ap_discs;

typedef struct apict
{
  int width;  /* The width of the apict.  */
  int height; /* The height of the apict.  */
  ap_lines *lines;
  ap_circles *circles;
  ap_strings *strings;
  ap_rects *rects;
  ap_discs *discs;
} apict,*apict_ptr;

typedef struct apict_set
{
  int size;
  int array_size;
  apict **array;
} apict_set;

apict *mk_apict();
void free_apict(apict *g);
void am_free_apict(apict *g); /* Same as free_apict. retained for compat. */
apict *mk_copy_apict(apict *ap);

void print_apict(apict *g);
void ap_add_line(apict *g, double x1, double y1, double x2, double y2,
                 int col);
void ap_add_circle(apict *g, double x, double y, double r, int col);
void ap_add_string(apict *g, double x, double y, char *s, int col);
void ap_add_rect(apict *g, double x, double y, double w, double h, int col);
void ap_add_disc(apict *g, double x, double y, double r, int col);
void ap_copy_from_to(apict *a_from, apict *a_to);
void set_apict_circles(apict *a);
apict *cur_apict();
void render_apict(apict *g);
void apict_on();
apict *apict_off();

apict_set *mk_empty_apict_set();
void add_to_apict_set(apict_set *aps,apict *this_apict);
int apict_set_size(apict_set *aps);
apict *apict_set_ref(apict_set *aps,int index);
void fprintf_apict_set(FILE *s,char *m1,apict_set *aps,char *m2);
void free_apict_set(apict_set *aps);
apict_set *mk_copy_apict_set(apict_set *aps);



#ifdef PC_MVIS_PLATFORM

typedef struct doc_section
{
  bool apictp;  /* TRUE iff the document_section is an apict. */
  bool expop;   /* TRUE iff the document_section is an expo.  */
  int indent;   /* Viewing the document as a whole, with x = 0 the
                                   left margin, then indent is the amount by which
                                   to indent this document_section. */
  int y_start;  /* Viewing the document as a whole, with y = 0 the
                   top, and y increasing downwards,then y_start
                   gives the y coordinate of the top of this
                   document_section.  */
  int y_end;    /* Viewing the document as a whole, with y = 0 the
                   top, and y increasing downwards,then y_start
                   gives the y coordinate of the bottom of this
                   document_section.  */
  apict *ap;    /* If apictp == TRUE, this holds the apict. */
  expo *ex;     /* If expop == TRUE, this holds the expo. */
} doc_section;

typedef struct doc_sections
{
  doc_section *ds1;
  struct doc_sections *rest_ds;
} doc_sections;

typedef struct document
{
  doc_sections *ds;
  int length;    /* The total length of the document, given in
                       the scale that the height of a graph is 512 units */
} document;

#define history_length 10

typedef document *document_ptr;

/* A record of the previous documents, the current document, and the later documents.
   This is used so that we can switch to the previous document, etc. */
typedef struct document_history
{
  document_ptr docs[history_length];
  bool no_documents;    /* TRUE iff there are no documents in the history */
  int index_cur_doc;    /* The index into docs of the current document. */
  int num_prev_docs;
  int num_next_docs;
} document_history;

extern int text_height; /* The height to use per line of text, given
                           that an apict is 512 units tall.  */
extern int line_spacing; /* The vertical spacing to allow between
                            lines of text */
extern int space_between_secs;
extern double apict_scale_by; /* A factor by which to scale apicts */
void add_apict_to_doc(document *doc, apict *ap);
void add_expo_to_doc(document *doc, expo *ex, int num_chars_per_line);
void doc_clear(document *d);
document *mk_empty_document();
void free_document(document *d);
void initialize_document_history(document_history *history);
void add_new_document_to_history(document *d, document_history *history);
bool switch_to_prev_document(document_history *history);
bool switch_to_next_document(document_history *history);
void clear_document_history(document_history *history);

#endif /* PC_MVIS_PLATFORM */
#endif /* #ifndef APICT_H */

