#include <intuition/intuitionbase.h>

#ifdef AZTEC_C
#include <functions.h>
#include <pragmas.h>
#endif // AZTEC_C

#ifdef LATTICE
#include <proto/all.h>
#endif // LATTICE

#ifdef REQLIB
#include <libraries/reqbase.h>

void BruceFileRequester(struct ReqFileRequester *);
#ifdef AZTEC_C
#pragma amicall(ReqBase, 0x54, BruceFileRequester(a0))
#endif
#ifdef LATTICE
#pragma libcall ReqBase BruceFileRequester 54 801
#endif

#endif // REQLIB
#ifdef ASLLIB
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <pragmas/asl_pragmas.h>

UBYTE *FilePart(UBYTE *path);
UBYTE *PathPart(UBYTE *path);
BOOL AddPart(UBYTE *dirname, UBYTE *filename, unsigned long size );
#ifdef AZTEC_C
/* Lattice users will have to use 2.0 amiga.lib for this one
   I don't include clib/dos_protos.h and pragmas/dos_lib.h because
   of name conflicts, and many prototypes differ from the manx ones */
#pragma amicall(DOSBase, 0x366, FilePart(d1))
#pragma amicall(DOSBase, 0x36c, PathPart(d1))
#pragma amicall(DOSBase, 0x372, AddPart(d1,d2,d3))
#endif // AZTEC_C
#endif // ASLLIB


#include <devices/input.h>
#include <devices/keymap.h>
#include <devices/console.h>
#include <devices/clipboard.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <exec/execbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>

#ifndef DSIZE
#define DSIZE 130
#define FCHARS 30
#endif

/* Mikael's memory macros */
#define Create(_Obj)     AllocMem((LONG)sizeof(struct _Obj), MEMF_PUBLIC|MEMF_CLEAR)
#define Kill(_Obj)       FreeMem(_Obj, (LONG)sizeof(*_Obj))
#define Delete(_Obj)     if (_Obj) FreeMem(_Obj, (LONG)sizeof(*_Obj))

/* Mikael's list macros */
#define HEADSENTINEL(l) ((struct Node *)&(((struct List *)(l))->lh_Head))
#define TAILSENTINEL(l) ((struct Node *)&(((struct List *)(l))->lh_Tail))
#define HEAD(l) (((struct List *)(l))->lh_Head)
#define TAIL(l) (((struct List *)(l))->lh_Tail)
#define PRED(n) (((struct Node *)(n))->ln_Pred)
#define SUCC(n) (((struct Node *)(n))->ln_Succ)
#define ENDLISTP(n) (SUCC(n) == NULL)
#define LASTP(n) (ENDLISTP(SUCC(n)))
#define FIRSTP(n) (PRED(PRED(n)) == NULL)
#define EMPTYLIST(l) (PRED(TAILSENTINEL(l)) == HEADSENTINEL(l))

#define MAPLIST(list,nodetype,loopvar)       \
    for (loopvar = (nodetype)HEAD(list);     \
         !ENDLISTP(loopvar);                 \
         loopvar = (nodetype)SUCC(loopvar))

#define SAFEMAPLIST(list,nodetype,loopvar,safevar)                          \
    for (loopvar = (nodetype)HEAD(list), safevar = (nodetype)SUCC(loopvar); \
         safevar != NULL;                                                   \
         loopvar = safevar, safevar = (nodetype)SUCC(loopvar))

#define KILLLIST(list,nodetype)                \
{                                              \
    REGISTER nodetype *_n1, *_n2;              \
    SAFEMAPLIST(list, nodetype *, _n1, _n2) {  \
        FreeMem(_n1, (LONG)sizeof(nodetype));  \
    }                                          \
}

#define SNAPRSRC "Snap.resource"

struct SnapRsrc {
    struct Node node;
    struct Task *Task;
    WORD Priority;
    WORD gfxqual;
    WORD textqual;
    WORD insertkey;
    WORD cwkey;
    char Prepend[17];
    char Append[17];
    WORD flags;
    LONG chardelay;
    LONG linedelay;
    UWORD CrawlPtrn;
    WORD StartUnit;
    WORD FrameMask;
    WORD BadChar;
    WORD CacheSize;
    WORD Leading;
    struct MinList CachedWindows;
    struct TextFont *AlternateFont;
};

#define XEROX           1
#define EARLYPATCH      2
#define TRUEUNDERSCORE  4
#define JOINLONG        8
#define SIMPLEREFRESH  16

struct Snap {
    ULONG Size;
    char Chars[1];
};

#define MAX_Depth 8

struct GfxSnap
{
	struct Gadget DiskGad;
	struct Gadget ClipGad;
	struct Gadget VProp;
	struct Gadget HProp;
	struct PropInfo VInfo;
	struct PropInfo HInfo;
	struct Image VImage;
	struct Image HImage;
	WORD topbar, leftbar, rightbar, bottombar;
	LONG x, y;
	LONG width, height;
	LONG depth;
	LONG viewmode;
	UBYTE rgb[ (1L << MAX_Depth)][ 3];
	SHORT pagew;
	SHORT pageh;
	struct Window *window;
	struct BitMap *BitMap;
};

#define MINWIDTH  90
#define MINHEIGHT 50

struct CacheWindow {
    struct MinNode Node;
    struct Window *Window;
    SHORT xoff;
    SHORT yoff;
    SHORT fw;
    SHORT fh;
    struct TextFont *font;
};

#define SAVEGAD 1
#define DISKGAD 2
#define CLIPGAD 3
#define NAMEGAD 4
#define VPROP   5
#define HPROP   6

struct CBFHandle {
    WORD Type;
    union {
        BPTR File;
        struct IOClipReq *ClipReq;
    } Handle;
};

#define CBFCLIP 0
#define CBFFILE 1

#define TitleFont(win) ((struct TextFont *)(win->IFont ? win->IFont : win->RPort->Font))

#define Swap2L(_x,_y) { REGISTER LONG _t = _x; _x = _y; _y = _t; }

#define noaction 0
#define snapgfx  1  /* window */
#define snaptext 2  /* text */
#define insert   4  /* inserting */
#define cancel	 5

#define waiting   0
#define selregion 1
#define waitext   2
#define selgfx    3
#define waitgfx   4

#define UNIT_FRAME 1 /* rect of chars */
#define UNIT_CHAR  2 /* characters with line wrap */
#define UNIT_WORD  3 /* words with line wrap */
#define UNIT_LINE  4 /* lines */
#define CHEIGHT   24 /* Max height of snap font */

#include <string.h>     /* Prototyping of string functions */
#include <stdlib.h>     /* Prototyping of standard lib functions */

VOID SaveClip(UBYTE *, ULONG);
struct Snap *FetchClip(VOID);
VOID MultiDraw(struct RastPort *, LONG, Point *);
VOID crawl_frame(LONG);
VOID erase_frame(VOID);
VOID draw_frame(LONG);
ULONG AsciiToInputEvent(ULONG, struct InputEvent *, struct KeyMap *);
struct Screen *WhichScreen(VOID);
struct Window *WhichWindow(struct Screen *);


VOID CacheSync(struct TextFont *);
VOID CacheWindow(struct Window *, LONG, LONG, SHORT, SHORT, struct TextFont *);
struct CacheWindow *GetCachedWindow(struct Screen *, struct Window *);
struct TextFont *SmartOpenFont(struct TextAttr *);
VOID CloseStuff(VOID);
VOID CloseLibs(VOID);
WORD OpenLibs(VOID);
WORD OpenStuff(VOID);
VOID SafePatch(VOID);
VOID SafeRestore(VOID);
WORD bump(struct CBFHandle *, WORD, UBYTE *, WORD);
ULONG WriteBody(struct BitMap *, struct CBFHandle *);
WORD SaveGS(struct GfxSnap *, struct CBFHandle *);
//WORD isdigit(char);
LONG dectoint(char *);
LONG hextoint(char *);
VOID InsertAscii(ULONG);
VOID GadText(struct Gadget *, char *, LONG);
VOID SwapColorMap(struct GfxSnap *);
VOID CheckWindowMsgs(VOID);
WORD SetSnapFont(struct TextFont *);
WORD SnapIsSpace(LONG, LONG);
VOID update_frame(VOID);
VOID FindWord(VOID);
VOID ChangeUnit(VOID);
VOID ExtendSelection(VOID);
WORD SnapChars(VOID);
WORD HandleChars(VOID);
VOID FixHeights(VOID);
struct GfxSnap *SnapGfx(struct RastPort *);
VOID ExtendGfx(VOID);
VOID gfx_frame(VOID);
WORD HandleGfx(VOID);
struct Window *opensharedwindow(struct NewWindow *);
VOID closesharedwindow(struct Window *);
VOID SetUpBorder(struct Border *, struct Gadget *);
VOID AdjustSize(struct GfxSnap *);
VOID SyncGS(struct GfxSnap *);
SHORT OpenCW(VOID);
UBYTE __stdargs __saveds interpret(UWORD *);
VOID __stdargs __saveds CopyFont(VOID);
VOID __stdargs __saveds myhandler();

ULONG AsciiToInputEvent( ULONG ascii, register struct InputEvent *ie, struct KeyMap *km);

VOID SafePatch( void);
VOID SafeRestore( void);

VOID CBFInit(struct CBFHandle *CBFH);
VOID CBFEndWrite(struct CBFHandle *CBFH);
VOID CBFEndRead(struct CBFHandle *CBFH);
ULONG CBFSeek(struct CBFHandle *CBFH, LONG Offset, LONG Origin);
LONG CBFWrite(struct CBFHandle * CBFH, STRPTR Buf, ULONG BufSize);
LONG CBFRead(struct CBFHandle *CBFH, STRPTR Buf, ULONG BufSize);

VOID erase_frame( void);
VOID crawl_frame( LONG dir);
VOID draw_frame( LONG ft);

void __stdargs __saveds myhandler( void);

int disp( register struct RexxMsg *msg, register struct rexxCommandList *dat, char *p);
