/* Time-stamp: <96/12/23 16:47:38 john> */

/* 
# Purpose: Exports from <a href="#make-grid.c">make-grid.c</a>, and defines the cell, row and grid structures.
 */

/* A grid has an array (and list, but that's more of a construction
   line) or rows; and a row an array (and a list) of cells.
 */

typedef struct cell {
  struct cell *next;


  /* If an entry is spread over several cells horizontally or
     vertically, the cells have the same "entry" field and the
     "x_into" and "y_into" fields indicate how far into it this cell
     is.
     */
  struct entry *entry;
  int x_into;
  int y_into;

  /* We put a pointer to the title of the entry in here, and set the
     width to the length thereof, and the height to one. If we want to
     spread the title vertically, the separate cells going down have
     separate cell_texts, each with the appropriate width.
   */
  char *cell_text;
  int title_width;

  /* On some forms of output, we may wish to respect the "length" and
     "depth" attributes, which specify that this entry is larger than
     normal; the unit is the "normal entry", e.g. you might say that
     Sheeps' Green extends along Fen Causeway for the length of 10
     houses, and goes as far back from the road as 30 houses.
   */
  int phys_width;
  int phys_height;

} CELL;

typedef struct row {
  struct row *next;
  int row_number;
  /* The list of cells is where we store them until we hae enough
     information to construct the array of cells; and later, for
     managing their space. */
  struct cell *cell_list;
  struct cell **cells;
  int min_rank, max_rank;
  int phys_y;
} ROW;

#define cell_n(_r_,_i_) (((_r_)->cells)[((_i_)-((_r_)->min_rank))])

typedef struct grid {
  /* Mark where we read this page from. */
  char *page_type;
  char *page_name;
  /* The central_entry is the road down the middle of the page, which
     is the first entry in the attribute file. */
  struct entry *central_entry;
  /* The list of rows is where we store them until we hae enough
     information to construct the array of rows; and later, for
     managing their space. */
  struct row *row_list;
  int n_rows;
  struct row **rows;
  int *row_title_widths;
  int *phys_xs;
  int phys_top;
  int min_rank, max_rank;
  struct entry *entries;
} GRID;

#define cell_yx_storable(_g_,_y_,_x_) \
  (((_y_) >= 0) && \
   ((_y_) <= ((_g_)->n_rows)) && \
   (((((_g_)->rows)[(_y_)])->min_rank) <= (_x_)) && \
   ((_x_) <= ((((_g_)->rows)[(_y_)])->max_rank)))

#define cell_yx_raw(_g_,_y_,_x_) (cell_n((((_g_)->rows)[(_y_)]), (_x_)))

#define cell_yx(_g_,_y_,_x_) (cell_yx_storable(_g_,_y_,_x_) ? (cell_yx_raw(_g_,_y_,_x_)) : ((struct cell *)NULL))

extern struct grid *entries_to_grid(struct entry *entries);
extern void show_row(struct row *row, int row_number_for_labelling);
extern void show_grid(struct grid *grid);
extern void free_grid(struct grid *grid);

extern struct grid *make_area_layout_grid(struct entry *entry,
					  struct entry *entries,
					  char *area_layout_data,
					  int debug_gridding);

/* end of grid.h */
