/* Libraries */
#include <libraries/mui.h>

/* protos */
#include <clib/muimaster_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

/*  Pragmas  */
#include <pragmas/muimaster_pragmas.h>
#include <pragmas/exec_pragmas.h>

/*  Ansi  */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <dos.h>

struct Library *MUIMasterBase;
struct DosLibrary *DOSBase;

char err[2*FAULT_MAX];

/* MUIBuilder */
#include "GUI.h"
#include "Hack.c"
#include "LS.c"

#define about_txt "\033c\
\033bTowerAssault Hack\033n\n\n\
This little Programm was programmed\n\
by \033bALeX Kazik\033n. ItŽs FreeWare. Soure\n\
Code is avaiable. Read TFM for usage.\n\
\n\
Contact me:\n\
akazik@TechFak.Uni-Bielefeld.DE\n\
\n\
or\n\
\n\
AleX Kazik\n\
Stapenhorststr. 81\n\
33615 Bielefeld\n\
GERMANY"

#define minmax(MIN,a,MAX) min(max(MIN,a),MAX)

/* titel */
static void title(void){
	printf("[32mTA-Hack V1.0 ©1996 ALeX Kazik[0m\n");
}

/* Init function */
static int init(char *argv0){
	if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))){
		title();
		printf("%s: Can't Open MUIMaster Library\n",argv0);
		return(FALSE);
	}
	return(TRUE);
}

/* main-gui function */
BOOL running = TRUE;
static int main_gui(char *argv0, BOOL force){
	struct ObjApp * App; /* Application object */
	ULONG	signal, plr;
	APTR aboutwin = NULL;

	/* Program initialisation ( you need to write it yourself) */
	if(!init(argv0))
		return(20);

	/* Create Application : generated by MUIBuilder */
	if(!(App = CreateApp())){
		CloseLibrary(MUIMasterBase);
		return(20);
	}

	/* Init */
	set(App->TX_STATUS, MUIA_Text_Contents, findTA());
	
	if(found==0 || (found>2 && !force))
		set(App->GRP_PLAYER, MUIA_Disabled, TRUE);
	else{
		set(App->STR_LIVES, MUIA_String_Integer, *LIVES[0]);
		set(App->STR_MONEY, MUIA_String_Integer, *MONEY[0]);
		set(App->CY_PLAYER, MUIA_Cycle_Active, 0);
	}
	
	if(found==0 || found>=4 || (found==3 && !force))
		set(App->GRP_LS, MUIA_Disabled, TRUE);

	while (running){
		switch (DoMethod(App->App,MUIM_Application_Input,&signal)){
		case MUIV_Application_ReturnID_Quit:
			running = FALSE;
			break;
		case ID_LIVES:
			get(App->CY_PLAYER, MUIA_Cycle_Active, &plr);
			setlives(plr, App->STR_LIVES);
			set(App->WINDOW, MUIA_Window_ActiveObject, App->STR_MONEY);
			break;
		case ID_MONEY:
			get(App->CY_PLAYER, MUIA_Cycle_Active, &plr);
			set(App->CY_PLAYER, MUIA_Cycle_Active, 1-plr);
			break;
		case ID_PLAYER:
			get(App->CY_PLAYER, MUIA_Cycle_Active, &plr);
			setlives(1-plr, App->STR_LIVES);
			setmoney(1-plr, App->STR_MONEY);
			set(App->STR_LIVES, MUIA_String_Integer, *LIVES[plr]);
			set(App->STR_MONEY, MUIA_String_Integer, *MONEY[plr]);
			set(App->WINDOW, MUIA_Window_ActiveObject, App->STR_LIVES);
			break;
		case ID_PAGES:
			get(App->GRP_PAGES, MUIA_Group_ActivePage, &plr);
			if(plr == 1)
				set(App->WINDOW, MUIA_Window_ActiveObject, App->STR_LIVES);
			break;
		case ID_ABOUT_MUI:
			if (!aboutwin){
				aboutwin = AboutmuiObject,
					MUIA_Window_RefWindow, App->WINDOW,
					MUIA_Aboutmui_Application, App->App,
					End;
			}
			if (aboutwin)
				set(aboutwin,MUIA_Window_Open,TRUE);
			else
				DisplayBeep(0);
			break;
		case ID_ABOUT:
			MUI_RequestA(App->App, App->WINDOW, NULL, NULL, "*OK", about_txt, NULL);
			break;
		case ID_SAVE:
			sprintf(err+FAULT_MAX, "\0332%s", Save(App->GA_STATUS));
			set(App->GA_STATUS, MUIA_Gauge_InfoText, err+FAULT_MAX);
			break;
		case ID_LOAD:
			sprintf(err+FAULT_MAX, "\0332%s", Load(force,App->GA_STATUS));
			set(App->GA_STATUS, MUIA_Gauge_InfoText, err+FAULT_MAX);
			break;
		}
		if (running && signal)
			if (Wait(signal | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
				running = FALSE;
	}
	get(App->CY_PLAYER, MUIA_Cycle_Active, &plr);
	setlives(plr, App->STR_LIVES);
	setmoney(plr, App->STR_MONEY);
	DisposeApp(App);
	CloseLibrary(MUIMasterBase);
	return(0);
}

/* brk-function*/
static int brkfunc(void){
	running = FALSE;
	return(0);
}

/* Arguments */
char ArgStr[] = "PL1LIVES/N,PL2LIVES/N,MONEY/N,LOAD/S,SAVE/S,FILE=NAME/K,MUI=GUI/S,FORCE/S";
struct {
	LONG *PL1LIVES, *PL2LIVES, *MONEY;
	LONG LOAD, SAVE;
	char *NAME;
	LONG GUI, FORCE;
} ArgArray = {NULL, NULL, NULL, NULL};

static char *setORnot(LONG *a){
	return(a?" (set)":"");
}

/* Main */
int main(int argc, char **argv){
	struct RDArgs *rda;
	int ret = 20;

	if(onbreak(brkfunc)){
		title();
		printf("%s: CouldŽnt install break trap.\n",argv[0]);
		return(20);
	}

	DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L);
	if(!DOSBase){
		title();
		printf("%s: CouldŽnt open dos.library V37.\n",argv[0]);
		return(20);
	}

	if(argc == 0)
		ret=main_gui(argv[0],FALSE);
	else if(!(rda = ReadArgs(ArgStr, (LONG *)&ArgArray, NULL))){
		dummy = IoErr();
		title();
		PrintFault(dummy,argv[0]);
	}else{
		if(ArgArray.NAME)
			savefile = ArgArray.NAME;
		if(ArgArray.GUI)
			ret=main_gui(argv[0], ArgArray.FORCE);
		else{
			title();
			printf("%s: %s\n",argv[0],findTA());
			if(found != 0){
				if(ArgArray.LOAD){
					if(found >= 4)
						printf("%s: DoŽnt know, how to load.\n",argv[0]);
					else if(found == 3 && !ArgArray.FORCE)
						printf("%s: Programm unidentified. (Try FORCE)\n",argv[0]);
					else
						printf("%s: %s\n",argv[0],Load(ArgArray.FORCE,NULL));
				}
				if(found>2 && !ArgArray.FORCE)
					printf("%s: Programm unidentified. (Try FORCE)\n",argv[0]);
				else{
					if(ArgArray.PL1LIVES)
						*LIVES[0] = minmax(0,*ArgArray.PL1LIVES,99);
					if(ArgArray.PL2LIVES)
						*LIVES[1] = minmax(0,*ArgArray.PL2LIVES,99);
					if(ArgArray.MONEY)
						*MONEY[0] = *MONEY[1] = minmax(0,*ArgArray.MONEY,999999);
				}
				printf("Player1: %d Lives%s\n",*LIVES[0],setORnot(ArgArray.PL1LIVES));
				printf("         %d CR%s\n",*MONEY[0],setORnot(ArgArray.MONEY));
				printf("Player2: %d Lives%s\n",*LIVES[1],setORnot(ArgArray.PL1LIVES));
				printf("         %d CR%s\n",*MONEY[1],setORnot(ArgArray.MONEY));
				if(ArgArray.SAVE){
					if(found >= 4)
						printf("%s: DoŽnt know, how to save.\n",argv[0]);
					else if(found == 3 && !ArgArray.FORCE)
						printf("%s: Programm unidentified. (Try FORCE)\n",argv[0]);
					else
						printf("%s: %s\n",argv[0],Save(NULL));
				}
				ret=0;
			}
		}
		FreeArgs(rda);
	}
	
	CloseLibrary((struct Library *) DOSBase);
	
	return(ret);
}
