/* Convert and display images */

/* mark@topic.demon.co.uk */
/* mpaddock@cix.compulink.co.uk */

/* This is freely distributable */

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/utility.h>

#include <dos/dos.h>

#include <math.h>

/* EGS Stuff	*/
#include <egs/clib/egs_protos.h>
#include <egs/pragmas/egs_pragmas.h>

#include <egs/clib/egsintui_protos.h>
#include <egs/pragmas/egsintui_pragmas.h>

#include <egs/clib/egsgfx_protos.h>
#include <egs/pragmas/egsgfx_pragmas.h>

#include <egs/egsintui.h>

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

#include <libraries/MPImage.h>
#include <pragmas/MPImage_pragmas.h>
#include <clib/MPImage_protos.h>
#include <dos.h>
#include <string.h>
#include <dos/rdargs.h>

#define TEMPLATE "FROM/A,X/N/K,Y/N/K,MINX/N/K,MINY/N/K,MAXX/N/K,MAXY/N/K,PUBSCREEN/K,EGS/S,NOREMAP/S,CLONE/S,TO/K,FORMAT/K,FORCEGREY/S,PALETTE/K,COLOURS/K/N,12BIT/S,LINEAR/S,WHITE0/S,MODENAME/K,NOPROGRESS/S,GUI/S"

#define OPT_FILE			0
#define OPT_X				1
#define OPT_Y				2
#define OPT_MINX			3
#define OPT_MINY			4
#define OPT_MAXX			5
#define OPT_MAXY			6
#define OPT_SCREEN		7
#define OPT_EGS			8
#define OPT_NOREMAP		9
#define OPT_CLONE			10
#define OPT_TO				11
#define OPT_FORMAT		12
#define OPT_FORCEGREY	13
#define OPT_PALETTE		14
#define OPT_COLOURS		15
#define OPT_12BIT			16
#define OPT_LINEAR		17
#define OPT_WHITE0		18
#define OPT_MODENAME		19
#define OPT_PROGRESS		20
#define OPT_GUI			21

#define OPT_COUNT			22

extern long __oslibversion=39;

extern long __stack = 16000;

struct Library *MPImageBase;

const char Version[]="$VER: ConvertMPImage 5.1 (1.10.96)";

UBYTE NewMap256[256] = {  1,   2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
								  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
								  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
								  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
								  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
								  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
								  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
								 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
								 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
								 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
								 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
								 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
								 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
								 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
								 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
								 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,  0
								};
UBYTE NewMap16[16] = {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,  0
							};

int
main(int argc,char **argv) {
	BOOL FromWB = FALSE;
	struct RDArgs *rdargs = NULL;
	LONG opts[OPT_COUNT] = {
		0
	};
	int resx = RETURN_OK;
	struct EasyStruct es = {
		sizeof(struct EasyStruct),
		0,
		"ConvertMPImage",
		NULL,
		"Ok"
	};
	struct MPImage *MPi;
	struct Screen *screen;
	struct Window *win;
	struct IntuiMessage *msg;
	BOOL done;
	struct EI_NewWindow	EGS_NewWindow = {0};	// EGS New window
	struct EI_Window		*EGS_Win;				// EGS Window
	struct EI_EIntuiMsg 	*EGSmsg;					// Message from the EGS windows
	ULONG newx=0,newy=0;

	if (argc == 0) {
		argc = _WBArgc;
		argv = _WBArgv;
		FromWB = TRUE;
		if (argc < 2) {
			es.es_TextFormat = (char *)"Double Click with an Image to run";
			EasyRequestArgs(NULL,&es,NULL,NULL);
			return RETURN_WARN;
		}
		opts[OPT_FILE] = (LONG)argv[1];
		
	}
	else {
		if (!(rdargs = ReadArgs((char *)TEMPLATE, opts, NULL))) {
			PrintFault(IoErr(), NULL);
			return RETURN_ERROR;
		}
		if (opts[OPT_GUI]) {
			FromWB=TRUE;
		}
	}
	if (MPImageBase = OpenLibrary("MPImage.library",5)) {
		SetMPImageScreen((char *)opts[OPT_SCREEN],opts[OPT_PROGRESS]?0:MPIF_PROGRESS);
		if (opts[OPT_TO] || opts[OPT_FORMAT]) {
			if (MPi=LoadMPImage((UBYTE *)opts[OPT_FILE],NULL,
										(opts[OPT_FORCEGREY] ? MPIF_FORCEGREY : MPIF_GREY) |
										(opts[OPT_LINEAR] ? MPIF_LINEARGREY : 0))) {
				if (opts[OPT_MINX]) {
					if (MPi->Width < *((ULONG *)opts[OPT_MINX])) {
						newx = *((ULONG *)opts[OPT_MINX]);
					}
				}
				if (opts[OPT_MAXX]) {
					if (MPi->Width > *((ULONG *)opts[OPT_MAXX])) {
						newx = *((ULONG *)opts[OPT_MAXX]);
					}
				}
				if (!opts[OPT_MINX] && !opts[OPT_MAXX]) {
					if (opts[OPT_X]) {
						newx = *((ULONG *)opts[OPT_X]);
					}
				}
				if (opts[OPT_MINY]) {
					if (MPi->Height < *((ULONG *)opts[OPT_MINY])) {
						newy = *((ULONG *)opts[OPT_MINY]);
					}
				}
				if (opts[OPT_MAXY]) {
					if (MPi->Height > *((ULONG *)opts[OPT_MAXY])) {
						newy = *((ULONG *)opts[OPT_MAXY]);
					}
				}
				if (!opts[OPT_MINY] && !opts[OPT_MAXY]) {
					if (opts[OPT_Y]) {
						newy = *((ULONG *)opts[OPT_Y]);
					}
				}
				if (newx || newy) {
					if (!newx) {
						newx = MPi->Width;
					}
					if (!newy) {
						newy = MPi->Height;
					}
					if (!RescaleMPImage(MPi,newx,newy)) {
						if (FromWB) {
							es.es_TextFormat = MPImageErrorMessage();
							EasyRequestArgs(NULL,&es,NULL,NULL);
						}
						else {
							Printf(MPImageErrorMessage());
							Printf("\n");
						}
						resx = RETURN_FAIL;
					}
				}
				if (!resx) {
					UBYTE *GreyMap = NULL;
					if (opts[OPT_WHITE0]) {
						if (!opts[OPT_FORMAT] || !stricmp((UBYTE *)opts[OPT_FORMAT],MPI_BW16)) {
							GreyMap = NewMap16;
						}
						else {
							if (!stricmp((UBYTE *)opts[OPT_FORMAT],MPI_BW256)) {
								GreyMap = NewMap256;
							}
						}
					}
					if (!SaveMPImage((UBYTE *)opts[OPT_TO],
										MPi->Red, MPi->Green, MPi->Blue,
										MPi->Width, MPi->Height,
										MPIS_MODENAME,opts[OPT_MODENAME],
										MPIS_FORMAT,opts[OPT_FORMAT],
										MPIS_PALETTE,opts[OPT_PALETTE],
										opts[OPT_COLOURS]?MPIS_COLOURS:TAG_IGNORE,opts[OPT_COLOURS] ? *((ULONG *)opts[OPT_COLOURS]) : 0,
										MPIS_12BIT, opts[OPT_12BIT],
										MPIS_LINEAR, opts[OPT_LINEAR],
										MPIS_GREYMAP, GreyMap,
										TAG_END)) {
						if (FromWB) {
							es.es_TextFormat = MPImageErrorMessage();
							EasyRequestArgs(NULL,&es,NULL,NULL);
						}
						else {
							Printf(MPImageErrorMessage());
							Printf("\n");
						}
						resx = RETURN_FAIL;
					}
				}
				FreeMPImage(MPi);
			}
			else {
				if (FromWB) {
					es.es_TextFormat = MPImageErrorMessage();
					EasyRequestArgs(NULL,&es,NULL,NULL);
				}
				else {
					Printf(MPImageErrorMessage());
					Printf("\n");
				}
				resx = RETURN_FAIL;
			}
		}
		else {
			if (opts[OPT_EGS]) {
				if ((EGSBase = OpenLibrary((char *)"egs.library",0)) &&
					 (EGSGfxBase = OpenLibrary((char *)"egsgfx.library",0)) &&
				    (EGSIntuiBase = OpenLibrary((char *)"egsintui.library", 0))) {
				   screen = NULL;
					if (MPi=LoadMPImage((UBYTE *)opts[OPT_FILE],screen,MPIF_EGS)) {
						if (opts[OPT_MINX]) {
							if (MPi->Width < *((ULONG *)opts[OPT_MINX])) {
								newx = *((ULONG *)opts[OPT_MINX]);
							}
						}
						if (opts[OPT_MAXX]) {
							if (MPi->Width > *((ULONG *)opts[OPT_MAXX])) {
								newx = *((ULONG *)opts[OPT_MAXX]);
							}
						}
						if (!opts[OPT_MINX] && !opts[OPT_MAXX]) {
							if (opts[OPT_X]) {
								newx = *((ULONG *)opts[OPT_X]);
							}
						}
						if (opts[OPT_MINY]) {
							if (MPi->Height < *((ULONG *)opts[OPT_MINY])) {
								newy = *((ULONG *)opts[OPT_MINY]);
							}
						}
						if (opts[OPT_MAXY]) {
							if (MPi->Height > *((ULONG *)opts[OPT_MAXY])) {
								newy = *((ULONG *)opts[OPT_MAXY]);
							}
						}
						if (!opts[OPT_MINY] && !opts[OPT_MAXY]) {
							if (opts[OPT_Y]) {
								newy = *((ULONG *)opts[OPT_Y]);
							}
						}
						if (newx || newy) {
							if (!newx) {
								newx = MPi->Width;
							}
							if (!newy) {
								newy = MPi->Height;
							}
							if (!RescaleMPImage(MPi,newx,newy)) {
								if (FromWB) {
									es.es_TextFormat = MPImageErrorMessage();
									EasyRequestArgs(NULL,&es,NULL,NULL);
								}
								else {
									Printf(MPImageErrorMessage());
									Printf("\n");
								}
								resx = RETURN_FAIL;
							}
						}
						if (!resx) {
							EGS_NewWindow.LeftEdge = 0;
							EGS_NewWindow.TopEdge = 20;
							EGS_NewWindow.Width = MPi->Width;
							EGS_NewWindow.Height = MPi->Height;
							EGS_NewWindow.MinWidth = 20;
							EGS_NewWindow.MinHeight = 20;
							EGS_NewWindow.MaxWidth = MPi->Width;
							EGS_NewWindow.MaxHeight = MPi->Height;
							EGS_NewWindow.Screen = NULL;
							EGS_NewWindow.Bordef.SysGadgets = EI_WINDOWSIZE | EI_WINDOWFRONT | EI_WINDOWFLIP |
																		 EI_WINDOWARROWL | EI_WINDOWARROWR | EI_WINDOWARROWU | EI_WINDOWARROWD |
																		 EI_WINDOWSCROLLH | EI_WINDOWSCROLLV | EI_WINDOWDRAG |
																		 EI_WINDOWCLOSE;
							EGS_NewWindow.FirstGadgets = NULL;
							EGS_NewWindow.Title = (char *)opts[OPT_FILE];
							EGS_NewWindow.Flags = EI_GIMMEZEROZERO | EI_SUPER_BITMAP | EI_WINDOWACTIVE | EI_REPORTMOUSE | EI_QUICKSCROLL | EI_RMBTRAP;
							EGS_NewWindow.IDCMPFlags = EI_iCLOSEWINDOW;
							EGS_NewWindow.Port = NULL;
							EGS_NewWindow.Menu = NULL;
							EGS_NewWindow.Render = NULL;
							if (EGS_Win = EI_OpenWindow(&EGS_NewWindow)) {
								E_ActivateEGSScreen();
								EG_CopyBitMapRastPort(MPi->EGS_BitMap,EGS_Win->RPort,0,0,MPi->Width,MPi->Height,0,0);
								done = FALSE;
								while	(!done) {
									WaitPort(EGS_Win->UserPort);
									while (EGSmsg = (struct EI_EIntuiMsg *)GetMsg(EGS_Win->UserPort)) {
										switch (EGSmsg->Class) {
										case EI_iCLOSEWINDOW:
											done = TRUE;
											break;
										default:
											break;
										}
										ReplyMsg((struct Message *)EGSmsg); 
									}
								}
								EI_CloseWindow(EGS_Win);
							}
						}
						FreeMPImage(MPi);
					}
					else {
						if (FromWB) {
							es.es_TextFormat = MPImageErrorMessage();
							EasyRequestArgs(NULL,&es,NULL,NULL);
						}
						else {
							Printf(MPImageErrorMessage());
							Printf("\n");
						}
						resx = RETURN_FAIL;
					}
				}
				if (EGSIntuiBase) {
					CloseLibrary(EGSIntuiBase);
				}
				if (EGSGfxBase) {
					CloseLibrary(EGSGfxBase);
				}
				if (EGSBase) {
					CloseLibrary(EGSBase);
				}
			}
			else {
				if (screen = LockPubScreen((UBYTE *)opts[OPT_SCREEN])) {
					if (MPi=LoadMPImage((UBYTE *)opts[OPT_FILE],screen,
								(opts[OPT_CLONE] ? MPIF_CLONEBITMAP : 0) | 
								(opts[OPT_NOREMAP] ? MPIF_NOREMAP : 0))) {
						if (opts[OPT_MINX]) {
							if (MPi->Width < *((ULONG *)opts[OPT_MINX])) {
								newx = *((ULONG *)opts[OPT_MINX]);
							}
						}
						if (opts[OPT_MAXX]) {
							if (MPi->Width > *((ULONG *)opts[OPT_MAXX])) {
								newx = *((ULONG *)opts[OPT_MAXX]);
							}
						}
						if (!opts[OPT_MINX] && !opts[OPT_MAXX]) {
							if (opts[OPT_X]) {
								newx = *((ULONG *)opts[OPT_X]);
							}
						}
						if (opts[OPT_MINY]) {
							if (MPi->Height < *((ULONG *)opts[OPT_MINY])) {
								newy = *((ULONG *)opts[OPT_MINY]);
							}
						}
						if (opts[OPT_MAXY]) {
							if (MPi->Height > *((ULONG *)opts[OPT_MAXY])) {
								newy = *((ULONG *)opts[OPT_MAXY]);
							}
						}
						if (!opts[OPT_MINY] && !opts[OPT_MAXY]) {
							if (opts[OPT_Y]) {
								newy = *((ULONG *)opts[OPT_Y]);
							}
						}
						if (newx || newy) {
							if (!newx) {
								newx = MPi->Width;
							}
							if (!newy) {
								newy = MPi->Height;
							}
							if (!RescaleMPImage(MPi,newx,newy)) {
								if (FromWB) {
									es.es_TextFormat = MPImageErrorMessage();
									EasyRequestArgs(NULL,&es,NULL,NULL);
								}
								else {
									Printf(MPImageErrorMessage());
									Printf("\n");
								}
								resx = RETURN_FAIL;
							}
						}
						if (!resx) {
							if (win = OpenWindowTags(NULL,
														WA_CloseGadget, TRUE,
														WA_PubScreen, screen,
														WA_SuperBitMap, MPi->BitMap,
														WA_IDCMP, IDCMP_CLOSEWINDOW,
														WA_InnerWidth, MPi->Width,
														WA_InnerHeight, MPi->Height,
														WA_Title, opts[OPT_FILE],
														WA_DragBar, TRUE,
														WA_NoCareRefresh, TRUE,
														WA_AutoAdjust, TRUE,
														WA_GimmeZeroZero,TRUE,
														TAG_END)) {
								done = FALSE;
								while	(!done) {
									WaitPort(win->UserPort);
								 	while (msg = (struct IntuiMessage *)GetMsg(win->UserPort)) {
								 		switch (msg->Class) {
								 		case IDCMP_CLOSEWINDOW:
									 		// Close window
											done = TRUE;
						 					break;
								 		default:
									 		// unknown message
								 			break;
									 		}
										ReplyMsg((struct Message *)msg);
							 		}
								}	
								CloseWindow(win);
							}
						}
						FreeMPImage(MPi);
					}
					else {
						if (FromWB) {
							es.es_TextFormat = MPImageErrorMessage();
							EasyRequestArgs(NULL,&es,NULL,NULL);
						}
						else {
							Printf(MPImageErrorMessage());
							Printf("\n");
						}
						resx = RETURN_FAIL;
					}
					UnlockPubScreen(NULL,screen);
				}
				else {
					if (FromWB) {
						es.es_TextFormat = "Failure locking Public Screen %s";
						EasyRequest(NULL,&es,NULL,(UBYTE *)opts[OPT_SCREEN]);
					}
					else {
						Printf("Failure locking Public Screen %s\n",(UBYTE *)opts[OPT_SCREEN]);
					}
				}
			}
		}
		CloseLibrary(MPImageBase);
	}
	else {
		if (FromWB) {
			es.es_TextFormat = (char *)"Error opening MPImage.library";
			EasyRequestArgs(NULL,&es,NULL,NULL);
		}
		else {
			Printf((char *)"Error opening MPImage.library\n");
		}
		resx = RETURN_FAIL;
	}
	if (rdargs) {
		FreeArgs(rdargs);
	}
	return resx;
}
