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


#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <graphics/displayinfo.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <stdio.h>

#include "skew.h"

BOOL Really_Quit = FALSE;   /* TRUE when positive answer to ReallyQuit? */
BOOL Writing_Done = FALSE;  /* TRUE when work was saved and no gadget hit */

extern int Display_num;

extern struct Window  *Wnd;
extern struct TagItem gc_CTags[];

/* flags for cycle gadgets on display #3 */
int WaitingMode_FLAG, Variables_FLAG, Comments_FLAG, FillIns_FLAG;
int WaitingMode_START, Variables_START, Comments_START, FillIns_START;


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

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

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

struct Gadget *GList = 0L;
struct Gadget *Gadgets[ 55 ];

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

char OutFileName[ 80 ];

struct FileRequester            *gc_GenC = 0l;

UBYTE                            gc_CPatt[32]  = "#?.c";
UBYTE                            gc_CFile[32]  = "skew_file.c";
UBYTE                            gc_CPath[256];

UWORD                            gc_TagOffset, gc_GadOffset, gc_ScreenOffset;

struct TagItem                   gc_CTags[] = {
    ASL_Hail,                   "Save C Source As...",
    ASL_Window,                 0l,
    ASL_File,                   gc_CFile,
    ASL_Dir,                    gc_CPath,
    ASL_Pattern,                gc_CPatt,
    ASL_OKText,                 "Save",
    ASL_FuncFlags,              FILF_SAVE | FILF_PATGAD,
    TAG_DONE };


/*  function prototypes  */
void HandleIDCMP( void );
static void HandleGadgets( USHORT, APTR );
static void HandleQuitGad( void );
static BOOL AskYesNo(  char *, char *, char * );
static int  GetOutFileName( void );
extern int  GenerateCode( *FILE );
extern long MakeDisplay( int );

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

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

		while ( msg = 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;
            }
        }
    }
}


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_QUIT1 ] ) {
                HandleQuitGad( );
            }
            else {          /* gad_address == Gadgets[ GD_GO_ON1 ] ) */
                RemoveGList( Wnd, GList, -1 );
                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;
            }
            else if ( gad_address == Gadgets[ GD_DELTAMOVE ] ) {
                Flag2A ^= DELTAMOVE_FLAG;
            }
            else if ( gad_address == Gadgets[ GD_DELTAMOVE_F ] ) {
                Flag2A ^= DELTAMOVE_F_FLAG;
            }
            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 {      /* 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_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_gadtools ] ) {
                Writing_Done = FALSE;
                Flag3 ^= gadtools_FLAG;
            }
            else if ( gad_address == Gadgets[ GD_WaitingMode ] ) {
                Writing_Done = FALSE;
                WaitingMode_FLAG = (WaitingMode_START + code) % 2;
            }
            else if ( gad_address == Gadgets[ GD_Variables ] ) {
                Writing_Done = FALSE;
                Variables_FLAG = (Variables_START + code) % 2;
            }
            else if ( gad_address == Gadgets[ GD_Comments ] ) {
                Writing_Done = FALSE;
                Comments_FLAG = (Comments_START + code) % 3;
            }
            else if ( gad_address == Gadgets[ GD_FillIns ] ) {
                Writing_Done = FALSE;
                FillIns_FLAG = (FillIns_START + code) % 4;
            }
            else if ( gad_address == Gadgets[ GD_QUIT3 ] ) {
                if ( NOT Writing_Done ) {
                    HandleQuitGad( );
                }
                else {
                    Really_Quit = TRUE;
                }
            }
            else if( gad_address == Gadgets[ GD_WRITE_C ] ) {
                Writing_Done = FALSE;
                GetOutFileName();
            }
            else {      /* gad_address == Gadgets[ GD_STEP_BACK3 ] ) */
                Writing_Done = FALSE;
                RemoveGList( Wnd, GList, -1 );
                ZipWindow( Wnd );
                ZipWindow( Wnd );
                MakeDisplay( --Display_num );
            }
        break;
    }
}


void HandleQuitGad( void )
{
    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 = FALSE;

    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, 100 );
}



/* so far we do nothing with the returned value, but we have negative
integers for errors and positive for user cancelling; 0 means O.K! DONE */

int GetOutFileName( void )
{
    char tmp_str[ 290 ];
    char *tmp_dir, *tmp_file;
    FILE *out_ptr;

    if ( NOT ( gc_GenC = AllocAslRequest( ASL_FileRequest, TAG_DONE ) ) )
        return( -10 );

    gc_CTags[1].ti_Data = Wnd;

    if ( AslRequest( gc_GenC, gc_CTags )) {

        tmp_dir     =   gc_GenC->rf_Dir;
        tmp_file    =   gc_GenC->rf_File;

        if ( strlen( tmp_dir ) != 0 ) {     /* not default dir */
            if ( strcspn( tmp_dir, ":" ) != ( strlen( tmp_dir ) - 1 ) )
            {
                strcpy( tmp_str, tmp_dir );
                strcat( tmp_str, "/" );
                strcat( tmp_str, tmp_file );
            }
            else {
                strcpy( tmp_str, tmp_dir );
                strcat( tmp_str, tmp_file );
            }
        }
        else {
            strcpy( tmp_str, tmp_file );
        }

        /* if file already exists */
        if ( NOT access( tmp_str, 0 ) ) {
            if ( NOT AskYesNo( "File already exists! Overwrite it?", "YES", "NO" ) ) {
                return( 2 );            /* he didn't want to overwrite */
            }
        }
    }
    else
        return( 1 );                        /* user hit 'CANCEL' */

    if ( ( out_ptr = fopen( tmp_str, "w" ) ) == NULL ) {
        AskYesNo( "File has NOT been opened!", "CANCEL", "CANCEL" );
        return( -5 );
    }

    GenerateCode( out_ptr );

    Writing_Done = TRUE;

    fclose( out_ptr );

    return( 0 );
}
