/*                          Programm -WaitFor-                              */
/*                                                                          */
/*                Dieses Programm ermöglicht das Warten auf                 */
/*                                                                          */
/*   - Das Erscheinen eines Fensters    (Option <WINDOW>)                   */
/*   - Das Erscheinen eines Screens     (Option <SCREEN>)                   */
/*   - Das Erscheinen eines Tasks       (Option <TASK>)                     */
/*   - Das Verschwinden eines Fensters  (Option <ENDWINDOW>)                */
/*   - Das Verschwinden eines Screens   (Option <ENDSCREEN>)                */
/*   - Das Verschwinden eines Tasks     (Option <ENDTASK>)                  */
/*   - Das Drücken einer Maustaste      (Option <LMB, MMB, RMB>)            */
/*                                                                          */
/*                                                                          */
/*    Compilieren : CC NewPrefs.c -md -so                                   */
/*    Linken      : LN NewPrefs.o -lcl  (AztecC V5.2)                       */
/*                                                                            */

/* Include Files */

#include <Intuition/IntuitionBase.h>
#include <Exec/ExecBase.h>
#include <Exec/Tasks.h>
#include <Libraries/DosExtens.h>
#include <Libraries/DOS.h>
#include <Hardware/CIA.h>


/* Globale Variablen */

struct IntuitionBase		*IntuitionBase ;
struct Screen				*screen ;
extern struct ExecBase		*SysBase ;
extern struct CIA			ciaa ;
extern struct Custom		custom ;


int main(int argc, char *argv[])
{
	if (!(IntuitionBase = (struct IntuitionBase *)	/* intuition.library */
	OpenLibrary ("intuition.library", 0L)))			/* öffnen */
		exitall (10) ;

	if (argc==2)
	{

		if (!(stricmp(argv[1], "LMB")))
		{
			while (ciaa.ciapra&(1<<CIAB_GAMEPORT0))
				Delay (5) ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "RMB")))
		{
			while (custom.potinp&(1<<10))
				Delay (5) ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "MMB")))
		{
			while (custom.potinp&(1<<8))
				Delay (5) ;
			exitall (0) ;
		}
	}
	else
	if (argc==3)
	{
		if (!(stricmp(argv[1], "TASK")))
		{
			FOREVER
			{
				/* Task in TaskWait und TaskReady-Liste suchen */

				Disable () ;
				if (findtask ((struct Task *) SysBase->TaskWait.lh_Head, argv[2]))
					break ;
				else
				if (findtask ((struct Task *) SysBase->TaskReady.lh_Head, argv[2]))
					break ;
				Enable () ;
				Delay (10) ;
			}
			Enable () ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "ENDTASK")))
		{
			/* Ist Task überhaupt vorhanden ? */

			FOREVER
			{
				/* Task in TaskWait und TaskReady-Liste suchen */

				Disable () ;
				if (findtask ((struct Task *) SysBase->TaskWait.lh_Head, argv[2]))
					break ;
				else
				if (findtask ((struct Task *) SysBase->TaskReady.lh_Head, argv[2]))
					break ;
				Enable () ;
				exitall (5) ;
			}

			/* Wenn ja, auf Ende des Tasks warten */

			FOREVER
			{
				/* Task in TaskWait und TaskReady-Liste suchen */

				Disable () ;
				if (!(findtask ((struct Task *) SysBase->TaskWait.lh_Head, argv[2])))
					if (!(findtask ((struct Task *) SysBase->TaskReady.lh_Head, argv[2])))
						break ;
				Enable () ;
				Delay (10) ;
			}
			Enable () ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "SCREEN")))
		{
			/* Screen suchen */

			FOREVER
			{
				Forbid () ;
				if (findscreen (IntuitionBase->FirstScreen, argv[2]))
					break ;
				Permit () ;
				Delay (10) ;
			}
			Permit () ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "ENDSCREEN")))
		{
			/* ist Screen überhaupt vorhanden ? */

			Forbid () ;
			if (!(findscreen (IntuitionBase->FirstScreen, argv[2])))
			{
				Permit () ;
				exitall (5) ;
			}

			/* Wen ja, Auf Schließen des Screens warten */
			FOREVER
			{
				Forbid () ;
				if (!(findscreen (IntuitionBase->FirstScreen, argv[2])))
					break ;
				Permit () ;
				Delay (10) ;
			}
			Permit () ;
			exitall (0) ;
		}
		else
		if (!(stricmp(argv[1], "WINDOW")))
		{
			/* Window in allen Screens suchen */

			FOREVER
			{
				Forbid () ;
				screen = IntuitionBase->FirstScreen ;
				while (screen)
				{
					if (findwindow (screen, argv[2]))
					{
						Permit () ;
						exitall (0) ;
					}
					screen = screen->NextScreen ;
				}
				Permit () ;
				Delay (10) ;
			}
		}
		else
		if (!(stricmp(argv[1], "ENDWINDOW")))
		{
			/* Ist Window in irgendeinem Screens überhaupt vorhanden ? */

			Forbid () ;
			screen = IntuitionBase->FirstScreen ;
			FOREVER
			{
				if (findwindow (screen, argv[2]))
					break ;
				if (!(screen = screen->NextScreen))
				{
					Permit () ;
					exitall (5) ;
				}
			}

			/* Wenn ja, auf Schließen des Windows im entspr. Screen warten */

			while (findwindow (screen, argv[2]))
			{
				Permit () ;
				Delay (10) ;
				Forbid () ;
			}
			exitall (0) ;
		}
	}
	puts ("USAGE : WaitFor <LMB|MMB|RMB|SCREEN|ENDSCREEN|") ;
	puts ("                 WINDOW|ENDWINDOW|TASK|ENDTASK> <Name>") ;
	exitall (5) ;
}

findtask (struct Task *task, char *name)
{
	struct Process				*proc ;
	struct CommandLineInterface	*cli ;
	char 						*str ;

	while (task->tc_Node.ln_Succ)
	{
		/* printf ("Task : %s\n", task->tc_Node.ln_Name) ; */
		if (stricmp(name, task->tc_Node.ln_Name) == 0)
			return (TRUE) ;

		/* Falls CLI-Process, den Programmnamen aus CLI-Struktur holen */

		if (task->tc_Node.ln_Type == NT_PROCESS)
		{
			proc = (struct Process *) task ;
			if (proc->pr_TaskNum != 0)
			{
				/* dieser dämliche BCPL-Mist im Amiga-System ;-( */

				cli = (struct CommandLineInterface *) BADDR(proc->pr_CLI) ;
				str = (char *) BADDR(cli->cli_CommandName) ;
				/* printf ("Proc : %s\n", str+1) ; */
				if (*str)
				{
					if (strnicmp(name, str+1, *str) == 0)
						return (TRUE) ;
				}
			}
		}
		task = (struct Task *) task->tc_Node.ln_Succ ;
	}
	return (FALSE) ;
}

findscreen (struct Screen *scr, char *name)
{
	while (scr)
	{
		if (stricmp(name, scr->Title) == 0)
			return (TRUE) ;
		scr = scr->NextScreen ;
	}
	return (FALSE) ;
}

findwindow (struct Screen *scr, char *name)
{
	struct Window *win ;

	win = scr->FirstWindow ;
	while (win)
	{
		if (stricmp(name, win->Title) == 0)
			return (TRUE) ;
		win = win->NextWindow ;
	}
	return (FALSE) ;
}


exitall (int err)
{
	if (IntuitionBase)
		CloseLibrary (IntuitionBase) ;
	exit (err) ;
}
