/* $Id: me2.h,v 1.3 1992/11/08 22:56:24 mike Exp $ */

/* $Log: me2.h,v $
 * Revision 1.3  1992/11/08  22:56:24  mike
 * - Added macro for new buffer flag: `BFVIEW'.
 *
 * Revision 1.2  1992/10/03  02:18:48  mike
 * - A small change for the Atari ST/TT version.
 *
 */

/*
 *	ME2.H 	MODULE
 *
 * This file is the general header file for all parts of the ME2
 *   display editor. It contains definitions used by everyone.
 */

/* Craig Durland	Public Domain
 *   Distributed "as is", without warranties of any kind, but comments,
 *     suggestions and bug reports are welcome.
 */

#ifndef ME2_H
#define ME2_H


#include <os.h>
#include <dstring.h>
#include <dtable.h>
#include <const.h>
#include <ed.h>

#if UX_OS
#define NFILEN		512	/* # of bytes, file name */
#else
#define NFILEN		128	/* # of bytes, file name */
#endif
#define NBUFN		 80	/* # of bytes, buffer name */
#define NLINE		256	/* # of bytes, user typed line */
#define FLINE		512	/* # of bytes, line in a file */
#define NKBDM		256	/* # of strokes, keyboard macro */

/* ******************************************************************** */
/* ************************* KEYS ************************************* */
/* ******************************************************************** */

#define CTLX		PFIX1	/* ^X prefix key */

/* ******************************************************************** */
/* ************ Some useful constants ********************************* */
/* ******************************************************************** */

#undef TRUE
#undef FALSE

	/* return codes */
#define FALSE		0
#define TRUE		1
#define ABORT		2

	/* File I/O constants */
#define FIOSUC		0	/* File I/O: success. */
#define FIOFNF		1	/* File I/O: file not found. */
#define FIOEOF		2	/* File I/O: end of file. */
#define FIOERR		3	/* File I/O: error. */

	/* Last command run flags */
#define CFLINE		0x0001	/* Last command was next-line or prev-line */
#define CFCUT		0x0002	/* Last command was a cut */
#define CFUNDO		0x0004	/* Last command was a undo */
#define CFCHAR		0x0008	/* Last command was insert character */

	/* Command completion constants */
#define CC_SYS		0x01	/* system keywords */
#define CC_PGM		0x02	/* pgms */
#define CC_MUTT		0x04	/* Mutt keywords */
#define CC_BUF		0x08	/* buffer names */
#define CC_SYSVAR	0x10	/* sys vars */
#define CC_FNAME	0x20	/* file names */

#define CC_TRIGGER	' '	/* default command completion trigger */

	/* Undo constants */
#define BU_INSERT	0	/* Characters were inserted */
#define BU_DELETE	1	/* Characters were deleted */
#define BU_UNCHANGED	2	/* Buffer contents OK */
#define BU_SP		3	/* Sequence point */

	/* Internal hook constants.  See main.c */
#define RESIZE_HOOK	0
#define PROCESS_HOOK	1
#define GC_HOOK		2

#define NUM_HOOKS	3

/***************************************************************************
 *									   *
 * All text is kept in circularly linked lists of Line structures.	   *
 *   These begin at the header line (which is the blank line beyond the	   *
 *   end of the buffer).  This line is pointed to by the Buffer.  Each	   *
 *   line contains a the number of bytes in the line (the "used" size),	   *
 *   the size of the text array, and the text.  The end of line is not	   *
 *   stored as a byte; it's implied.					   *
 *									   *
 ***************************************************************************/

typedef struct Line
{
  struct Line *l_next;		/* Link to the next line */
  struct Line *l_prev;		/* Link to the previous line */
  int16 l_size;			/* Allocated size */
  int16 l_used;			/* Used size */
  unsigned char l_text[1];	/* A bunch of characters */
} Line;

#define lforw(lp)	((lp)->l_next)
#define lback(lp)	((lp)->l_prev)
#define lgetc(lp,n)	((lp)->l_text[n])
#define lputc(lp,n,c)	((lp)->l_text[n] = (c))
#define llength(lp)	((lp)->l_used)

/***************************************************************************
 *									   *
 * Marks point between two characters in a buffer.			   *
 * See mark.c for more info.						   *
 *									   *
 ***************************************************************************/

typedef struct { Line *line; int16 offset; } Mark;

#define THE_DOT		0	/* mark id of the dot */
#define THE_MARK	1	/* mark id of the mark */

/***************************************************************************
 *									   *
 * There is a window structure allocated for every active display window.  *
 *   The windows are kept in a big list, in top to bottom screen order,	   *
 *   with the listhead at first_window.  Each window contains its own	   *
 *   dot.								   *
 * The flag field contains some bits that are set by commands to guide	   *
 *   redisplay; although this is a bit of a compromise in terms of	   *
 *   decoupling, the full blown redisplay is just too expensive to run for *
 *   every input character.						   *
 * A window frame is the the chunk of the buffer that is displayed on the  *
 *   screen.  It starts at top_line and extends for w_ntrows lines.  The   *
 *   framing is OK if the dot is on a line within the frame.		   *
 ***************************************************************************/

typedef struct Window
{
  struct Window *nextw;		/* Next window */
  struct Buffer *wbuffer;	/* Buffer displayed in window */
  struct Line   *top_line;	/* Top line in the window */
  Mark  dot;			/* dot in window */
  uint8 w_toprow;		/* top row of window (origin 0) */
  uint8 w_ntrows;		/* # of rows of text in window */
  char  w_force;		/* If NZ, forcing row.  signed */
  int16 lmargin;		/* left margin */
  uint8 w_flag;			/* window update hint flags */
  Line *elp;			/* pointer to edited line if WFEDIT */
} Window;

#define WFFORCE		0x01	/* Window needs forced reframe */
#define WFMOVE		0x02	/* Movement from line to line */
#define WFEDIT		0x04	/* Editing within a line */
#define WFHARD		0x08	/* Better to do a full display */
#define WFMODE		0x10	/* Update mode line */

#define dot_moved()		/* The dot moved horizontally */

/***************************************************************************
 *									   *
 * Text is kept in buffers.  A buffer struct, described below, exists for  *
 *   every buffer in the system.  The buffers are kept in a list (sorted   *
 *   by name), to make it easier for commands that search for a buffer by  *
 *   name.								   *
 * A list of marks is kept in the buffer.  The dot is the first mark in	   *
 *   the list.  See mark.c for more info.				   *
 * The text for the buffer is kept in a circularly linked list of lines.   *
 *   header_line is a pointer to a dummy line (which contains no text and  *
 *   is not part of the buffer) that is used to mark the start of text -   *
 *   it points to the first "real" line.  When walking lines in a buffer,  *
 *   the header_line is considered the last line in the buffer.		   *
 * 									   *
 ***************************************************************************/

typedef struct Buffer
{
  struct Buffer *nextb;		/* pointer to next Buffer */
  uint16 id;			/* buffer id - unique identifier */
  Line header_line;		/* pointer to the header Line */
  void *marks;			/* dot and marks */
  dString b_fname;		/* name of file attached to this buffer */
  dString b_bname;		/* Buffer name */
  int32 b_flags;		/* Flags - only the lower 8 are used by ME2 */
  dTable lkeys;			/* key bindings local to this buffer */
  int			/* buffer local vars */
    tabsize,			/* blanks per tab (0 => use ^I) */
    wrap_col;			/* column to word wrap at (left edge is 1) */
  void *bvars;			/* Mutt buffer variables */
  void *undos;			/* Buffer's undo list */
} Buffer;

#define BFCHG		0x01	/* Changed since last write */
#define BFNOCARE	0x02	/* Don't care what happens to buffer */
#define BFHIDDEN	0x04	/* User don't wanna see this buffer */
#define BFUNDO		0x08	/* Keep an undo list for this buffer */
#define BFMODE		0x10	/* Tickle bit to force modeline update */
#define BFIMMORTAL	0x20	/* 0 => temp buffer that can be GC'd */
#define BFINTERACTIVE	0x40	/* A buffer for humans */
#define BFBADREAD	0x80	/* Buffer didn't read file correctly */
#define BFVIEW		0x100	/* A read-only buffer */

#define SCRATCH_BUFFER "*scratch*"	/* the scratch buffer */

#define BUFFER_FIRST_LINE(bp)  (bp)->header_line.l_next
#define BUFFER_LAST_LINE(bp)   &(bp)->header_line
#define BUFFER_HEADER_LINE(bp) &(bp)->header_line

/***************************************************************************
 *									   *
 * The starting position of a region, and the size of the region in	   *
 *   characters, is kept in a region structure.				   *
 * Used by the region commands.						   *
 *									   *
 ***************************************************************************/

typedef struct
{
  Mark mark;		/* top of the region */
  int32 r_size;		/* Length in characters */
  int16
    ulcol,		/* upper left screen column ... */
    width, height;	/* of the rectangle enclosing the region */
} Region;

/* ******************************************************************** */
/* ***************** Bags : see bag.c ********************************* */
/* ******************************************************************** */

typedef struct Bag
{
  uint8 type;			/* what the bag contains */
  uint16 id;			/* bag id - unique identifier */
  int16 width, height;		/* of the rectangle, else undefined */
  declare_dTable_of(char) text;	/* bag contents */
  struct Bag *next;		/* next bag */
} Bag;

/* ******************************************************************** */
/* ***************** Externs ****************************************** */
/* ******************************************************************** */

extern Bag
  *cut_buffer;		/* in cutbuf.c */
extern Buffer
  *curbp,		/* Current buffer: buffer.c */
  *first_buffer;	/* Head of list of buffers: buffer.c */
extern int
  thisflag,		/* Flags, this command: main.c */
  lastflag,		/* Flags, last command: main.c */
  mline_dirty,		/* Stuff in message line: display.c */
  screen_is_garbage,	/* State of screen unknown: display.c */
  do_undo;		/* TRUE if saving undos for current buffer: buffer.c */
extern Mark *the_dot;	/* the dot in the current buffer: buffer.c */
extern Window
  *curwp,		/* Current window: window.c */
  *first_window;	/* Head of list of windows: window.c */

extern Buffer	*bfind();		/* in buffer.c */
extern Bag	*alloc_bag();		/* in bag.c */
extern char	*malloc();
extern KeyCode	t_getchar(), getkey(), getkeyX();
extern Line	*lalloc();		/* Allocate a line: line.c */
extern Mark	*id_to_mark();		/* in mark.c */


#endif
