/*
 *  Source machine generated by GadToolsBox V1.4
 *  which is (c) Copyright 1991,92 Jaba Development
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <exec/types.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/gfxbase.h>

#include <proto/exec.h>				// use amiga library stuff
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/asl.h>
#include <proto/utility.h>
#include <proto/diskfont.h> 
#include <proto/intuition.h>

#include "AmigaWIN.h"
#include "rawkeys.h"
#include "mod2midi_globals.h"

#include "mod2midi_rev.h"

UBYTE version_str[] = { VERSTAG };

#define	FW	7		// font width
#define	FH	8		// font height

#define	Input_CNT	1
#define	GD_f1		1
typedef char *string;

struct Screen         *Scr = NULL;
APTR                   VisualInfo = NULL;
struct Window         *InputWnd = NULL;
struct Gadget         *InputGList = NULL;
struct Gadget         *InputGadgets[10];
struct Menu           *InputMenus = NULL;
UWORD                  InputLeft = 50;
UWORD                  InputTop = 91;
UWORD                  InputWidth = 80*FW;
UWORD                  InputHeight = (25*FH)+18;
UBYTE                 InputWdt[100];

struct TextAttr thinpaz8 = {
	( STRPTR )"thinpaz.font", 8, 0x00, 0x00 };

struct TextFont	*thinpazfont8;

struct NewMenu InputNewMenu[] = {
	NM_TITLE, (STRPTR)"Project", NULL, 0, NULL, NULL,
		NM_ITEM, (STRPTR)"Select midi file", (STRPTR)"d", 0, 0x0L, NULL,
		NM_ITEM, (STRPTR)"Select source mod file", (STRPTR)"s", 0, NULL, NULL,
		NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
		NM_ITEM, (STRPTR)"Convert Now", (STRPTR)"c", 0, NULL, NULL,
		NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
		NM_ITEM, (STRPTR)"About", (STRPTR)"?", 0, NULL, NULL,
		NM_ITEM, (STRPTR)"Quit", (STRPTR)"q", 0, NULL, NULL,
	NM_TITLE, (STRPTR)"Samples", NULL, 0, NULL, NULL,
		NM_ITEM, (STRPTR)"Remap Samples to MID instruments", (STRPTR)"m", 0, 0x0L, NULL,
		NM_ITEM, (STRPTR)"Transposing", (STRPTR)"t", 0, NULL, NULL,
		NM_ITEM, (STRPTR)"Volume Shift", (STRPTR)"v", 0, NULL, NULL,
		NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
		NM_ITEM, (STRPTR)"Save Info", (STRPTR)"i", 0, NULL, NULL,
	NM_TITLE, (STRPTR)"Options", NULL, 0, NULL, NULL,
		NM_ITEM, (STRPTR)"Drum Channel", (STRPTR)"d", 0, 0x0L, NULL,
		NM_ITEM, (STRPTR)"Tempo Type", NULL, 0, NULL, NULL,
};

UWORD InputGTypes[] = {
	BUTTON_KIND,
};

struct NewGadget InputNGad[] = {
	6, 3, 45, 12, (UBYTE *)"Quit", NULL, GD_f1, PLACETEXT_IN, NULL, NULL,
};

ULONG InputGTags[] = {
	(GT_Underscore), '_', (TAG_DONE),
};




/*
 * --- Message info
 */
ULONG			IClass;
UWORD			Qualifier, Code;

struct		Gadget	*IObject;
ULONG			version;


struct	FileRequester	*filereq;


/*
 * --- Close the libraries which are opened by me.
 */
void CloseLibraries( void ){
	if ( filereq )
		FreeAslRequest( filereq );

	if (DiskFontBase)		CloseLibrary( (struct Library *) DiskFontBase );
	if (GadToolsBase)		CloseLibrary(( struct Library * )GadToolsBase );
	if (IntuitionBase)	CloseLibrary(( struct Library * )IntuitionBase );
	if (DosBase)			CloseLibrary(( struct Library * )DosBase );
	if (GfxBase)			CloseLibrary(( struct Library * )GfxBase );
	if (AslBase)			CloseLibrary(( struct Library * )AslBase );
}


/*
 * --- Open lots of libraries that I need.
 */
long OpenLibraries( void ){
	struct	TagItem	AslTags[] = { 0,0 };

	if ( !(GfxBase = (struct GfxBase *) OpenLibrary((UBYTE *) "graphics.library" , 33l ))) {
		Printf("\graphics.library\n");
		return FALSE;
		}

	if ( !(DosBase = (struct DosBase *) OpenLibrary((UBYTE *) "dos.library", 33l ))) {
		Printf("\tdos.library\n");
		return FALSE;
		}

	if ( !(IntuitionBase = (struct IntuitionBase *) OpenLibrary((UBYTE *) "intuition.library", 33l ))) {
		Printf("\tintuition.library\n");
		return FALSE;
		}

	if ( !(AslBase = (struct Library *) OpenLibrary((UBYTE *) "asl.library", 37l ))) {
		if ( !(AslBase = (struct Library *) OpenLibrary((UBYTE *) "asl13.library", 34l ))) {
			Printf("\tasl.library\n");
			return FALSE;
			}
		}

	if ( !(GadToolsBase = (struct Library *) OpenLibrary((UBYTE *) "gadtools.library", 36l ))) {
		if ( !(GadToolsBase = (struct Library *) OpenLibrary((UBYTE *) "gadtools13.library", 34l ))) {
			Printf("\tgadtools.library\n");
			return FALSE;
			}
		}

	if ( !(DiskFontBase = (struct Library *) OpenLibrary((UBYTE *) "diskfont.library", 33l ))) {
		Printf("\tdiskfont.library\n");
		return FALSE;
		}

	filereq = (struct FileRequester *) AllocAslRequest( ASL_FileRequest,AslTags );

	return TRUE;
}


/*
 * --- Clears all message from a message port.
 */
void ClearMsgPort( struct MsgPort *mport )
{
    struct IntuiMessage  *msg;

    while ( msg = GT_GetIMsg( mport )) GT_ReplyIMsg( msg );
}




/*
 * --- Reads a message from the window message port.
 * --- Returns TRUE if a message was read and puts the
 * --- message data in the globals. Return FALSE if there
 * --- was no message at the port.
 */
long ReadIMsg( struct Window *iwnd )
{
    struct IntuiMessage *imsg;

    if ( imsg = GT_GetIMsg( iwnd->UserPort )) {

        IClass      =   imsg->Class;
        Qualifier   =   imsg->Qualifier;
        Code        =   imsg->Code;
        IObject     =   imsg->IAddress;

        GT_ReplyIMsg( imsg );

        return TRUE;
    }
    return FALSE;
}




/**********************************************************************
 *
 *						Draw3DOutBox
 *	Description : just like normal bevelbox except inside color is selectable
 *				  plus it looks MONUMENTAL!
 *								ŻŻŻŻŻŻŻŻŻŻŻ
 *  Returns		: NULL
 *	Globals		: usual
 *
 */
void Draw3DBox(
	struct	RastPort *rp,		// window rastport to draw into
	UWORD	xpos,				// X coordinate to place MEGA-BEVEL
	UWORD	ypos,				// Y coordinate to place MEGA-BEVEL
	UWORD	xsize,				// X size of MEGA-BEVEL
	UWORD	ysize,				// X size of MEGA-BEVEL
	UWORD	shine_pen,			// top-left pen
	UWORD	body_pen,			// central pen
	UWORD	shadow_pen			// bot-right pen
){

#define	LineDraw(x,y,x2,y2)	Move( rp, x , y); \
							Draw( rp, x2, y2 )

	xsize--;ysize--;

	SetAPen( rp, body_pen );
	RectFill( rp, xpos, ypos, xpos+xsize, ypos+ysize);

	LineDraw( xpos, ypos, xpos+1, ypos+1 );
	LineDraw( xpos+xsize-1, ypos+ysize-1, xpos+xsize, ypos+ysize );

	SetAPen( rp, shine_pen );
	LineDraw( xpos+0, ypos+0, xpos+xsize-1, ypos );
	LineDraw( xpos+0, ypos+1, xpos+xsize-2, ypos+1 );
	LineDraw( xpos+0, ypos+0, xpos, ypos+ysize-1 );
	LineDraw( xpos+1, ypos+0, xpos+1, ypos+ysize-2 );

	SetAPen( rp, shadow_pen );
	LineDraw( xpos+1, ypos+ysize-0, xpos+xsize-1, ypos+ysize-0 );
	LineDraw( xpos+2, ypos+ysize-1, xpos+xsize-2, ypos+ysize-1 );
	LineDraw( xpos+xsize-0, ypos+1, xpos+xsize-0, ypos+ysize-1 );
	LineDraw( xpos+xsize-1, ypos+2, xpos+xsize-1, ypos+ysize-2 );

	SetAPen( rp, 2 );
	if ( shine_pen > shadow_pen ){
		LineDraw( xpos+0, ypos+0, xpos+2, ypos+0 );
		LineDraw( xpos+0, ypos+0, xpos+0, ypos+2 );
	}
	else {
		LineDraw( xpos+xsize, ypos+ysize, xpos+xsize-2, ypos+ysize );
		LineDraw( xpos+xsize, ypos+ysize, xpos+xsize-0, ypos+ysize-2 );
	}
}







int OpenInputWindow( void )
{
	struct NewGadget	ng;
	struct Gadget	*g;
	UWORD		lc, tc;
	UWORD		offx, offy;

	OpenLibraries();
	version=GfxBase->LibNode.lib_Version;
	Scr = IntuitionBase->ActiveScreen;
	if ( ! (thinpazfont8  = OpenDiskFont( &thinpaz8 )) ) {
			;
		}
	if ( ! ( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
		return( 1L );
	offx = Scr->WBorLeft; offy = Scr->WBorTop + Scr->RastPort.TxHeight + 1;



	if ( ! ( g = CreateContext( &InputGList )))
		return( 1L );

	for( lc = 0, tc = 0; lc < Input_CNT; lc++ ) {

		CopyMem((char * )&InputNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));

		ng.ng_VisualInfo = VisualInfo;
		ng.ng_TextAttr   = &thinpaz8;
		ng.ng_LeftEdge  += offx;
		ng.ng_TopEdge   += offy;

		InputGadgets[ lc ] = g = CreateGadgetA((ULONG)InputGTypes[ lc ], g, &ng, ( struct TagItem * )&InputGTags[ tc ] );

		while( InputGTags[ tc ] ) tc += 2;
		tc++;

		if ( NOT g )
			return( 2L );
	}


	if ( ! ( InputMenus = CreateMenus( InputNewMenu,
					GTMN_FrontPen,		2L,
					TAG_DONE )))
		return( 3L );

	LayoutMenus( InputMenus, VisualInfo,
			//		GTMN_TextAttr, 		&helvetica18,
					GTMN_NewLookMenus,	TRUE,
					TAG_DONE );

	if ( ! ( InputWnd = OpenWindowTags( NULL,
				WA_Left,		InputLeft,
				WA_Top,			InputTop,
				WA_Width,		InputWidth,
				WA_Height,		InputHeight + offy,
				WA_IDCMP,		IDCMP_MOUSEBUTTONS|BUTTONIDCMP|INTEGERIDCMP|
								IDCMP_CHANGEWINDOW|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
								IDCMP_ACTIVEWINDOW|IDCMP_MENUPICK|IDCMP_VANILLAKEY|IDCMP_RAWKEY,
				WA_Flags,		WFLG_NEWLOOKMENUS|WFLG_ACTIVATE|WFLG_DRAGBAR|WFLG_DEPTHGADGET|
								WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_GIMMEZEROZERO,
			//	WA_Gadgets,		InputGList,
				WA_Title,		InputWdt,
				WA_PubScreen,	NULL,
				WA_MinWidth,	InputWidth,
				WA_MinHeight,	InputHeight + offy,
				WA_MaxWidth,	InputWidth + 140,
				WA_MaxHeight,	InputHeight + offy + 500,
				TAG_DONE )))
	return( 4L );

	SetMenuStrip( InputWnd, InputMenus );

	GT_RefreshWindow( InputWnd, NULL );

	SetFont( InputWnd->RPort, thinpazfont8 );

	return( 0L );
}

void CloseInputWindow( void )
{
	InputLeft = InputWnd->LeftEdge;
	InputTop = InputWnd->TopEdge;

	if ( InputMenus      ) {
		ClearMenuStrip( InputWnd );
		FreeMenus( InputMenus );
		InputMenus = NULL;	}

	if ( InputWnd        ) {
		CloseWindow( InputWnd );
		InputWnd = NULL;
	}

	if ( InputGList      ) {
		FreeGadgets( InputGList );
		InputGList = NULL;
	}
}





/**********************************************************************
 *
 *						InputMenus()
 *	Description : Handles all menu events
 *  Returns		: BOOL
 *	Globals		:
 *
 */
LONG HandleInputMenus( void ){
	struct	MenuItem		*Next;
	LONG	ret=-1;
	UWORD	menu, item, sub;

    while( Code != MENUNULL ) {
        Next = ItemAddress(  InputMenus, Code );
        menu = MENUNUM( Code );
        item = ITEMNUM( Code );
        sub  = SUBNUM( Code );
        switch ( menu ) {
            case    0:
                switch ( item ) {
					case	0:	ret = 0; break;
					case	1:	ret = 1; break;
					case	3:	ret = 2; break;
					case	5:	ret = 5; break;
					case	6:	ret = 99; break;
				}
				break;
            case    1:
                switch ( item ) {
					case	0:	ret = 3; break;		// remap
					case	1:	ret = 6; break;		// transpose
					case	2:	ret = 9; break;		// volume
					case	4:	ret = 4; break;		// save info
				}
				break;
            case    2:
                switch ( item ) {
					case	0:	ret = 7; break;		// drum ch
					case	1:	ret = 8; break;		// tempo
					case	2:	ret = 8; break;		//  "
				}
				break;
		}
		Code = Next->NextSelect;
	}
	return ret;
}


	WORD	rawkey=0;
	WORD	normkey=0;

int GetIntuiEvent( void ){
	int ret=-1;

//printf("waitport\n");
	WaitPort( InputWnd->UserPort );
//	while ( ReadIMsg( InputWnd )) {
		ReadIMsg( InputWnd ); {
//printf("decode msg\n");
		ret=-1;
		rawkey=NULL; normkey = NULL;
		switch ( IClass ) {
			case	IDCMP_CLOSEWINDOW:			// Key short cuts
				ret = 99;
				break;

			case	IDCMP_MOUSEBUTTONS:
				switch ( Code ){
					case SELECTUP:
						break;
					case SELECTDOWN:
						break;
				}
				break;

			case	IDCMP_GADGETUP:
				switch ( IObject->GadgetID ) {
					case	GD_f1:
						ret = 99;
						break;
				}
				break;

			case	IDCMP_VANILLAKEY:			// Key short cuts
				normkey = Code;
				break;

			case	IDCMP_RAWKEY:
				switch( Code ){
					case KEY_UP		:
					case KEY_DOWN	:
					case KEY_LEFT	:
					case KEY_RIGHT	: rawkey = Code;	break;
					default			: rawkey = NULL;	break;
				}
				break;

			case	IDCMP_MENUPICK:
				ret = HandleInputMenus();
				break;

			case	IDCMP_CHANGEWINDOW:
				break;

			case	IDCMP_ACTIVEWINDOW:
				ClearMsgPort( InputWnd->UserPort );
				break;

			case	IDCMP_REFRESHWINDOW:
				GT_BeginRefresh( InputWnd );
				GT_EndRefresh( InputWnd, TRUE);
				break;
		}
	}
//printf("ret=%d   normkey=%d  rawkey=%d\n",ret,normkey,rawkey);
	return ret;
}




/**********************************************************************
 *
 *						AslFileRequest
 *
 *	Description : Put up the ASL FileRequester
 *	Returns		: UBYTE pointer to filename ascii (NULL terminated)
 *	Globals		:
 *
 */
UBYTE *AslFileRequest(
	UBYTE type,				// 'l'=load / 's'=save
	UBYTE *title,			// title of requester window
	UBYTE *drawer,			// the drawer to open into
	UBYTE *pattern			// the pattern to use
){
static
	UBYTE	FileName[180];
	UBYTE	*char1, *ret;
	UWORD	flag1, flag2, len, x, y;

    ret = 0;

	if( !filereq ) return ret;

	x = 10;				// get current mouse coords
	y = 10;

    switch( type ) {
    	case    's':
			char1 = "Save";
			flag1 = FILF_SAVE | FILF_PATGAD;
			flag2 = TRUE;
			break;
        case    'l':
			char1 = "Open";
			flag1 = FILF_PATGAD;
			flag2 = FALSE;
			break;
		}

	if ( AslRequestTags( filereq,
					    ASL_OKText, 			char1,
					    ASL_Hail, 				flag1,
					//	ASLFR_Screen, 			CurrentScr,
						ASLFR_TitleText, 		title,
						ASLFR_InitialLeftEdge,	x,
						ASLFR_InitialTopEdge,	y,
						ASLFR_InitialWidth,		300,
						ASLFR_InitialHeight,	284,
						ASLFR_InitialDrawer,	drawer,
						ASLFR_DoSaveMode,		flag2,
						ASLFR_DoPatterns,		TRUE,
						ASLFR_InitialPattern,	pattern,
					//	ASLFR_TextAttr,			&helvetica13,		//	&mflex10,
						TAG_DONE ) ) {
        strcpy( FileName, filereq->rf_Dir );
		len = strlen( FileName );
		if ( len-- )
			if ( FileName[ len ] != '/' && FileName[ len ] != ':' )
				strcat( FileName, "/" );
        strcat( FileName, filereq->rf_File );
        ret = FileName;
    }

	return( ret );
}



//--------------------------------------------------------------------------

UBYTE	str[100];

void cprintf( UBYTE *a, int b, UBYTE *c ){
	int len=strlen(c);

	if( *(c+len-1) == 13 ) *(c+len-1)=NULL;
	sprintf(str,a,b,c);
	Text( InputWnd->RPort, str, strlen(str) );
}

void cputs( UBYTE *a ){
	Text( InputWnd->RPort, a, strlen(a) );
}

void cputchar( UBYTE *a, UBYTE c ){
	sprintf(str,a,c);
	Text( InputWnd->RPort, str, strlen(str) );
}


//--------------------------------------------------------------------------


void MainWindow(string title, int num, ...)
/* Post: Screen is set up with a nice title and num menus */
{
	va_list args;

	strcpy( InputWdt, title );

	OpenInputWindow();
}


void EndWindows( void ){
	if ( thinpazfont8 )
		CloseFont( thinpazfont8 );
	CloseInputWindow();
	CloseLibraries();
}


	WORD	curr_x=0,curr_y=0,
			left_x=0,top_y=0,
			right_x=0,bottom_y=0,
			pos_x=0,pos_y=0;

void gotoxy( WORD x, WORD y ){
	pos_x = x; pos_y=y;
	curr_x=(x+left_x)*FW;	curr_y=(y+top_y)*FH;
	Move( InputWnd->RPort, curr_x, curr_y );
}
void textcolor( WORD n ){
	SetAPen( InputWnd->RPort, n );
}
void textbackground( WORD n ){
	SetBPen( InputWnd->RPort, n );
}

void window( int x, int y, int x2, int y2 ){
	left_x  =x;		top_y   =y;
	right_x =x2;	bottom_y=y2;
//printf("window:x=%d y=%d x2=%d y2=%d\n",x, y, x2, y2);
}	

void renderwindow( int x, int y, int x2, int y2 ){
	Draw3DBox( InputWnd->RPort, (x*FW)-12, (y*FH)-6, (x2*FW)+12, (y2*FH)+16, 2,3,1 );
//printf("rwindow:x=%d y=%d x2=%d y2=%d\n",x, y, x2, y2);
}


void PrintBar(string s, int w, int y)
/* Post: String s (width w) is highlighted in the text window on line y */
{
	gotoxy(1, y+1);
	textcolor(1);
	textbackground(2);
	cprintf(" %-*s ", w, s);
}

void ClearBar(string s, int w, int y)
/* Post: String s (width w) is normalized in the text window on line y */
{
	gotoxy(1, y+1);
	textcolor(2);
	textbackground(3);
	cprintf(" %-*s ", w, s);
}

void Beep( void ){
	DisplayBeep( NULL );
}

int Choice( void ){
	int ret=-1;

	ret = GetIntuiEvent();

	return ret;
}


void ScrollWindowUp( void ){
	ClipBlit( InputWnd->RPort, left_x*FW, ((top_y+1)*FH)+2,
			  InputWnd->RPort, left_x*FW, ((top_y)*FH)+2,
			 (right_x-left_x)*FW,
			 ((bottom_y-top_y-1)*FH)+2, 0xc0 );
}

void ScrollWindowDown( void ){
	ClipBlit( InputWnd->RPort, left_x*FW, (top_y*FH)+2,
			  InputWnd->RPort, left_x*FW, ((top_y+1)*FH)+2,
			 (right_x-left_x)*FW,
			 ((bottom_y-top_y-1)*FH), 0xc0 );
}




void insline( void ){
	;
}

void clreol( int x ){
	int lp;

	cprintf(" %-*s ", right_x-(x+left_x), " ");
}


#define getch GetCursorKeys
WORD GetCursorKeys( void ){
	GetIntuiEvent();
	if( rawkey ) {
		if( rawkey == KEY_UP ) return -72;
		if( rawkey == KEY_DOWN ) return -80;
		if( rawkey == KEY_LEFT ) return -75;
		if( rawkey == KEY_RIGHT ) return -77;
	}
	else
		return normkey;
}


void ClearWin( void ){
	textcolor(0);
	RectFill( InputWnd->RPort, 0, 0, 80*FW,(26*FH)+1);
	window(1, 1, 80, 25);
}


int ScrollChoice( char *title, char **sp, int w)
/*
 * Returns: The offset of the string from s which is chosen, -1 on none
 *    s points to the start of a list of strings, max length w, NULL term.
 */
{
	string s, t, *srt, *end;
	int l, p, cur, ch, x = -1;

	if (strlen(title) > w)
		w = strlen(title);

	textcolor(1);
	textbackground(0);
	gotoxy(1, 25);
	cputs("Use cursor keys and <RETURN> to make a selection (ESC=back one level).");

	for (end = sp, l = 0; *end!=NULL && l<20; l++);

	renderwindow(6, 1, w, l+1);

	textcolor(2);
	textbackground(3);
	gotoxy(3 + (w - strlen(title))/2, 1);
	cprintf("-- %-*s --", 14, title );

	srt = end = sp;
	for (end = sp, l = 0; *end!=NULL && l<20; l++) {
		gotoxy(6, l+2);
		cprintf(" %-*s", w, *(end++) );
	}
	end--;

	window(6, 2, 8+w, l+2);

	PrintBar(*srt, w, p = 0);
	cur = 0;
	x = -1;
	do {
		ch = GetCursorKeys();
		if(ch<0) {
			if (ch==-72)
				if (!cur)
					Beep();
				else if (p) {
					ClearBar(*(srt+p), w, p);
					p--;
					PrintBar(*(srt+p), w, p);
					cur--;
				} else {
					ClearBar(*(srt--), w, 0);
					gotoxy(1, 1);
					ScrollWindowDown();
					gotoxy(w+3, 1);
					PrintBar(*srt, w, 0);
					end--;
					cur--;
				}
			else if (ch==-80)
				if (p==l-1 && *(end+1)==NULL)
					Beep();
				else if (p < l-1) {
					ClearBar(*(srt+p), w, p);
					p++;
					cur++;
					PrintBar(*(srt+p), w, p);
				} else {
					ClearBar(*end, w, p);
					end++;
					ScrollWindowUp();
					gotoxy(w+3, l);
					cur++;
					PrintBar(*end, w, p);
					srt++;
				}
		} else
		if (ch==13)
			x = cur;
	} while (x < 0 && ch != 27);
	ClearWin();
	return x;
}



/* returns the ysize of the box drawn */
int PrintBox(string *sp, int *x1, int *y1, int *w1) {
	int w, x, i, j, ys=0;
	string s, t, *c;

	if (*sp==NULL)
		return;
	c = sp;
	for (w = strlen(*(c++)), i = 1; *c!=NULL; c++, i++)
		if (w < (x = strlen(*c)))
			w = x;
	*w1 = w + 2;
	*x1 = 1 + (x = (76 - w)/2);
	i = 1 + (21 - i)/2;
	*y1 = i-1;

	for (c = sp; *c!=NULL; c++) ys++;

	window( *x1, *y1, *w1, ys );
	renderwindow( *x1, *y1, *w1, ys );

	textcolor(2);
	textbackground(3);

	x=1;i=1;
	for (c = sp; *c!=NULL; c++) {
		gotoxy(x, i++);
		w = strlen(*c);
		cprintf(" %-*s ", w, *c);
	}
	return ys;
}


void DrawBox( char **sp)
/* Post: The NULL-terminated array of strings pointed to by sp is printed */
{
	int i,i2,i3;
	PrintBox(sp, &i, &i2, &i3);
}


char InfoBox( char **sp)
/*
 * Returns: The key pressed after the NULL-terminated array of strings
 *    pointed to by sp is printed.
 */
{
	int k;

	ClearWin();
	DrawBox(sp);
	window(1, 1, 80, 25);
	textcolor(1);
	textbackground(0);
	gotoxy(1, 25);
	Text( InputWnd->RPort, "Please press a key.", 18 );
	k = GetCursorKeys();
	ClearWin();
	gotoxy(1, 25);
	Text( InputWnd->RPort, "OK.                ", 18 );
	return (char)k;
}



string FileSelect( char **sp, string def)
/* Pre: def != NULL */
/*
 * Returns: The string entered (or def if none entered), after printing
 *    box filled with NULL-terminated strings sp.
 */
{
	string s;

	s = AslFileRequest( 'l', *sp, "" , "#?" );

	return s;
}




string DialogBox( char **sp, string def)
/* Pre: def != NULL */
/*
 * Returns: The string entered (or def if none entered), after printing
 *    box filled with NULL-terminated strings sp.
 */
{
	int x, y, w, ch, i=0, ys;
	string s;

	ys=PrintBox(sp, &x, &y, &w);
	s = (string) malloc(w+1);
	s[w] = 0;
	strncpy(s, def, w);
	textcolor(2);
	textbackground(3);
	gotoxy(1, 25);
	cputs("Enter text, and when you are finished, press <RETURN>.");
	textcolor(1);
	textbackground(0);
	window(x, y, x+w-1, y);
	gotoxy(1, ys-1);
	cprintf("%-*s", w, s);
	gotoxy(1, ys-1);
	x = strlen(s);
	do {
		if (!(ch = getch()))
			ch = -getch();
		if (ch==8 || ch==127)
			if (!i)
				Beep();
			else {
				x = --i;
				gotoxy(1+x, ys-1);
				cputchar(" ",0);
				gotoxy(1+x, ys-1);
		//		clreol( x );
			}

/*		else if (ch==-75)			// left
			if (!i)
				Beep();
			else {
				cputchar("\b",0);
				i--;
			}
		else if (ch==-77)			// right
			if (i==x)
				Beep();
			else {
				cputchar("%c", s[i]);
				i++;
			}
*/
		else if (ch!=13 && ch!=27)
			if (i==w-1)
				Beep();
			else {
				cputchar("%c", ch);
				if (i==x)
					x++;
				s[i++] = ch;
			}
	} while (ch!=13 && ch!=27);
	s[x] = 0;
	if (ch==27) {
		free(s);
		strcpy(s = (string) malloc(strlen(def)+1), def);
	}
	ClearWin();
	return s;

}

