/*************************************************************************
 ***                        req.c                        (JJB TEMPLAR) ***
 *** Date begun: 11/8/89.                                              ***
 *** Last modified: 28/8/89.                                           ***
 *************************************************************************/
/*** Requester for string/integer input.                               ***
 *************************************************************************/

#include <exec/types.h>
#include <intuition/intuition.h>

#include <proto/intuition.h>
#include <proto/exec.h>

#include <string.h>

extern struct Window    *Window;
extern int              has_resized;

extern void sprintf();

#define G_OKAY      50
#define G_CANCEL    51
#define G_STRING    52

UWORD   rb1_dat[10] = {0,0, 193,0, 193,53, 0,53, 0,0};  /* White */
UWORD   rb2_dat[10] = {2,1, 191,1, 191,52, 2,52, 2,1};  /* Red */
UWORD   rb3_dat[ 4] = {0,0, 178,0};                     /* Line */

struct Border r_bd[6] = {
    {7,13,1,2,JAM1,2,rb3_dat,NULL},
    {9,14,2,0,JAM1,2,rb3_dat,&r_bd[0]},
    {0, 0,3,3,JAM1,5,rb2_dat,&r_bd[1]},
    {1, 0,3,3,JAM1,5,rb2_dat,&r_bd[2]},
    {0, 0,1,2,JAM1,5,rb1_dat,&r_bd[3]},
    {1, 0,1,2,JAM1,5,rb1_dat,&r_bd[4]}};

struct IntuiText r_txt[4] = {
    {1,2,JAM1,55, 3,NULL,NULL,NULL},
    {2,0,JAM1,57, 4,NULL,NULL,&r_txt[0]},
    {1,2,JAM1,55,21,NULL,NULL,&r_txt[1]},
    {2,0,JAM1,57,22,NULL,NULL,&r_txt[2]}};
struct IntuiText g_txt[2] = {
    {1,2,JAM1,15,2,NULL,"OKAY",NULL},
    {3,3,JAM1, 8,2,NULL,"CANCEL",NULL}};

struct Image g_img[8] = {
    {2,1,60,10,0,NULL,0,0,NULL},        /* Grey box */
    {0,0,64,12,0,NULL,0,1,&g_img[0]},   /* White border */
    {2,1,64,12,0,NULL,0,2,&g_img[1]},   /* Black shadow */
    {0,0,64,12,0,NULL,0,3,&g_img[0]},   /* Red border */
    {2,1,64,12,0,NULL,0,2,&g_img[3]},   /* Black shadow */
    {-2,-1,164,10,0,NULL,0,0,NULL},         /* Black box */
    {-4,-2,168,12,0,NULL,0,1,&g_img[5]},    /* White border */
    {-2,-1,168,12,0,NULL,0,2,&g_img[6]}};   /* Black shadow */

UBYTE   s_buf[256],u_buf[256];
struct StringInfo g_inf = {s_buf,u_buf,0,255,};

struct Gadget r_gad[3] = {
    {NULL,13,36,64,12,GADGHCOMP|GADGIMAGE,RELVERIFY|ENDGADGET,
     BOOLGADGET|REQGADGET,(APTR)&g_img[2],NULL,&g_txt[0],NULL,NULL,G_OKAY,NULL},
    {&r_gad[0],117,36,64,12,GADGHCOMP|GADGIMAGE,RELVERIFY|ENDGADGET,
     BOOLGADGET|REQGADGET,(APTR)&g_img[4],NULL,&g_txt[1],NULL,NULL,G_CANCEL,NULL},
    {&r_gad[1],17,21,160,8,GADGHCOMP|GADGIMAGE,RELVERIFY|ENDGADGET,
     STRGADGET|REQGADGET,(APTR)&g_img[7],NULL,NULL,NULL,(APTR)&g_inf,G_STRING,NULL}};

struct Requester req = {
    NULL,200,75,195,54,0,0,&r_gad[2],&r_bd[5],&r_txt[1],0,0,};

static int  r_init(title,src,len,type) /*================================*/
char    *title,*src;
int     len,type;                  /* 1 = LONGINT, 0 = STRING */
{
register char   *cp;

    cp = s_buf + 84;
    while (cp-- > s_buf) *cp = 0;       /* Clear s_buf */

    r_txt[0].LeftEdge = 97 - (strlen(title) * 4);
    r_txt[1].LeftEdge = r_txt[0].LeftEdge + 2;
    r_txt[1].IText = r_txt[0].IText = title;

    r_gad[2].Activation = (type)? RELVERIFY|ENDGADGET|LONGINT: RELVERIFY|ENDGADGET;

    req.LeftEdge = (Window->Width / 2) - 97;
    req.TopEdge = (Window->Height / 2) - 27;
    req.ReqGadget = &r_gad[2];
    req.ReqText = &r_txt[1];

    strcpy(s_buf,src);
    g_inf.MaxChars = len;

    ModifyIDCMP(Window,Window->IDCMPFlags | REQSET);
    return(Request(&req,Window));
}

static int  r_loop() /*==================================================*/
{
struct IntuiMessage *msg;
int     loop = 1,x,y;
  /* To track NEWSIZE, since I can't get NEWSIZE messages during req. */
    x = Window->Width;      y = Window->Height;

    while (loop > 0) {
        Wait(1 << Window->UserPort->mp_SigBit);
        while (msg = (struct IntuiMessage *)GetMsg(Window->UserPort)) {
            if (msg->Class == GADGETUP) {
                switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
                    case (G_STRING):
                    case (G_OKAY):   loop = 0;  break;
                    case (G_CANCEL): loop = -1; break;
                }
            }
            else if (msg->Class == REQSET) {
                ModifyIDCMP(Window,Window->IDCMPFlags & ~REQSET);
                ActivateGadget(&r_gad[2],Window,&req);
            }
        ReplyMsg((struct Message *)msg);
	}
    }
    if ((x != Window->Width) || (y != Window->Height)) has_resized = 1;
    return(loop);
}

int     r_string(title,src,len) /*=======================================*/
char    *title,*src;
int     len;
{
    src[len-1] = 0;
    if (!r_init(title,src,len,0)) return(0);

    if ((r_loop() < 0) || !s_buf[0]) return(0);

    strcpy(src,s_buf);
    return(1);
}

int     r_int(title,src,len) /*==========================================*/
char    *title;
int     *src,len;
{
char    buf[10];
    sprintf(buf,"%d",*src);
    buf[len-1] = 0;    /* Caller was pretty stupid if this was necessary */
    if (!r_init(title,buf,len,1)) return(0);

    if ((r_loop() < 0) || !s_buf[0]) return(0);

    *src = g_inf.LongInt;
    return(1);
}

int     r_bool(cp) /*====================================================*/
char    *cp;
{
    r_txt[0].LeftEdge = 57;         r_txt[1].LeftEdge = 59;
    r_txt[1].IText = r_txt[0].IText = "Aye or Nay";

    r_txt[2].LeftEdge = 97 - (strlen(cp) * 4);
    r_txt[3].LeftEdge = r_txt[2].LeftEdge + 2;
    r_txt[3].IText = r_txt[2].IText = cp;

    req.LeftEdge = (Window->Width / 2) - 97;
    req.TopEdge = (Window->Height / 2) - 27;
    req.ReqGadget = &r_gad[1];
    req.ReqText = &r_txt[3];

    if (Request(&req,Window)) return(r_loop() + 1);
    return(0);          /* Fail if couldn't set requester up. */
}
