#include "ezlib.h"

/* this file contains a function called getstring() which will prompt
 * a user for a string, and the return it to you if they clicked o.k.
 * or hit return in the string gadget
 */

/*    Yes, if you haven't already noticed, some of these structures were
 * generated by PowerWindows.  Also note that I had to mess around with
 * the generated code a fair amount before it worked properly.
 *
 *    One other thing.	The reason these structures are declared global
 * and then copied in down below is so that the routine will be completely
 * re-entrant and won't modify any static data on multiple calls through
 * the same code!  This comes in handy when you have several children
 * tasks using this code.
 */
void *AllocMem();

struct StringInfo ez_string_gadget_SInfo = {
	NULL,  /* buffer where text will be edited - FILLED IN LATER*/
	NULL,	/* optional undo buffer */
	0,	/* character position in buffer */
	255,	/* maximum number of characters to allow */
	0,	/* first displayed character buffer position */
	0,0,0,0,0,	/* Intuition initialized and maintained variables */
	0,	/* Rastport of gadget */
	0,	/* initial value for integer gadgets */
	NULL	/* alternate keymap (fill in if you set the flag) */
};

SHORT ez_BorderVectors1[] = {
	0,0,
	292,0,
	292,11,
	0,11,
	0,0
};
struct Border ez_Border1 = {
	-2,-2,	/* XY origin relative to container TopLeft */
	3,0,JAM1,	/* front pen, back pen and drawmode */
	5,	/* number of XY vectors */
	ez_BorderVectors1,    /* pointer to XY vectors */
	NULL	/* next border in list */
};

struct Gadget ez_string_gadget_global = {
	NULL,	/* next gadget */
	13,18,	/* origin XY of hit box relative to window TopLeft */
	291,10, /* hit box width and height */
	NULL,	/* gadget flags */
	SELECTED+RELVERIFY,   /* activation flags */
	STRGADGET,	/* gadget type flags */
	(APTR)&ez_Border1,    /* gadget border or image to be rendered */
	NULL,	/* alternate imagery for selection */
	NULL,	/* first IntuiText structure */
	NULL,	/* gadget mutual-exclude long word */
	NULL,	 /* SpecialInfo structure */
	NULL,	/* user-definable data */
	NULL	/* pointer to user-definable data */
};

SHORT ez_BorderVectors2[] = {
	0,0,
	75,0,
	75,11,
	0,11,
	0,0
};
struct Border ez_Border2 = {
	-1,-1,	/* XY origin relative to container TopLeft */
	3,0,JAM1,	/* front pen, back pen and drawmode */
	5,	/* number of XY vectors */
	ez_BorderVectors2,    /* pointer to XY vectors */
	NULL	/* next border in list */
};

struct IntuiText ez_IText = {
	3,0,JAM1,	/* front and back text pens, drawmode and fill byte */
	10,1,	/* XY origin relative to container TopLeft */
	NULL,	/* font pointer or NULL for default */
	(UBYTE *)"  OK ",      /* pointer to text */
	NULL	/* next IntuiText structure */
};

struct Gadget ez_ok_gadget_global = {
	NULL,	 /* next gadget */
	230,40, /* origin XY of hit box relative to window TopLeft */
	74,10,	/* hit box width and height */
	NULL,	/* gadget flags */
	RELVERIFY,	/* activation flags */
	BOOLGADGET,	/* gadget type flags */
	(APTR)&ez_Border2,    /* gadget border or image to be rendered */
	NULL,	/* alternate imagery for selection */
	&ez_IText,   /* first IntuiText structure */
	NULL,	/* gadget mutual-exclude long word */
	NULL,	/* SpecialInfo structure */
	NULL,	/* user-definable data */
	NULL	/* pointer to user-definable data */
};

struct IntuiText ez_IText2 = {
	3,0,JAM1,	/* front and back text pens, drawmode and fill byte */
	10,1,	/* XY origin relative to container TopLeft */
	NULL,	/* font pointer or NULL for default */
	(UBYTE *)"Cancel",      /* pointer to text */
	NULL	/* next IntuiText structure */
};

struct Gadget ez_cancel_gadget_global = {
	NULL,	 /* next gadget - filled in below */
	10,40,	/* origin XY of hit box relative to window TopLeft */
	74,10,	/* hit box width and height */
	NULL,	/* gadget flags */
	RELVERIFY,	/* activation flags */
	BOOLGADGET,	/* gadget type flags */
	(APTR)&ez_Border2,    /* gadget border or image to be rendered */
	NULL,	/* alternate imagery for selection */
	&ez_IText2,   /* first IntuiText structure */
	NULL,	/* gadget mutual-exclude long word */
	NULL,	/* SpecialInfo structure */
	NULL,	/* user-definable data */
	NULL	/* pointer to user-definable data */
};


/* some defines for our gadget id's for this window... */
#define CANCEL_GADG 351
#define SEARCH_GADG 352
#define STRING_GADG 353


char *getstring(screen, title, def_string)
 struct Screen *screen;
 UBYTE *title;
 char *def_string;
{
 char buff[255], *string = NULL;
 struct Window *win, *OpenWindow();
 struct IntuiMessage *msg, *GetMsg();
 struct Gadget *gadg, string_gadget, search_gadget, cancel_gadget;
 struct StringInfo string_gadgetSInfo;
 USHORT len;
 LONG go_on = TRUE;
 ULONG	idcmp = GADGETUP+CLOSEWINDOW+ACTIVEWINDOW,   /* IDCMP flags */
	flags = WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH+WINDOWACTIVE;

 if (def_string != NULL)
  strcpy(buff, def_string);
 else
  buff[0] = 0;

 /* this part uses the structure assignment feature of Manx which I
  * believe is part of ANSI C, so this should be o.k.
  */
 cancel_gadget = ez_cancel_gadget_global;
 search_gadget = ez_ok_gadget_global;
 string_gadget = ez_string_gadget_global;

 string_gadgetSInfo = ez_string_gadget_SInfo;
 string_gadget.SpecialInfo = (APTR) &string_gadgetSInfo;

 cancel_gadget.NextGadget = &search_gadget;
 search_gadget.NextGadget = &string_gadget;

 cancel_gadget.GadgetID = CANCEL_GADG;
 search_gadget.GadgetID = SEARCH_GADG;
 string_gadget.GadgetID = STRING_GADG;
 string_gadgetSInfo.Buffer = (UBYTE *)buff;

 win = createwindow(screen, flags, idcmp, 148, 46, 316, 55);
 if ( win == NULL)
   { return NULL; }

 /* put the window title in */
 SetWindowTitles(win, title, -1L);

 /* add the gadgets to the window and make them appear */
 AddGList(win, &cancel_gadget, 1, 3, NULL);
 RefreshGadgets(&cancel_gadget, win, NULL);

 while (go_on)
  {
   Wait(1L << win->UserPort->mp_SigBit);

   while( go_on && (msg = GetMsg(win->UserPort)) )
    {
     switch(msg->Class)
      {
	case GADGETUP : gadg = (struct Gadget *)msg->IAddress;
			switch( gadg->GadgetID )
			 {
			   case CANCEL_GADG : go_on = FALSE;
					      break;

			   case SEARCH_GADG : /* fall through here...  */

			   case STRING_GADG : go_on = FALSE;
					      len = strlen(buff) + 1;
					      if (len == 1)   /* empty gadget */
						 break;
					      string = (char *)AllocMem(len, 0L);
					      if (string == NULL)
						 break;
					      strcpy(string, buff);
					      break;

			  default	    : break;
			 }
			break;

	case ACTIVEWINDOW : ActivateGadget(&string_gadget, win, NULL);
			    break;

	case CLOSEWINDOW : go_on = FALSE;
			   break;

	default : break;

      } /* end of switch(msg->Class) */
     ReplyMsg(msg);

    } /* end of while(msg....) */

  } /* end of while (go_on) */

 CloseWindow(win);

 return string;
}

