/*
 *  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);
}
