/*
 *  FM_IntegerReq_React.c
 *
 *  Requester for cycledelay-request and iterations-request with reaction-support
 *  $VER: V2.0, 13.10.2001
 *  Coded by Edgar Schwan
 */

#include <intuition/gadgetclass.h>
#include <intuition/classusr.h>
#include <intuition/screens.h>
#include <classes/window.h>
#include <dos/dos.h>
#include <gadgets/integer.h>

#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>

#include <pragmas/intuition_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/graphics_pragmas.h>

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

#include "FM_IntegerReq_React.h"
#include "FM_ReactionBasics.h"
#include "FM_Reaction.h"
#include "FM_ReactionCD.h"

extern ULONG *PALETTE;

struct ReactWinData *cycle_rwd = NULL;
struct ReactWinData *iterat_rwd = NULL;

/*	Do_CycleDelayRequest(): cycledelay-requester (full handling).

		SYNOPSIS: ULONG NewValue = Do_CycleDelayRequest
						(
						struct Window	  *Win;
						char				  *PubScreenName;
						WORD 					Left;
						WORD					Top;
						ULONG					Value;
						);

		INPUTS:		Win:
							Pointer to the parent-window.

						PubScreenName:
							name of the public-screen, where the window should appear.

						Left:
							Left edge of palette-window.

						Top:
							Top edge of palette-window.

						Value:
							Actual value for delay-time.

		RETURNS:		NewValue:
							New value for delay-time.
*/

ULONG Do_CycleDelayRequest(struct Window *Win, char *PubScreenName, WORD Left, WORD Top, ULONG Value)
{
LONG result = RESULT_NOTHING;
ULONG waitsigs, mask;
ULONG NewValue = Value;

if (OpenCycleReqWindow(PubScreenName, Value) == TRUE) {

	waitsigs = cycle_rwd->RWD_WSignals|SIGBREAKF_CTRL_C;

	while(result == RESULT_NOTHING) {
		mask = Wait(waitsigs);
#ifndef NDEBUG
		printf("mask: %lX\n", mask);
#endif /*NDEBUG*/
		if (mask & cycle_rwd->RWD_WSignals) {
			result = HandleCycleReqWindow(Win, &NewValue);
			if (result == RESULT_CANCEL) NewValue = Value;
			}
		if (mask & SIGBREAKF_CTRL_C) {
			NewValue = Value;
			result = RESULT_CANCEL;
			}
		}

	CloseCycleReqWindow();
	} else DisplayError(Win, TXT_ERR_Window, 5L);

LoadRGB32(ViewPortAddress (Win), (APTR) PALETTE);
return(NewValue);
}

/*	OpenCycleReqWindow(): open window of cycle-requester.

		SYNOPSIS: BOOL res = OpenCycleReqWindow
						(
						char	  *PubScreenName;
						ULONG		Value;
						);

		INPUTS:		PubScreenName:
							name of the public-screen, where the window should appear.

						Value:
							Value for Integer-Gadget.

		RETURNS:		res:
							TRUE, if successfull.
*/

BOOL OpenCycleReqWindow(char *PubScreenName, ULONG Value)
{
if (cycle_rwd = OpenReactionWindow(WIN_CYC_ID, GROUP_Cyc_ID, PubScreenName)) {
	SetGadgetAttrs(cycle_rwd->RWD_GadgetArray[Cyc_INTEGER_DelayTime], cycle_rwd->RWD_IWindow, NULL,
						INTEGER_Number, Value, TAG_DONE);
	return(TRUE);
	}
return(FALSE);
}

/*	CloseCycleReqWindow(): close window of cycle-requester.

		SYNOPSIS: void = CloseCycleReqWindow
						(
						void
						);

		INPUTS:		-

		RETURNS:		-
*/

void CloseCycleReqWindow(void)
{
CloseReactionWindow(cycle_rwd);
}

/*	HandleCycleReqWindow(): Handle the messages of the cycle-requester.

		SYNOPSIS: LONG = HandleCycleReqWindow
						(
						struct Window	*Win;
						ULONG				*NewValue
						);

		INPUTS:		Win:
							Pointer to a window-structure.

						NewValue:
							Pointer to a var to store the new value.

		RETURNS:		res:
							result of messages:	RESULT_NOTHING -> nothing happens.
														RESULT_CANCEL  -> user wants to quit without a change.
														RESULT_OK      -> accept changes and quit.
*/

LONG HandleCycleReqWindow(struct Window *Win, ULONG *NewValue)
{
LONG rc = RESULT_NOTHING;
ULONG result, code;

while((result = DoMethod(cycle_rwd->RWD_WindowObject, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG) {

#ifndef NDEBUG
	printf("result: %ld\n", result);
#endif /*NDEBUG*/

	switch (result & WMHI_CLASSMASK) {
		case WMHI_CLOSEWINDOW:
			rc = RESULT_CANCEL;
			break;

		case WMHI_GADGETUP:
			switch (result & RL_GADGETMASK) {
				case Cyc_BUTTON_Accept:
					rc = RESULT_OK;
					break;
				case Cyc_BUTTON_Cancel:
					rc = RESULT_CANCEL;
					break;
				case Cyc_INTEGER_DelayTime:
					GetAttr(INTEGER_Number, cycle_rwd->RWD_GadgetArray[Cyc_INTEGER_DelayTime], NewValue);
					break;
#ifndef NDEBUG
				default:
					printf("unknown result: %lX\nunknown gadget: %lX\n", result, result & WMHI_GADGETMASK);
					DisplayBeep(NULL);
					break;
#endif /*NDEBUG*/
				}
			break;

		case WMHI_ICONIFY:
			DoMethod(cycle_rwd->RWD_WindowObject, WM_ICONIFY);
			GetAttr(WINDOW_Window, cycle_rwd->RWD_WindowObject, (ULONG *) &cycle_rwd->RWD_IWindow);
			break;

		case WMHI_UNICONIFY:
			DoMethod(cycle_rwd->RWD_WindowObject, WM_OPEN);
			GetAttr(WINDOW_Window, cycle_rwd->RWD_WindowObject, (ULONG *) &cycle_rwd->RWD_IWindow);
			break;
#ifndef NDEBUG
		default:
			printf("unknown result: %lX\nunknown class: %lX\n", result, result & WMHI_CLASSMASK);
			DisplayBeep(NULL);
			break;
#endif /*NDEBUG*/
		}
	}
return(rc);
}

/*	Do_IterationsRequest(): iteration-requester (full handling).

		SYNOPSIS: ULONG NewValue = Do_IterationsRequest
						(
						struct Window	  *Win;
						char				  *PubScreenName;
						WORD 					Left;
						WORD					Top;
						ULONG					Value;
						);

		INPUTS:		Win:
							Pointer to the parent-window.

						PubScreenName:
							name of the public-screen, where the window should appear.

						Left:
							Left edge of palette-window.

						Top:
							Top edge of palette-window.

						Value:
							Actual value for delay-time.

		RETURNS:		NewValue:
							New value for delay-time.
*/

ULONG Do_IterationsRequest(struct Window *Win, char *PubScreenName, WORD Left, WORD Top, ULONG Value)
{
LONG result = RESULT_NOTHING;
ULONG waitsigs, mask;
ULONG NewValue = Value;

if (OpenIteratReqWindow(PubScreenName, Value) == TRUE) {

	waitsigs = iterat_rwd->RWD_WSignals|SIGBREAKF_CTRL_C;

	while(result == RESULT_NOTHING) {
		mask = Wait(waitsigs);
#ifndef NDEBUG
		printf("mask: %lX\n", mask);
#endif /*NDEBUG*/
		if (mask & iterat_rwd->RWD_WSignals) {
			result = HandleIteratReqWindow(Win, &NewValue);
			if (result == RESULT_CANCEL) NewValue = Value;
			}
		if (mask & SIGBREAKF_CTRL_C) {
			NewValue = Value;
			result = RESULT_CANCEL;
			}
		}

	CloseIteratReqWindow();
	} else DisplayError(Win, TXT_ERR_Window, 5L);

LoadRGB32(ViewPortAddress (Win), (APTR) PALETTE);
return(NewValue);
}

/*	OpenIteratReqWindow(): open window of iteration-requester.

		SYNOPSIS: BOOL res = OpenIteratReqWindow
						(
						char	  *PubScreenName;
						ULONG		Value;
						);

		INPUTS:		PubScreenName:
							name of the public-screen, where the window should appear.

						Value:
							Value for integer-gadget.

		RETURNS:		res:
							TRUE, if successfull.
*/

BOOL OpenIteratReqWindow(char *PubScreenName, ULONG Value)
{
if (iterat_rwd = OpenReactionWindow(WIN_IT_ID, GROUP_It_ID, PubScreenName)) {
	SetGadgetAttrs(iterat_rwd->RWD_GadgetArray[It_INTEGER_Iterations], iterat_rwd->RWD_IWindow, NULL,
						INTEGER_Number, Value, TAG_DONE);
	return(TRUE);
	}
return(FALSE);
}

/*	CloseIteratReqWindow(): close window of iteration-requester.

		SYNOPSIS: void = CloseIteratReqWindow
						(
						void
						);

		INPUTS:		-

		RETURNS:		-
*/

void CloseIteratReqWindow(void)
{
CloseReactionWindow(iterat_rwd);
}

/*	HandleIteratReqWindow(): Handle the messages of the iteration-requester.

		SYNOPSIS: LONG = HandleIteratReqWindow
						(
						struct Window	*Win;
						ULONG				*NewValue
						);

		INPUTS:		Win:
							Pointer to a window-structure.

						NewValue:
							Pointer to a var to store the new value.

		RETURNS:		res:
							result of messages:	RESULT_NOTHING -> nothing happens.
														RESULT_CANCEL  -> user wants to quit without a change.
														RESULT_OK      -> accept changes and quit.
*/

LONG HandleIteratReqWindow(struct Window *Win, ULONG *NewValue)
{
LONG rc = RESULT_NOTHING;
ULONG result, code;

while((result = DoMethod(iterat_rwd->RWD_WindowObject, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG) {

#ifndef NDEBUG
	printf("result: %ld\n", result);
#endif /*NDEBUG*/

	switch (result & WMHI_CLASSMASK) {
		case WMHI_CLOSEWINDOW:
			rc = RESULT_CANCEL;
			break;

		case WMHI_GADGETUP:
			switch (result & RL_GADGETMASK) {
				case It_BUTTON_Accept:
					rc = RESULT_OK;
					break;
				case It_BUTTON_Cancel:
					rc = RESULT_CANCEL;
					break;
				case It_INTEGER_Iterations:
					GetAttr(INTEGER_Number, iterat_rwd->RWD_GadgetArray[It_INTEGER_Iterations], NewValue);
					break;
#ifndef NDEBUG
				default:
					printf("unknown result: %lX\nunknown gadget: %lX\n", result, result & WMHI_GADGETMASK);
					DisplayBeep(NULL);
					break;
#endif /*NDEBUG*/
				}
			break;

		case WMHI_ICONIFY:
			DoMethod(iterat_rwd->RWD_WindowObject, WM_ICONIFY);
			GetAttr(WINDOW_Window, iterat_rwd->RWD_WindowObject, (ULONG *) &iterat_rwd->RWD_IWindow);
			break;

		case WMHI_UNICONIFY:
			DoMethod(iterat_rwd->RWD_WindowObject, WM_OPEN);
			GetAttr(WINDOW_Window, iterat_rwd->RWD_WindowObject, (ULONG *) &iterat_rwd->RWD_IWindow);
			break;
#ifndef NDEBUG
		default:
			printf("unknown result: %lX\nunknown class: %lX\n", result, result & WMHI_CLASSMASK);
			DisplayBeep(NULL);
			break;
#endif /*NDEBUG*/
		}
	}
return(rc);
}
