/* MPMorph - Amiga Morphing program */
/* Copyright (C) © 1993  Topicsave Limited */

/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* any later version. */

/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the */
/* GNU General Public License for more details. */

/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* mpaddock@cix.compulink.co.uk */

#include "g/unix.h"

#ifndef __MPCLI

/* Amiga headers */
#define INTUI_V36_NAMES_ONLY
#define INTUITION_IOBSOLETE_H
#define ASL_V38_NAMES_ONLY
#define NO_REQTOOLS_OBSOLETE

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <devices/input.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <devices/timer.h>

#include <rexx/errors.h>
#include <rexx/storage.h>

#include <libraries/amigaguide.h>

#include <libraries/reqtools.h>

/* stuff for gcc to work */
#include <dos/exall.h>
#include <graphics/scale.h>

#include <egs/egsintui.h>

#include <libraries/MPImage.h>

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/layers_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/input_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <clib/utility_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/icon_protos.h>
#include <clib/timer_protos.h>
#include <clib/alib_protos.h>
#include <clib/rexxsyslib_protos.h>
#include <clib/amigaguide_protos.h>

#include <clib/reqtools_protos.h>

#include <egs/clib/egs_protos.h>
#include <egs/clib/egsintui_protos.h>
#include <egs/clib/egsgfx_protos.h>

#include <clib/MPImage_protos.h>

#include <pragmas/exec_sysbase_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/layers_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/input_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/diskfont_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/timer_pragmas.h>
#include <pragmas/rexxsyslib_pragmas.h>
#include <pragmas/amigaguide_pragmas.h>

#include <pragmas/reqtools_pragmas.h>

#include <egs/pragmas/egs_pragmas.h>
#include <egs/pragmas/egsintui_pragmas.h>
#include <egs/pragmas/egsgfx_pragmas.h>

#include <pragmas/MPImage_pragmas.h>

#define USE_BUILTIN_MATH
#include <string.h>

/* prevent inclusion of another math library */
#define LIBRARIES_MATHFFP_H

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef _M68881
#include <math.h>
#include <m68881.h>
#else
#include <mffp.h>
#endif

extern struct Library *EGSIntuiBase;
extern struct Library *EGSGfxBase;
extern struct Library *EGSBase;

/* Progress requester */
#include "progress.h"

/* Help nodes */
extern STRPTR context[];

/* Libraries */
extern struct ExecBase *SysBase;
extern struct DosLibrary *DOSBase;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *LayersBase;
extern struct Library *GadToolsBase;
extern struct Library *AslBase;
extern struct UtilityBase *UtilityBase;
extern struct Library *RexxSysBase;
extern struct Library *AmigaGuideBase;
extern struct Device *TimerBase;
extern struct Library *IconBase;

extern struct Library *MPImageBase;

extern struct ReqToolsBase *ReqToolsBase;

/* Help stuff */
extern AMIGAGUIDECONTEXT handle;
extern struct NewAmigaGuide nag;
extern ULONG ASig;

extern struct MsgPort		*WMsgPortp;		/* Message port for Picture Windows */

extern struct List InfoList; /* List of messages */

extern struct EI_NewWindow	EGS_NewWindow;	/* EGS New window */
extern struct EI_Window		*EGS_Win;			/* EGS Window */
extern struct E_EBitMap		*EGS_BitMap;

extern void *Chain;
#define PUDDLE 2048
#define THRESH 500

enum HelpNumbers {
H_Help=0,
H_Library,
H_AllocVec,
H_OpenPoints,
H_Progress,
H_FileFormat,
H_Range,
H_MemPointsR,
H_CloseFile,
H_3Points,
H_Open,
H_ARexx,
H_Really,
HE_OldFormat,
HE_RLoad,
HE_RSave,
HE_RScale
};

#endif

extern BOOL Pic1_Open;				/* 1st image open OK */
extern BOOL Pic2_Open;				/* 2nd image open OK */

/* some work buffers */
extern char buffer[256];
extern char buffer1[512];

/* Image structure */
struct Picture {
	UBYTE					filename[256];	/* filename */
	struct				MPImage	*MPi;	/* Image */
};

extern struct Picture Pic1,Pic2;/* 1st and 2nd image */

/* Point structure */
struct MyPoint {
	struct MinNode MyNode;	/* linked into list */
	WORD x,y;		/* Coordinates in 1st image */
	WORD x1,y1;		/* 2nd image */
	WORD Cx,Cy;		/* Current image */
	LONG Cdiff;		/* seperation between two points (squared) */
	WORD xdiff;		/* x difference */
	WORD ydiff;		/* y difference */
	double xd,yd;	/* double coords for AntiAlias */
	double x1d,y1d;/* 2nd image */
	BOOL Used;		/* Is it being used? */
	struct List TList;	/* List of triangles; */
};

struct Triangle {
	struct MinNode TNode;	/* Linked into list */
	struct MyPoint *Point1;
	struct MyPoint *Point2;
	UWORD MinX,MinY,MaxX,MaxY;
};

/* List of points */
extern struct List			PointList;

/* Size of image */
extern USHORT	width, height;

extern char AnimName[256];	/* Buffer for file name to save */

extern char *Loadscript;		/* ARexx load script */

extern WORD x,y;				/* Current coords */

extern struct MyPoint **Points;	/* Pointer to points */
extern struct MyPoint **PointsAlloc;	/* The actual allocated pointer */
extern struct MyPoint **PointsX;	/* Pointer to points horizontal */
extern struct MyPoint **PointsY;	/* Pointer to points vertical */

extern WORD	Depth;	/* Number of points to check each time */

extern UWORD Mode;		/* Mode = 0 use 3 closest if no others, choose 1st 3 */
					/* Mode = 1 leave points stationary, choose 1st 3 */
					/* Mode = 2 Only calculate points once */
					/* Mode = 4 choose 3 closet, always use */
					/* Mode = 8 Delaunay Triangle algorithm */
					/* Mode = 16 Binary search - NOT USED IN THIS VERSION */

								/* SET/UNSET */
#define MODE_STAT		1	/* Stationary if no triangle/Use 3 points anyway */
#define MODE_ONCE		2	/* Only calculate once */
#define MODE_CLOSEST	4	/* Choose 3 closest/Choose 1st 3 found */
#define MODE_DELAU	8	/* Delaunay Triangle/Normal mode (sets DEPTH to 0) */

extern LONG PointCount;			/* Number of points */

extern struct MyPoint BigPoint;	/* Point far away */

extern char MyFileName[257];

#ifndef __MPCLI
extern struct Hook ProgressHook;
extern ULONG __saveds __asm ProgressH(register __a0 struct Hook *hook,
								  register __a2 APTR *object,
								  register __a1 APTR *message);

/* Settings stuff */
extern char **ArgArray;
extern char **ArgArraySettings;
#endif

extern BOOL				AntiAlias;	/* AntiAlias points */

/* Table of parameters */
extern struct Arexx {
	LONG xf;				/* Current frame */
	LONG xFrames;		/* Number of frames */
	LONG xSingle;		/* Warp or Morph */
	LONG xmove;			/* Movement 1 to 2 */
	LONG xr;				/* red of image 1 */
	LONG xg;				/* green */
	LONG xb;				/* blue */
	LONG xr2;			/* red of image 2 */
	LONG xg2;			/* green */
	LONG xb2;			/* blue */
	LONG xDo;			/* Produce this image */
	LONG xrplus;		/* Add red */
	LONG xgplus;		/* green */
	LONG xbplus;		/* blue */
	LONG xrminus;		/* subtract red */
	LONG xgminus;		/* subtract green */
	LONG xbminus;		/* subtract blue */
	LONG xDX;			/* X skip */
	LONG xDY;			/* Y skip */
	LONG xStart;		/* Start Frame number */
	LONG FILLER[32];	/* Filler for future expansion */
} Arexx;

#define f Arexx.xf
#define Frames Arexx.xFrames
#define Single Arexx.xSingle
#define move Arexx.xmove
#define r Arexx.xr
#define g Arexx.xg
#define b Arexx.xb
#define r2 Arexx.xr2
#define g2 Arexx.xg2
#define b2 Arexx.xb2
#define Do Arexx.xDo
#define rplus Arexx.xrplus
#define gplus Arexx.xgplus
#define bplus Arexx.xbplus
#define rminus Arexx.xrminus
#define gminus Arexx.xgminus
#define bminus Arexx.xbminus
#define DX Arexx.xDX
#define DY Arexx.xDY
#define Start Arexx.xStart

extern char 				FileName[256];	/* File name buffer */
extern UBYTE 				*arrayr,		/* Pointers to red,green and blue */
		  						*arrayg,
		  						*arrayb;
extern BOOL					EGS;			/* EGS Preview */
extern UBYTE		*p[3];/* chunky pointers - order for OpalVision */
#define RED p[0]
#define BLUE p[2]
#define GREEN p[1]
extern BOOL					CreateIcons;/* Create Icons on pictures? */

extern char 					*Postscript;/* ARexx postscript */
extern BOOL					Integer;

extern char *SaveFormat;
extern char *ModeName;
extern char *palette;
extern ULONG Colours;
extern BOOL Bit12;
extern BOOL QuickGrey;
extern BOOL ForceGrey;
extern BOOL Grey;
extern BOOL NoProgress;
extern struct Hook *PProgressHook;

/* Protos */
BOOL SaveFile(void);
void Close24bit(struct Picture *pic);
void DeleteAllPoints(void);
BOOL MyOpen(char *filename,BOOL JustPoints);
extern void MyArgArrayInit(int argc,char **argv, char *prefsfile,char *prefsdir);
extern void MyArgArrayDone(void);
extern UBYTE *MyArgString(UBYTE *arg2,UBYTE *arg3,BOOL reopen);
extern ULONG MyArgInt(UBYTE *arg2, long arg3,BOOL reopen);
extern BOOL MyFindToolType(UBYTE *arg2,BOOL reopen);
void OpenNewArgs(UBYTE *filename);
void help(ULONG hnum);
BOOL LoadFrames(BOOL points,BOOL image1,BOOL image2);
void CopyEGS(int line, UBYTE **er,UBYTE **eg,UBYTE **eb);
int cmpX(struct MyPoint **A,struct MyPoint **B);
int cmpY(struct MyPoint **A,struct MyPoint **B);
int cmpDiff(struct MyPoint **A,struct MyPoint **B);
BOOL	GenerateTriangles(void);
void	FreeTriangles(void);
BOOL AddTri(int aa,int bb,int cc);
#ifndef __MPCLI
void AddMessage(UBYTE *message);
#endif

/* RenderSub.c */
#ifndef __MPCLI
void DisableWindow(void);
void EnableWindow(void);
void Error(char *ErrorMessage, char *Gadget,char *extra,ULONG hnum);
LONG SendRxMsg(char *msgtxt,BOOL IgnoreError);
long *GetRx(char *title);
#endif
APTR MyAllocVec(ULONG size,ULONG requirements);
void MyFreeVec(APTR memptr);
APTR MyAllocMem(ULONG size,ULONG requirements);
void MyFreeMem(APTR memptr,ULONG size);
APTR Mymalloc(ULONG size);
APTR Mystrdup(UBYTE *str);

#ifndef __MPCLI
/* Args.c */
void argArrayDone( void );
char **argArrayInit( LONG argc, char **argv );

/* Arb stuff */
extern struct RexxHost *myhost;

void SetMaxFrame(int Frame);
void SetFrame(int Frame);
void SetMaxLine(int Line);
void SetLine(int Line);
#endif
