
/*
 *  			skew2.c  --  SKEleton Writer, part 2
 */

#include <exec/types.h>
#include <stdio.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <graphics/displayinfo.h>

#include "skew.h"

BOOL Really_Quit = FALSE;	/* TRUE when positive answer to ReallyQuit? */

extern long GlobalError;

extern BOOL Writing_Done;	/* TRUE when work was saved and no gadget hit */

extern long Display_num;

extern struct Window  *Wnd;

/* flags for cycle gadgets on display #3 */
extern LONG
	WaitingMode_FLAG, Variables_FLAG, Comments_FLAG, FillIns_FLAG,
    TopArgs_FLAG, TopReturn_FLAG, TestVarScope_FLAG;

/* stuff for IDCMPWindow name */
extern char *IDCMP_WIN_BUF, IDCMP_WIN_NAME[];

/* stuff for top-level function name */
extern char *TOP_LEVEL_BUF, TOP_LEVEL_NAME[];

/* prefix & suffix for the names of generated functions */
extern char *PREFIX_BUF, *SUFFIX_BUF, PREFIX_NAME[], SUFFIX_NAME[];

extern char *TEST_VAR_BUF, TEST_VAR_NAME[];

extern struct Gadget *GList, *Gadgets[];

/* flags related to gadgets & output file */
LONG Flag1  = CLASS_FLAG;			            /* 'Class' is preset */
LONG Flag2A, Flag2B, Flag3;

/*  function prototypes  */
VOID HandleIDCMP( VOID );
__regargs static VOID HandleGadgets( USHORT, APTR );
static VOID HandleQuitGad( VOID );
static LONG  HandleOutFile( VOID );
__regargs static BOOL AskYesNo(  char *, char *, char * );
__regargs extern VOID  GenerateCode( BPTR );
__regargs extern LONG MakeDisplay( LONG );


VOID
HandleIDCMP()
{
	struct  IntuiMessage  *msg;
	ULONG	class;
	USHORT  code;
	APTR	iaddress;

	while ( Really_Quit == FALSE ) {
		WaitPort( Wnd->UserPort );

		while ( msg = (struct IntuiMessage *)GT_GetIMsg( Wnd->UserPort ) ) {

		class	 = msg->Class;
		code	 = msg->Code;
		iaddress = msg->IAddress;

		GT_ReplyIMsg( msg );

		switch ( class ) {
			case IDCMP_REFRESHWINDOW:
				GT_BeginRefresh( Wnd );
				GT_EndRefresh( Wnd, TRUE );
				break;
			case IDCMP_GADGETUP:
				HandleGadgets( code, iaddress );
				break;
			case IDCMP_MENUPICK:
											/* just swallow */
				break;
			}
		}
	}

    /* reply all outstanding messages */
    while ( msg = (struct IntuiMessage *)GT_GetIMsg( Wnd->UserPort ) )
        GT_ReplyIMsg( msg );
}


VOID
HandleGadgets( USHORT code, APTR gad_address )
{
	switch ( Display_num ) {

		/* window #0 */
		case 0 :
			if ( gad_address == Gadgets[ GD_IDCMPWindow ] ) {
				strcpy( IDCMP_WIN_NAME,
  ((struct StringInfo *) Gadgets[ GD_IDCMPWindow ]->SpecialInfo)->Buffer );

			}
			else if( gad_address == Gadgets[ GD_Class ] ) {
				Flag1 ^= CLASS_FLAG;
			}
			else if( gad_address == Gadgets[ GD_Code ] ) {
				Flag1 ^= CODE_FLAG;
			}
			else if( gad_address == Gadgets[ GD_Qualifier ] ) {
				Flag1 ^= QUALIFIER_FLAG;
			}
			else if( gad_address == Gadgets[ GD_MouseX ] ) {
				Flag1 ^= MOUSEX_FLAG;
			}
			else if( gad_address == Gadgets[ GD_MouseY ] ) {
				Flag1 ^= MOUSEY_FLAG;
			}
			else if( gad_address == Gadgets[ GD_Seconds ] ) {
				Flag1 ^= SECONDS_FLAG;
			}
			else if( gad_address == Gadgets[ GD_Micros ] ) {
				Flag1 ^= MICROS_FLAG;
			}
			else if( gad_address == Gadgets[ GD_IAddress ] ) {
				Flag1 ^= IADDRESS_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_gadtools ] ) {
				Flag1 ^= gadtools_FLAG;
			}
			else if( gad_address == Gadgets[ GD_QUIT1 ] ) {
				HandleQuitGad( );
			}
			else if ( gad_address == Gadgets[ GD_GO_ON1 ] ) {
				RemoveGList( Wnd, GList, -1 );

				/* nothing else works! */
				ZipWindow( Wnd ); ZipWindow( Wnd );
				MakeDisplay( ++Display_num );
			}
		break;

		/* window #1 */
		case 1 :
			if ( gad_address == Gadgets[ GD_MOUSEBUTTONS ]  ) {
				Flag2A ^= MOUSEBUTTONS_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MOUSEBUTTONS_F ] ) {
				Flag2A ^= MOUSEBUTTONS_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MOUSEMOVE ] ) {
				Flag2A ^= MOUSEMOVE_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MOUSEMOVE_F ] ) {
				Flag2A ^= MOUSEMOVE_F_FLAG;
			}

			/* DELTAMOVE is disabled! */

			else if ( gad_address == Gadgets[ GD_GADGETDOWN ] ) {
				Flag2A ^= GADGETDOWN_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_GADGETDOWN_F ] ) {
				Flag2A ^= GADGETDOWN_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_GADGETUP ] ) {
				Flag2A ^= GADGETUP_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_GADGETUP_F ] ) {
				Flag2A ^= GADGETUP_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_CLOSEWINDOW ] ) {
				Flag2A ^= CLOSEWINDOW_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_CLOSEWINDOW_F ] ) {
				Flag2A ^= CLOSEWINDOW_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUPICK ] ) {
				Flag2A ^= MENUPICK_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUPICK_F ] ) {
				Flag2A ^= MENUPICK_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUVERIFY ] ) {
				Flag2A ^= MENUVERIFY_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUVERIFY_F ] ) {
				Flag2A ^= MENUVERIFY_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUHELP ] ) {
				Flag2A ^= MENUHELP_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_MENUHELP_F ] ) {
				Flag2A ^= MENUHELP_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_RAWKEY ] ) {
				Flag2A ^= RAWKEY_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_RAWKEY_F ] ) {
				Flag2A ^= RAWKEY_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_VANILLAKEY ] ) {
				Flag2A ^= VANILLAKEY_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_VANILLAKEY_F ] ) {
				Flag2A ^= VANILLAKEY_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQSET ] ) {
				Flag2A ^= REQSET_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQSET_F ] ) {
				Flag2A ^= REQSET_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQCLEAR ] ) {
				Flag2A ^= REQCLEAR_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQCLEAR_F ] ) {
				Flag2A ^= REQCLEAR_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQVERIFY ] ) {
				Flag2A ^= REQVERIFY_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REQVERIFY_F ] ) {
				Flag2A ^= REQVERIFY_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_NEWSIZE ] ) {
				Flag2B ^= NEWSIZE_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_NEWSIZE_F ] ) {
				Flag2B ^= NEWSIZE_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_SIZEVERIFY ] ) {
				Flag2B ^= SIZEVERIFY_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_SIZEVERIFY_F ] ) {
				Flag2B ^= SIZEVERIFY_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_ACTIVEWINDOW ] ) {
				Flag2B ^= ACTIVEWINDOW_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_ACTIVEWINDOW_F ] ) {
				Flag2B ^= ACTIVEWINDOW_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_INACTIVEWINDOW ] ) {
				Flag2B ^= INACTIVEWINDOW_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_INACTIVEWINDOW_F ] ) {
				Flag2B ^= INACTIVEWINDOW_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_CHANGEWINDOW ] ) {
				Flag2B ^= CHANGEWINDOW_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_CHANGEWINDOW_F ] ) {
				Flag2B ^= CHANGEWINDOW_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REFRESHWINDOW ] ) {
				Flag2B ^= REFRESHWINDOW_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_REFRESHWINDOW_F ] ) {
				Flag2B ^= REFRESHWINDOW_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_DISKINSERTED ] ) {
				Flag2B ^= DISKINSERTED_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_DISKINSERTED_F ] ) {
				Flag2B ^= DISKINSERTED_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_DISKREMOVED ] ) {
				Flag2B ^= DISKREMOVED_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_DISKREMOVED_F ] ) {
				Flag2B ^= DISKREMOVED_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_NEWPREFS ] ) {
				Flag2B ^= NEWPREFS_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_NEWPREFS_F ] ) {
				Flag2B ^= NEWPREFS_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_INTUITICKS ] ) {
				Flag2B ^= INTUITICKS_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_INTUITICKS_F ] ) {
				Flag2B ^= INTUITICKS_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_IDCMPUPDATE ] ) {
				Flag2B ^= IDCMPUPDATE_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_IDCMPUPDATE_F ] ) {
				Flag2B ^= IDCMPUPDATE_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_LONELYMESSAGE ] ) {
				Flag2B ^= LONELYMESSAGE_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_LONELYMESSAGE_F ] ) {
				Flag2B ^= LONELYMESSAGE_F_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_QUIT2 ] ) {
				HandleQuitGad( );
			}
			else if ( gad_address == Gadgets[ GD_GO_ON2 ] ) {
				RemoveGList( Wnd, GList, -1 );
				ZipWindow( Wnd ); ZipWindow( Wnd );
				MakeDisplay( ++Display_num );
			}
			else if ( gad_address == Gadgets[ GD_STEP_BACK2 ] ) {
				RemoveGList( Wnd, GList, -1 );
				ZipWindow( Wnd ); ZipWindow( Wnd );
				MakeDisplay( --Display_num );
			}
		break;

		/* window #2 */
		case 2 :
			if ( gad_address == Gadgets[ GD_TopLevelRet ] ) {
                Writing_Done = FALSE;
				TopReturn_FLAG = (WaitingMode_FLAG + code) % 2;
			}
			else if ( gad_address == Gadgets[ GD_TopLevelName ] ) {
                Writing_Done = FALSE;
				strcpy( TOP_LEVEL_NAME,
  ((struct StringInfo *) Gadgets[ GD_TopLevelName ]->SpecialInfo)->Buffer );
			}
			else if ( gad_address == Gadgets[ GD_Prefix ] ) {
                Writing_Done = FALSE;
				strcpy( PREFIX_NAME,
  ((struct StringInfo *) Gadgets[ GD_Prefix ]->SpecialInfo)->Buffer );
			}
			else if ( gad_address == Gadgets[ GD_Suffix ] ) {
                Writing_Done = FALSE;
				strcpy( SUFFIX_NAME,
  ((struct StringInfo *) Gadgets[ GD_Suffix ]->SpecialInfo)->Buffer );
			}
			else if ( gad_address == Gadgets[ GD_Skeletons ] ) {
                Writing_Done = FALSE;
				Flag3 ^= Skeletons_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_Prototypes ] ) {
                Writing_Done = FALSE;
				Flag3 ^= Prototypes_FLAG;
			}
			else if ( gad_address == Gadgets[ GD_WaitingMode ] ) {
                Writing_Done = FALSE;
				WaitingMode_FLAG = (WaitingMode_FLAG + code) % 2;
			}
			else if ( gad_address == Gadgets[ GD_Variables ] ) {
				Variables_FLAG = (Variables_FLAG + code) % 2;
                Writing_Done = FALSE;
			}
			else if ( gad_address == Gadgets[ GD_Comments ] ) {
                Writing_Done = FALSE;
				Comments_FLAG = (Comments_FLAG + code) % 3;
			}
			else if ( gad_address == Gadgets[ GD_FillIns ] ) {
                Writing_Done = FALSE;
				FillIns_FLAG = (FillIns_FLAG + code) % 4;
			}
            else if ( gad_address == Gadgets[ GD_TopArgs ] ) {
                Writing_Done = FALSE;
	    		TopArgs_FLAG = (TopArgs_FLAG + code) % 2;
            }
			else if ( gad_address == Gadgets[ GD_TestVarName ] ) {
                Writing_Done = FALSE;
				strcpy( TEST_VAR_NAME,
  ((struct StringInfo *) Gadgets[ GD_TestVarName ]->SpecialInfo)->Buffer );
			}
			else if ( gad_address == Gadgets[ GD_TestVarScope ] ) {
				TestVarScope_FLAG = (TestVarScope_FLAG + code) % 2;
                Writing_Done = FALSE;
			}
			else if ( gad_address == Gadgets[ GD_QUIT3 ] ) {
				if ( ! Writing_Done ) {
					HandleQuitGad();
				}
				else {
					Really_Quit = TRUE;
				}
			}
			else if ( gad_address == Gadgets[ GD_STEP_BACK3 ] ) {
                Writing_Done = FALSE;
				RemoveGList( Wnd, GList, -1 );
				ZipWindow( Wnd ); ZipWindow( Wnd );
				MakeDisplay( --Display_num );
			}
			else if( gad_address == Gadgets[ GD_WRITE_C ] ) {
				if ( ! HandleOutFile() ) {
					DisplayBeep( NULL );		/* he may try again... */
					return;
				}
			}
		break;
	}
}


VOID
HandleQuitGad()
{
	Really_Quit = AskYesNo( "Do you really want to quit?", " YES ", " NO " );
}


BOOL
AskYesNo( char *hail_text, char *pos_text, char *neg_text )
{
	struct IntuiText prompt, yprompt, nprompt;
	BOOL return_val;

	prompt.FrontPen 	= 0;
	prompt.BackPen  	= 1;
	prompt.DrawMode 	= JAM1;
	prompt.LeftEdge 	= 25;
	prompt.TopEdge  	= 15;
	prompt.ITextFont	= NULL;
	prompt.IText		= hail_text;
	prompt.NextText 	= NULL;

	yprompt.FrontPen	 = 0;
	yprompt.BackPen 	 = 1;
	yprompt.DrawMode	 = JAM1;
	yprompt.LeftEdge	 = 15;
	yprompt.TopEdge 	 = 3;
	yprompt.ITextFont	 = NULL;
	yprompt.IText		 = pos_text;
	yprompt.NextText	 = NULL;

	nprompt.FrontPen	 = 0;
	nprompt.BackPen 	 = 1;
	nprompt.DrawMode	 = JAM1;
	nprompt.LeftEdge	 = 15;
	nprompt.TopEdge 	 = 3;
	nprompt.ITextFont	 = NULL;
	nprompt.IText		 = neg_text;
	nprompt.NextText	 = NULL;

	return_val = AutoRequest( Wnd, &prompt, &yprompt,
					   &nprompt, NULL, NULL, 120, 80 );
}


/* returns 0 on SERIOUS error (requester not alocated ); 1 otherwise */
int
HandleOutFile()
{
	char OutFileName[ 80 ];
	char path_str[ 256 ];
	BPTR out_fh = NULL;
	struct FileRequester *gc_GenC = NULL;

	struct TagItem	gc_CTags[] = {
		ASL_Hail,		   	(ULONG)"Save C Source As...",
		ASL_Window, 	  	0L,
		ASL_Height			215,
		ASL_File,			(ULONG)"skew_file.c",
		ASL_Dir,			(ULONG)"RAM:",
		ASL_Pattern,		(ULONG)"#?.c",
		ASL_OKText, 	   	(ULONG)"Save",
		ASL_FuncFlags,  	FILF_SAVE | FILF_PATGAD,
		TAG_DONE
	};

	if ( ! ( gc_GenC =
		(struct FileRequester *)AllocAslRequest( 	ASL_FileRequest,
													TAG_DONE ) ) )
		return( 0 );

	gc_CTags[ 1 ].ti_Data = Wnd;

	if ( AslRequest( gc_GenC, gc_CTags ) ) {

		/* the idiot left us with no file name */
		if ( ! *gc_GenC->rf_File ) {
			AskYesNo( "Can't write to file with NO NAME!",
					"HOW STUPID OF ME!", "SORRY, I'M SLEEPY..." );
			goto cancel;
		}

		strcpy( path_str, gc_GenC->rf_Dir );
		AddPart( path_str, gc_GenC->rf_File, 256 );

		/* if we have some file-name and this file already exists */
		if ( ! access( path_str, 0 ) ) {
			if ( ! AskYesNo( "File already exists! Overwrite it?", "YES", "NO" ) ) {
				goto cancel;		 	/* he didn't want to overwrite */
			}
		}
	}
	else {
		goto cancel;					/* user hit 'CANCEL' */
	}

	/* this CAN be a slight problem... */
	if ( ( out_fh = Open( path_str, MODE_NEWFILE ) ) == NULL ) {
		AskYesNo( "File has NOT been opened!", "CANCEL", "CANCEL" );
		FreeAslRequest( gc_GenC );
		return( 0 );
	}

	GenerateCode( out_fh );

	Close( out_fh );

cancel:
	FreeAslRequest( gc_GenC );
	return( 1 );
}
