/* Some headers that may get precompiled */

#include <stdio.h>
#include <stdlib.h>
#include <lists.h>
#include <strings.h>
#include <ctype.h>
#include <stdarg.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <devices/inputevent.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/rastport.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/console_protos.h>
#include <clib/alib_protos.h>	       /*HD added */
#include <clib/icon_protos.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <clib/reqtools_protos.h>
#include <libraries/reqtools.h>

/* Memory-Debugging. Just delete the Begin-Comment at the beginning of the
   next line */
/*#include <debug_mem.h> /**/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
 *  note: if you want Local routines to silently be global, simply
 *  '#define Local' to nothing.
 */

#define Prototype extern
#define Local	  static

#ifndef _DCC
#define __stkargs
#endif

#define MAXLINELEN	256
#define MAXROWS 	256
#define PINGDEPTH	10	    /* Max. number of PING/PONGs */
#define MAX_FONT_SIZE	64	    /* Font may be at most this pixel high */

#define MAXTOGGLE   256
#define QMOVE	    (0x6B|0x80)

/*#define COLT(n)  (XTbase + (n) * Xsize)*/
/*#define ROWT(n)  (YTbase + (n) * Ysize)*/

#define COLT(n)  (XTbase + ColumnPos[n])
#define ROWT(n)  (YTbase + RowPos[n])
#define COL(n)   (Xbase  + ColumnPos[n])
#define ROW(n)   (Ybase  + RowPos[n])

#define nomemory()  { memoryfail = 1; }

/*
 *  code compatibility... try to phase these usages out.
 */

typedef unsigned char	    ubyte;
typedef unsigned short	    uword;
typedef unsigned short	    ushort;		/* HD added */
typedef unsigned long	    ulong;

typedef struct MinNode	    MNODE;
typedef struct Node	    NODE;
typedef struct MinList	    MLIST;
typedef struct List	    LIST;
typedef struct MsgPort	    PORT;
typedef struct Window	    WIN;
typedef struct Message	    MSG;
typedef struct TextAttr     TA;
typedef struct TextFont     FONT;
typedef struct RastPort     RP;
typedef struct IntuiMessage	IMESS;
typedef struct IntuitionBase	IBASE;
typedef struct Menu	    MENU;
typedef struct MenuItem     ITEM;
typedef struct IntuiText    ITEXT;
typedef struct Process	    PROC;
typedef ubyte * LINE;

/*
New def. for line:

typedef struct {
     ushort flags;	// flags
     ushort len;	// length of the line
     ubyte  lvl;	// folding level
     char   text[1];	// text is directly following !
} LINE;
*/

typedef struct _ED {
    MNODE	    Node;
    WIN 	  * Win;	/* actual window */
    struct Gadget * PropGad;	/* Pointer to our PropGadget */
    FONT	  * Font;	/* actual font! */
    long	    Topline,
		    Topcolumn;	/* top left edge of text */
    long	    Line,
		    Column;	/* actual cursor position */
    long	    Lines,
		    Maxlines;	/* no of text-lines and how much space is left */
    LINE	  * List;	/* list of text-lines */
    ubyte	    Name[64];
    ubyte	    Wtitle[130];
    char	    Modified;	/* is text modified ? */
    long	    dirlock;	/* directory lock */
    char	    iconmode;	/*  window in icon mode */

    /*
     *	CONFIG INFORMATION
     */

    char  BeginConfig;
    ubyte Tabstop;
    ubyte Margin;
    char  Insertmode;
    char  IgnoreCase;
    char  Wordwrap;
    short WWCol;	    /*	word wrap column		    */
    short Winx; 	    /*	save state of non-icon window	    */
    short Winy;
    short Winwidth;
    short Winheight;
    short IWinx, IWiny;     /*	save state of icon window	    */
    int   FGPen;	    /* Pens */
    int   BGPen;
    int   HGPen;
    int   TPen;
    char  Autosplit;	    /* Split line automatically ? */
    char  Autoindent;	    /* Autoindent cursor after <RETURN> ? */
    short ASLleft;
    short ASLtop;
    short ASLwidth;
    short ASLheight;
    char  AutoUnblock;	    /* Automatic Unblock on new BLOCK-command ? */
    char  EndConfig;
} ED;

/* Define Colors */
#define TEXT_FPEN   ep->FGPen
#define TEXT_BPEN   ep->BGPen
#define BLOCK_FPEN  ep->HGPen
#define BLOCK_BPEN  ~ep->HGPen
#define TEXT_MASK   (TEXT_FPEN | TEXT_BPEN)
#define BLOCK_MASK  (TEXT_FPEN | TEXT_BPEN | BLOCK_FPEN)

/* Block-Types
    note:   BSxxx is invalid if BSline < 0,
	    BExxx is invalid if BEline < 0
    If BlockType == BT_NONE, one must not check any other values.
*/
#define BT_NONE     0	    /* No current block */
#define BT_LINE     1	    /* Block is full-line */
#define BT_NORMAL   2	    /* Block starts at BScolumn/BSline and ends at
			       BEcolumn/BEline */
#define BT_VERTICAL 3	    /* Block is a rectangle from BScolumn/BSline to
			       BEcolumn/BEline */
/*
    Current state of block (temporary)
*/
#define BF_START    64	    /* Move BSxxx instead of BExxx */
#define BF_ACTIVE   128     /* Block is currently beeing marked (values of
			       block may change) */

/* Result of lineflags(line): */
#define LINE_ABOVE	1	/* line < Ep->Topline */
#define LINE_VISIBLE	2	/* line >= Ep->Topline && line < Ep->Topline + Rows */
#define LINE_BELOW	4	/* line >= Ep->Topline + Rows */

/* Where in the block am I actually ?

   BP_INSIDE+BP_START	- Inside 1. line of block
   BP_START		- In the same line in which block starts but not inside
			  block.
   BP_START+END+INSIDE	- I am in the only line the block has.
   BP_START+BP_END	- dito but not INSIDE the block
*/
#define BP_OUTSIDE	    0
#define BP_INSIDE	    1	    /* Inside block (anywhere) */
#define BP_START	    2	    /* line == BSline */
#define BP_END		    4	    /* line == BEline */

struct Block {
    ED	 * ep;		    /* the editor the block is in */
    USHORT type;	    /* BT_xxx */
    USHORT flags;	    /* yet unused */
    LONG  start_line;	    /* start- and endline */
    LONG  end_line;
    LONG  start_column;     /* start- and endcolumn */
    LONG  end_column;
};


struct TextMarker {
    ED	 * ep;		    /* The editor the marker is for */
    LONG   line;	    /* line and column */
    LONG   column;
};


struct PropGadget {
    struct Gadget g;
    struct PropInfo p;
    struct Image i;
};


#ifndef NULL
#define NULL 0
#endif
#ifdef E
#undef E
#endif

extern MLIST DBase;
extern MLIST PBase;
extern ED    *Ep;
