/*
 *  FM_CoordReq_React.c
 *
 *  Requester for coordinates-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/string.h>
#include <gadgets/checkbox.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_CoordReq_React.h"
#include "FM_ReactionBasics.h"
#include "FM_Reaction.h"
#include "FM_ReactionCD.h"

extern ULONG *PALETTE;

typedef long double LDouble;

/* prototypes */
void SaveCoords(struct Window *, BOOL);
void AdjustRatio(LDouble *, LDouble *, LDouble *, LDouble *, WORD, WORD, BOOL);

struct ReactWinData *coord_rwd = NULL;

/* Data */
LDouble Tmp_RMIN, Tmp_IMAX, Tmp_RMAX, Tmp_IMIN, Tmp_JKRE, Tmp_JKIM;

extern LDouble RMIN, RMAX, IMIN, IMAX;
extern LDouble JKRE, JKIM;
extern LDouble DEF_RMIN, DEF_RMAX, DEF_IMIN, DEF_IMAX;
extern LDouble DEF_JKRE, DEF_JKIM;
extern LDouble URMIN, URMAX, UIMIN, UIMAX, UJKRE, UJKIM;

/*  Do_CoordinatesRequest(): coordinates-requester (full handling).

        SYNOPSIS: BOOL res = Do_CoordinatesRequest
                        (
                        struct Window     *Win;
                        char                  *PubScreenName;
                        WORD                    Left;
                        WORD                    Top;
                        );

        INPUTS:     Win:
                            Pointer to the parent-window.

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

                        Left:
                            Left edge of palette-window (not supported yet).

                        Top:
                            Top edge of palette-window (not supported yet).

        RETURNS:        res:
                            Is TRUE, if changes are accepted.
*/

BOOL Do_CoordinatesRequest(struct Window *Win, char *PubScreenName, WORD Left, WORD Top)
{
BOOL rc = FALSE;
LONG result = RESULT_NOTHING;
BOOL KeepReal = TRUE;
ULONG waitsigs, mask;

Tmp_RMIN = RMIN; Tmp_IMAX = IMAX; Tmp_RMAX = RMAX; Tmp_IMIN = IMIN;

if (OpenCoordReqWindow(PubScreenName, &KeepReal) == TRUE) {
    waitsigs = coord_rwd->RWD_WSignals|SIGBREAKF_CTRL_C;

    while(result == RESULT_NOTHING) {
        mask = Wait(waitsigs);
#ifndef NDEBUG
        printf("mask: %lX\n", mask);
#endif /*NDEBUG*/
        if (mask & coord_rwd->RWD_WSignals) {
            result = HandleCoordReqWindow(Win, &KeepReal);
            }
        if (mask & SIGBREAKF_CTRL_C) {
            result = RESULT_CANCEL;
            }
        if (result == RESULT_OK) rc = TRUE;
        }

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

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

/*  OpenCoordReqWindow(): open window of coordinates-requester.

        SYNOPSIS: BOOL res = OpenCoordReqWindow
                        (
                        char  *PubScreenName;
                        BOOL    *KeepReal;
                        );

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

                        KeepReal:
                            Is TRUE, if to keep the x-axis.

        RETURNS:        res:
                            TRUE, if successfull.
*/

BOOL OpenCoordReqWindow(char *PubScreenName, BOOL *KeepReal)
{
TEXT String [MAXCHARS];

if (coord_rwd = OpenReactionWindow(WIN_COORD_ID, GROUP_Coord_ID, PubScreenName)) {
    sprintf (String, "%+2.16f", IMAX);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Top], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    sprintf (String, "%+2.16f", RMIN);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Left], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    sprintf (String, "%+2.16f", RMAX);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Right], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    sprintf (String, "%+2.16f", IMIN);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Bottom], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    sprintf (String, "%+2.16f", JKRE);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaReal], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    sprintf (String, "%+2.16f", JKIM);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaImag], coord_rwd->RWD_IWindow, NULL,
                        STRINGA_TextVal, &String, TAG_DONE);
    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_CHECKBOX_KeepAxis], coord_rwd->RWD_IWindow, NULL,
                        CHECKBOX_Checked, *KeepReal, TAG_DONE);
    return(TRUE);
    }
return(FALSE);
}

/*  CloseCoordReqWindow(): close window of coordinates-requester.

        SYNOPSIS: void = CloseCoordReqWindow
                        (
                        void
                        );

        INPUTS:     -

        RETURNS:        -
*/

void CloseCoordReqWindow(void)
{
CloseReactionWindow(coord_rwd);
}

/*  HandleCoordReqWindow(): Handle the messages of the coordinates-requester.

        SYNOPSIS: LONG res = HandlePalettePrefWindow
                        (
                        struct Window   *Win;
                        );

        INPUTS:     Win:
                            Pointer to a window-structure.

                        KeepReal:
                            .

        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 HandleCoordReqWindow(struct Window *Win, BOOL *KeepReal)
{
LONG rc = RESULT_NOTHING;
ULONG result, code;
TEXT String [MAXCHARS];

while((result = DoMethod(coord_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 Coord_STRING_Top:
                    ;
                    break;
                case Coord_STRING_Left:
                    ;
                    break;
                case Coord_STRING_Right:
                    ;
                    break;
                case Coord_STRING_Bottom:
                    ;
                    break;
                case Coord_STRING_JuliaReal:
                    ;
                    break;
                case Coord_STRING_JuliaImag:
                    ;
                    break;
                case Coord_CHECKBOX_KeepAxis:
                    *KeepReal = !(*KeepReal);
                    break;
                case Coord_BUTTON_Accept:
                    {
                    const char *str = NULL;
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Top], (ULONG *) &str);
                    Tmp_IMAX = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Left], (ULONG *) &str);
                    Tmp_RMIN = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Right], (ULONG *) &str);
                    Tmp_RMAX = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Bottom], (ULONG *) &str);
                    Tmp_IMIN = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaReal], (ULONG *) &str);
                    Tmp_JKRE = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaImag], (ULONG *) &str);
                    Tmp_JKIM = strtod (str, NULL);

                    if ((Tmp_RMIN >= Tmp_RMAX) || (Tmp_IMIN >= Tmp_IMAX)) DisplayBeep(Win->WScreen);
                    else {
                        SaveCoords (Win, FALSE);
                        RMIN = Tmp_RMIN; IMAX = Tmp_IMAX; RMAX = Tmp_RMAX; IMIN = Tmp_IMIN;
                        JKRE = Tmp_JKRE; JKIM = Tmp_JKIM;
                        rc = RESULT_OK;
                        }
                    }
                    break;
                
             case Coord_BUTTON_Ratio:
                  {
                    const char *str = NULL;
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Top], (ULONG *) &str);
                    Tmp_IMAX = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Left], (ULONG *) &str);
                    Tmp_RMIN = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Right], (ULONG *) &str);
                    Tmp_RMAX = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_Bottom], (ULONG *) &str);
                    Tmp_IMIN = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaReal], (ULONG *) &str);
                    Tmp_JKRE = strtod (str, NULL);
                    GetAttr(STRINGA_TextVal, coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaImag], (ULONG *) &str);
                    Tmp_JKIM = strtod (str, NULL);

                    if ((Tmp_RMIN >= Tmp_RMAX) || (Tmp_IMIN >= Tmp_IMAX)) DisplayBeep(Win->WScreen);
                    else  AdjustRatio ((LDouble *) &Tmp_RMIN, (LDouble *) &Tmp_IMAX, (LDouble *) &Tmp_RMAX, (LDouble *) &Tmp_IMIN, Win->Width, Win->Height, *KeepReal);

                    sprintf (String, "%+2.16f", Tmp_IMAX);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Top], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", Tmp_RMIN);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Left], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", Tmp_RMAX);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Right], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", Tmp_IMIN);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Bottom], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                  }
                    break;

                case Coord_BUTTON_Default:
                    sprintf (String, "%+2.16f", DEF_IMAX);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Top], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", DEF_RMIN);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Left], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", DEF_RMAX);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Right], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", DEF_IMIN);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_Bottom], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", DEF_JKRE);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaReal], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    sprintf (String, "%+2.16f", DEF_JKIM);
                    SetGadgetAttrs(coord_rwd->RWD_GadgetArray[Coord_STRING_JuliaImag], coord_rwd->RWD_IWindow, NULL,
                                        STRINGA_TextVal, &String, TAG_DONE);
                    break;
                case Coord_BUTTON_Cancel:
                    rc = RESULT_CANCEL;
                    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(coord_rwd->RWD_WindowObject, WM_ICONIFY);
            GetAttr(WINDOW_Window, coord_rwd->RWD_WindowObject, (ULONG *) &coord_rwd->RWD_IWindow);
            break;

        case WMHI_UNICONIFY:
            DoMethod(coord_rwd->RWD_WindowObject, WM_OPEN);
            GetAttr(WINDOW_Window, coord_rwd->RWD_WindowObject, (ULONG *) &coord_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);
}
