/************************************************************************/
/*                                                                      */
/* This file contains code for the Edit_Config command.			*/
/*                                                                      */
/************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "general.h"
#include "globals.h"
#include "intui.h"
#include "spl_gfx.h"
#include "config.h"


/* Get Stringinfo buffer for the string gadget with id 'G':	*/
#define Get_Gadget_String(G) (((struct StringInfo *) \
				(ConfigGadgets[G]->SpecialInfo))->Buffer)

	/* Set string to 'S' in string gadget 'G':	*/
#define Set_Gadget_String(G, S) \
		GT_SetGadgetAttrs(ConfigGadgets[G], \
			Windows[W_Config].Window, NULL, \
			GTST_String, S)

/* Get Stringinfo LongInt for the integer gadget with id 'G':	*/
#define Get_Gadget_Int(G) (((struct StringInfo *) \
				(ConfigGadgets[G]->SpecialInfo))->LongInt)

	/* Set number to 'N' in integer gadget 'G':	*/
#define Set_Gadget_Int(G, N) \
		GT_SetGadgetAttrs(ConfigGadgets[G], \
			Windows[W_Config].Window, NULL, \
			GTIN_Number, N)

	/* Set check state to  to 'On_Off' in check gadget 'G':	*/
#define Set_Gadget_State(G, On_Off) \
		GT_SetGadgetAttrs(ConfigGadgets[G], \
			Windows[W_Config].Window, NULL, \
			GTCB_Checked, (BOOL) (On_Off))

	/* Get gadget state for check gadget 'G':	*/
#define Get_Gadget_State(G) \
		(ConfigGadgets[G]->Flags & GFLG_SELECTED)

void Config_Set_Values()
/************************************************************************/
/*                                                                      */
/* Set fields in screen from global variables.				*/
/*                                                                      */
/************************************************************************/
{
    char	Buffer[Buffer_Length+1];
    double	D1, D2, D3;

    D1 = Delay_Draw_Seconds;
    D2 = Delay_Draw_Micros;
    D3 = D1 + D2 / 1000000.0;

    sprintf(Buffer, "%.2lf", D3);
    Set_Gadget_String(GDX_Delay_Draw_Value, Buffer);

    Set_Gadget_Int(GDX_Spline_Resolution_Value, Spline_Resolution);
    Set_Gadget_Int(GDX_Patch_Resolution_Value, Patch_Resolution);

    sprintf(Buffer, "%.2lf", Grid_Size);
    Set_Gadget_String(GDX_Grid_Size_Value, Buffer);

    Set_Gadget_Int(GDX_MQ_Size_KnotInfo_Value, MQ_Size_KnotInfo);
    Set_Gadget_Int(GDX_MQ_Size_Rotate_P_Value, MQ_Size_Rotate_P);
    Set_Gadget_Int(GDX_MQ_Size_Rotate_G_Value, MQ_Size_Rotate_G);
    Set_Gadget_Int(GDX_MQ_Size_Scale_G_Value, MQ_Size_Scale_G);
    Set_Gadget_Int(GDX_MQ_Size_Move_G_Value, MQ_Size_Move_G);
    Set_Gadget_Int(GDX_MQ_Size_Move_Value, MQ_Size_Move);

} /* Config_Set_Values */

void Config_Get_Values()
/************************************************************************/
/*                                                                      */
/* Get configuration parameters from the window, and set the global	*/
/* variables accordingly.						*/
/*                                                                      */
/************************************************************************/
{
    char	Buffer[Buffer_Length+1];
    double	D1, D2, D3;

    D1 = Delay_Draw_Seconds;
    D2 = Delay_Draw_Micros;
    D3 = D1 + D2 / 1000000.0;

    D1 = atof(Get_Gadget_String(GDX_Delay_Draw_Value));
    if (D1 >  0.0) {
	D3 = modf(D1, &D2);
	Delay_Draw_Seconds = D2;
	Delay_Draw_Micros  = D3 * 1000000.0;
    }

    Spline_Resolution= Get_Gadget_Int(GDX_Spline_Resolution_Value);
    Patch_Resolution = Get_Gadget_Int(GDX_Patch_Resolution_Value);

    Grid_Size        = atof(Get_Gadget_String(GDX_Grid_Size_Value));
    MQ_Size_KnotInfo = Get_Gadget_Int(GDX_MQ_Size_KnotInfo_Value);
    MQ_Size_Rotate_P = Get_Gadget_Int(GDX_MQ_Size_Rotate_P_Value);
    MQ_Size_Rotate_G = Get_Gadget_Int(GDX_MQ_Size_Rotate_G_Value);
    MQ_Size_Scale_G  = Get_Gadget_Int(GDX_MQ_Size_Scale_G_Value);
    MQ_Size_Move_G   = Get_Gadget_Int(GDX_MQ_Size_Move_G_Value);
    MQ_Size_Move     = Get_Gadget_Int(GDX_MQ_Size_Move_Value);

} /* Config_Get_Values */

static
Boolean_T Config_Handle_Gadget_Event(struct IntuiMessage *Msg)
/************************************************************************/
/*                                                                      */
/* Dispatcher for gadget events.					*/
/*                                                                      */
/************************************************************************/
{
    char	Buffer[Buffer_Length+1];
    double	D;
    long	L;
    Boolean_T 	Config_Done;
    struct Gadget *Gad = (struct Gadget *) Msg->IAddress;
    

    Config_Done = FALSE;

    switch (Gad->GadgetID) {

    case GD_Delay_Draw_Value:
	D = atof(Get_Gadget_String(GDX_Delay_Draw_Value));
	if (D < 0.0) D = 1.0;
	sprintf(Buffer, "%.2lf", D);
	Set_Gadget_String(GDX_Delay_Draw_Value, Buffer);
	break;

    case GD_Spline_Resolution_Value:
	L = Get_Gadget_Int(GDX_Spline_Resolution_Value);
	if (L < 1 || L > Max_Spline_Resolution) L = 4;
	Set_Gadget_Int(GDX_Spline_Resolution_Value, L);
	break;

    case GD_Patch_Resolution_Value:
	L = Get_Gadget_Int(GDX_Patch_Resolution_Value);
	if (L < 1 || L > Max_Patch_Resolution) L = 4;
	Set_Gadget_Int(GDX_Patch_Resolution_Value, L);
	break;

    case GD_Grid_Size_Value:
	D = atof(Get_Gadget_String(GDX_Grid_Size_Value));
	if (D < 0.5 || D > 500.0) D = 40.0;
	sprintf(Buffer, "%.2lf", D);
	Set_Gadget_String(GDX_Grid_Size_Value, Buffer);
	break;

    case GD_MQ_Size_KnotInfo_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_KnotInfo_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_KnotInfo_Value, L);
	break;

    case GD_MQ_Size_Rotate_P_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_Rotate_P_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_Rotate_P_Value, L);
	break;

    case GD_MQ_Size_Rotate_G_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_Rotate_G_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_Rotate_G_Value, L);
	break;

    case GD_MQ_Size_Scale_G_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_Scale_G_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_Scale_G_Value, L);
	break;

    case GD_MQ_Size_Move_G_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_Move_G_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_Move_G_Value, L);
	break;

    case GD_MQ_Size_Move_Value:
	L = Get_Gadget_Int(GDX_MQ_Size_Move_Value);
	if (L < 0 || L > 5) L = 2;
	Set_Gadget_Int(GDX_MQ_Size_Move_Value, L);
	break;

    case GD_Config_Ok:
	Config_Get_Values();
	Config_Done = TRUE;
	break;

    case GD_Config_Cancel:
	Config_Done = TRUE;
	break;

    } /* switch */

    return(Config_Done);

} /* Handle_Gadget_Event */

static
Boolean_T Config_Check_Event()
/************************************************************************/
/*                                                                      */
/* Check for an event and handle it.					*/
/*                                                                      */
/************************************************************************/
{
    struct 		IntuiMessage *Msg_Ptr;
    struct 		IntuiMessage Msg;
    struct 		Gadget *Gad;
    Boolean_T		Config_Done;

    Config_Done = FALSE;

    WaitPort(User_Port);

    while ((Msg_Ptr = GT_GetIMsg(User_Port)) != NULL) {

	Msg = *Msg_Ptr;
	
        GT_ReplyIMsg(Msg_Ptr);

        switch (Msg.Class) {

	case IDCMP_REFRESHWINDOW:
	    GT_BeginRefresh(Msg.IDCMPWindow);
	    if (Msg.IDCMPWindow == Windows[W_Config].Window) ConfigRender();
	    GT_EndRefresh(Msg.IDCMPWindow, TRUE);
	    break;

	case IDCMP_GADGETUP:
	case IDCMP_GADGETDOWN:
	    Config_Done = Config_Handle_Gadget_Event(&Msg);
	    break;

	} /* switch */

    } /* while */

    return(Config_Done);

} /* Config_Check_Event */

void Edit_Configuration()
/************************************************************************/
/*                                                                      */
/* Edit configuration of the program.					*/
/*                                                                      */
/************************************************************************/
{
    if (Windows[(int)W_Config].Window == NULL) Window_Open(W_Config);
    WindowToFront(Windows[W_Config].Window);

    Config_Set_Values();

    while (!Config_Check_Event()) ;

    Window_Close(W_Config);

    Compute_Splines();
    Redraw_Mask |= What_All;


} /* Edit_Configuration */
