
#include <exec/types.h>
#include <libraries/asl.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>

#include <clib/gadtools_protos.h>
#include <clib/iffparse_protos.h>
#include <clib/asl_protos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/intuition_protos.h>

#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define CATCOMP_NUMBERS

#include "project.catalog.h"

#include "compiler.h"

#include "project.h"

extern AttachList( void );
extern DettachList( void );
extern struct TagItem *ScreenPrefs( struct TagItem * );
extern void StdVanillaKey( long code );
extern void LoadScreenTags( struct IFFHandle * );
extern void SaveScreenTags( struct IFFHandle * );

extern struct TagItem *CheckTag;

struct CompilerOpts Config = {
    CPU30,FPU82,
    SMALL,SMALL,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    REGARG,
    FALSE,
    0,
    TRUE,
    TRUE,
    PROF0,
    0,
    0,
    0,
    "2.0",
};

char *OptLine;
char *ParmsLine;

char *DICEDir;
char *AutoDir;
char *SourceDir;
char *DestDir;
char *IncludeDir;
char *LibDir;
char *ObjDir;
char *Editor;

BOOL compilall=FALSE,compil=FALSE,link=FALSE;

struct CompilerOpts Config2;

void MakeOptions( void ) {
  char temp[102];

    strcpy( temp , "-" );
    strncat( temp , Config.Version , 3 );
    if ( Config.Proto )
	strcat( temp , " -proto" );
    switch( Config.CPU ) {
      case 1:
	strcat( temp , " -020" );
	break;
      case 2:
	strcat( temp , " -030" );
	break;
    }
    switch( Config.FPU ) {
      case 1:
	strcat( temp , " -881" );
	break;
      case 2:
	strcat( temp , " -882" );
	break;
    }
    switch( Config.Prof ) {
      case 1:
	strcat( temp , " -prof" );
	break;
      case 2:
	strcat( temp , " -prof2" );
	break;
    }
    if ( Config.CPP )
	strcat( temp , " -//" );
    if ( Config.Data == SMALL )
	strcat( temp , " -md" );
    else
	strcat( temp , " -mD" );
    if ( Config.Code == SMALL )
	strcat( temp , " -mc" );
    else
	strcat( temp , " -mC" );
    if ( Config.RCalls == REGARG )
	strcat( temp , " -mRR" );
    if ( Config.ICalls )
	strcat( temp , " -mi" );
    if ( Config.Resident && !Config.Hunk )
	strcat( temp , " -r" );
    if ( Config.DStack )
	strcat( temp , " -gs" );
    if ( Config.Chip )
	strcat( temp , " -chip" );
    if ( Config.Frag )
	strcat( temp , " -frag" );
    if ( Config.Unix )
	strcat( temp , " -unix" );
    if ( Config.Hunk ) {
	if ( Config.Resident )
	    strcat( temp , " -pr" );
	else
	    strcat( temp , " -pi" );
    }
    if ( Config.DebugI )
	strcat( temp , " -s" );
    if ( Config.DebugL )
	strcat( temp , " -d1" );
    switch( Config.HunkCode ) {
      case 1:
	strcat( temp , " -ms" );
	break;
      case 2:
	strcat( temp , " -ms2" );
	break;
    }
    ReplaceChar( &OptLine , temp );
}


/****************************************************************************
***									  ***
***	Actions des boutons de la fenêtre DirSet			  ***
***									  ***
****************************************************************************/

char *SSource,*SDest,*SInclude,*SLib,*SObj,*SDICE,*SEdit;

void ProjectCloseDirSet( BOOL use ) {
    if ( DirSetWnd ) {
	RemWinC( DirSetWnd );
	CloseDirSetWindow( );
	if ( !use ) {
	    ReplaceChar( &SourceDir , SSource );
	    ReplaceChar( &DestDir , SDest );
	    ReplaceChar( &IncludeDir , SInclude );
	    ReplaceChar( &LibDir , SLib );
	    ReplaceChar( &ObjDir , SObj );
	    ReplaceChar( &DICEDir , SDICE );
	    ReplaceChar( &Editor , SEdit );
	} else {
	    if ( strcmp( SSource , SourceDir ) || strcmp( SDest , DestDir ) ||
		    strcmp( SInclude , IncludeDir ) || strcmp( SLib , LibDir ) ||
		    strcmp( SEdit , Editor ) ||
		    strcmp( SObj , ObjDir ) || strcmp( SDICE , DICEDir ) )
	    {
		saved = FALSE;
		RemoveAssign( );
		MakeAssign( );
		UpdateNameList( );
	    }
	}
	free( SSource );
	free( SDest );
	free( SInclude );
	free( SLib );
	free( SObj );
	free( SDICE );
	free( SEdit );
    }
}

int DirSetUseClicked( void ) {
    ProjectCloseDirSet( TRUE );
}

int DirSetCancelClicked( void ) {
    ProjectCloseDirSet( FALSE );
}

int SourceClicked( void )
{
  struct FileRequester *fr;
  struct ModuleNode *wn=ModuleList->lh_Head;

    if (fr = AskDirectory( "Select sources path" , SourceDir )) {
	ReplaceChar( &SourceDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[6] , DirSetWnd , NULL , GTTX_Text , (long)SourceDir , TAG_DONE );
    }
}

int DestClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select destination path" , DestDir )) {
	ReplaceChar( &DestDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[7] , DirSetWnd , NULL , GTTX_Text , (long)DestDir , TAG_DONE );
    }
}

int IncludeClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select includes path" , IncludeDir )) {
	ReplaceChar( &IncludeDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[8] , DirSetWnd , NULL , GTTX_Text , (long)IncludeDir , TAG_DONE );
    }
}

int LibClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select libraries path" , LibDir )) {
	ReplaceChar( &LibDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[9] , DirSetWnd , NULL , GTTX_Text , (long)LibDir , TAG_DONE );
    }
}

int ObjClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select objects path" , ObjDir )) {
	ReplaceChar( &ObjDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[10] , DirSetWnd , NULL , GTTX_Text , (long)ObjDir , TAG_DONE );
    }
}

int PrgClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select objects path" , DICEDir )) {
	ChangeDICEDir( fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[11] , DirSetWnd , NULL , GTTX_Text , (long)DICEDir , TAG_DONE );
    }
}

int AutoDocClicked( void )
{
  struct FileRequester *fr;

    if (fr = AskDirectory( "Select Autodocs path" , DICEDir )) {
	ReplaceChar( &AutoDir , fr->rf_Dir );
	FreeAslRequest(fr);
	GT_SetGadgetAttrs( DirSetGadgets[13] , DirSetWnd , NULL , GTTX_Text , (long)AutoDir , TAG_DONE );
    }
}

/****************************************************************************
***									  ***
***	Action des boutons de la fenêtre d'options de compilation         ***
***									  ***
****************************************************************************/

int ProjectCloseCompilerOpt( BOOL use ) {
    if ( CompilerWnd ) {
	if ( use ) {
	    if ( memcmp( &Config , &Config2 , sizeof( struct CompilerOpts ) ) ) {
		saved = FALSE;
		compilall = compil = TRUE;
		memcpy( &Config , &Config2 , sizeof( struct CompilerOpts ) );
		MakeOptions( );
	    }
	}
	RemWinC( CompilerWnd );
	CloseCompilerWindow( );
    }
}

void ProjectCloseLinkerOpt( BOOL use ) {
    if ( LinkerWnd ) {
	RemWinC( LinkerWnd );
	CloseLinkerWindow( );
	if ( use ) {
	    if ( memcmp( &Config , &Config2 , sizeof( struct CompilerOpts ) ) ) {
		saved = FALSE;
		link = TRUE;
		memcpy( &Config , &Config2 , sizeof( struct CompilerOpts ) );
		MakeOptions( );
	    }
	}
    }
}

int CompilerUseClicked( void ) {
    ProjectCloseCompilerOpt( TRUE );
}

int CompilerCancelClicked( void ) {
    ProjectCloseCompilerOpt( FALSE );
}

int LinkerUseClicked( void ) {
    ProjectCloseLinkerOpt( TRUE );
}

int LinkerCancelClicked( void ) {
    ProjectCloseLinkerOpt( FALSE );
}

int RelocHunkClicked( void )
{
    if ( LinkerGadgets[3]->Flags & GFLG_SELECTED )
	Config2.Hunk = TRUE;
    else
	Config2.Hunk = FALSE;
}

int ResidentClicked( void )
{
    if ( CompilerGadgets[9]->Flags & GFLG_SELECTED )
	Config2.Resident = TRUE;
    else
	Config2.Resident = FALSE;
}

int DebugIClicked( void )
{
    if ( LinkerGadgets[4]->Flags & GFLG_SELECTED )
	Config2.DebugI = TRUE;
    else
	Config2.DebugI = FALSE;
}

int DebugLClicked( void )
{
    if ( CompilerGadgets[11]->Flags & GFLG_SELECTED )
	Config2.DebugL = TRUE;
    else
	Config2.DebugL = FALSE;
}

int DynamicClicked( void )
{
    if ( CompilerGadgets[10]->Flags & GFLG_SELECTED )
	Config2.DStack = TRUE;
    else
	Config2.DStack = FALSE;
}

int ChipClicked( void )
{
    if ( LinkerGadgets[2]->Flags & GFLG_SELECTED )
	Config2.Chip = TRUE;
    else
	Config2.Chip = FALSE;
}

int CPUClicked( void )
{
    Config2.CPU = CompilerMsg.Code;
}

int FPUClicked( void )
{
    Config2.FPU = CompilerMsg.Code;
}

int DataClicked( void )
{
    Config2.Data = CompilerMsg.Code;
}

int CodeClicked( void )
{
    Config2.Code = CompilerMsg.Code;
}

int CallsClicked( void )
{
    Config2.RCalls = CompilerMsg.Code;
}

int InlineClicked( void )
{
    if ( CompilerGadgets[6]->Flags & GFLG_SELECTED )
	Config2.ICalls = TRUE;
    else
	Config2.ICalls = FALSE;
}

int HunkCodeClicked( void )
{
    Config2.HunkCode = CompilerMsg.Code;
}

int Gadget70Clicked( void )
{
    if ( CompilerGadgets[7]->Flags & GFLG_SELECTED )
	Config2.CPP = TRUE;
    else
	Config2.CPP = FALSE;
}

int ProtoClicked( void )
{
    if ( CompilerGadgets[8]->Flags & GFLG_SELECTED )
	Config2.Proto = TRUE;
    else
	Config2.Proto = FALSE;
}

int ProfileClicked( void )
{
    Config2.Prof = CompilerMsg.Code;
}

int FragmentClicked( void )
{
    if ( LinkerGadgets[5]->Flags & GFLG_SELECTED )
	Config2.Frag = TRUE;
    else
	Config2.Frag = FALSE;
}

int UnixLibClicked( void )
{
    if ( LinkerGadgets[6]->Flags & GFLG_SELECTED )
	Config2.Unix = TRUE;
    else
	Config2.Unix = FALSE;
}



/****************************************************************************
***									  ***
***	Gestion de la fenêtre Main Options				  ***
***									  ***
****************************************************************************/

void ProjectCloseGenOpt( BOOL use ) {
    if ( GenOptWnd ) {
	RemWinC( GenOptWnd );
	CloseGenOptWindow( );
	if ( use )
	{
	    if ( memcmp( &Config , &Config2 , sizeof( struct CompilerOpts ) ) ) {
		saved = FALSE;
		compilall = TRUE;
		link = TRUE;
		memcpy( &Config , &Config2 , sizeof( struct CompilerOpts ) );
		MakeOptions();
		RemoveAssign( );
		MakeAssign( );
	    }
	}
    }
}

int GenTypeClicked( void )
{
    Config2.ObjType = GenOptMsg.Code;
}

int VerClicked( void )
{
    Config2.Version[0] = GenOptMsg.Code+'0';
}

int RevClicked( void )
{
    Config2.Version[2] = GenOptMsg.Code+'0';
}

int GenOptUseClicked( void )
{
    ProjectCloseGenOpt( TRUE );
}

int GenOptCancelClicked( void )
{
    ProjectCloseGenOpt( FALSE );
}

int GenOptVanillaKey( void )
{
    switch( GenOptMsg.Code )
    {
      case 't':
      case 'T':
	if ( isupper( GenOptMsg.Code ) )
	    Config2.ObjType --;
	else
	    Config2.ObjType ++;
	if ( Config2.ObjType <0 )
	    Config2.ObjType = 2;
	if ( Config2.ObjType >2 )
	    Config2.ObjType = 0;
	GT_SetGadgetAttrs( GenOptGadgets[0] , GenOptWnd , NULL , GTCY_Active , Config2.ObjType , TAG_DONE );
	break;
      case 'v':
      case 'V':
	if ( isupper( (int)GenOptMsg.Code ) )
	{
	    if ( Config2.Version[0] > '0' )
		Config2.Version[0] --;
	}
	else
	{
	    if ( Config2.Version[0] < '9' )
		Config2.Version[0] ++;
	}
	GT_SetGadgetAttrs( GenOptGadgets[1] , GenOptWnd , NULL , GTSL_Level , Config2.Version[0]-'0' , TAG_DONE );
	break;
      case 'R':
      case 'r':
	if ( isupper( (int)GenOptMsg.Code ) )
	{
	    if ( Config2.Version[2] > '0' )
		Config2.Version[2] --;
	}
	else
	{
	    if ( Config2.Version[2] < '9' )
		Config2.Version[2] ++;
	}
	GT_SetGadgetAttrs( GenOptGadgets[2] , GenOptWnd , NULL , GTSL_Level , Config2.Version[2]-'0' , TAG_DONE );
	break;
      case 'u':
      case 'U':
	ProjectCloseGenOpt( TRUE );
	break;
      case 'a':
      case 'A':
	ProjectCloseGenOpt( FALSE );
	break;
    }
}

int ProjectMainOpt( void )
{
    if ( !GenOptWnd ) {
	if ( !OpenGenOptWindow( ) ) {
	    GT_SetGadgetAttrs( GenOptGadgets[0] , GenOptWnd , NULL , GTCY_Active , Config.ObjType , TAG_DONE );
	    GT_SetGadgetAttrs( GenOptGadgets[1] , GenOptWnd , NULL , GTSL_Level , Config.Version[0]-'0' , TAG_DONE );
	    GT_SetGadgetAttrs( GenOptGadgets[2] , GenOptWnd , NULL , GTSL_Level , Config.Version[2]-'0' , TAG_DONE );
	    memcpy( &Config2 , &Config , sizeof( struct CompilerOpts ) );
	    AddWinC( GenOptWnd , HandleGenOptIDCMP );
	}
    } else {
	WindowToFront( GenOptWnd );
	ActivateWindow( GenOptWnd );
    }
}

/****************************************************************************
***									  ***
***	Gestion de la fenêtre DirSet					  ***
***									  ***
****************************************************************************/

int ProjectDirectory( void )
{
    if ( !DirSetWnd ) {
	SSource = strdup( SourceDir );
	SDest = strdup( DestDir );
	SInclude = strdup( IncludeDir );
	SLib = strdup( LibDir );
	SObj = strdup( ObjDir );
	SDICE = strdup( DICEDir );
	SEdit = strdup( Editor );
	if ( !OpenDirSetWindow( ) ) {
	    GT_SetGadgetAttrs( DirSetGadgets[6] , DirSetWnd , NULL , GTTX_Text , (long)SourceDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[7] , DirSetWnd , NULL , GTTX_Text , (long)DestDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[8] , DirSetWnd , NULL , GTTX_Text , (long)IncludeDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[9] , DirSetWnd , NULL , GTTX_Text , (long)LibDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[10] , DirSetWnd , NULL , GTTX_Text , (long)ObjDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[11] , DirSetWnd , NULL , GTTX_Text , (long)DICEDir , TAG_DONE );
	    GT_SetGadgetAttrs( DirSetGadgets[13] , DirSetWnd , NULL , GTTX_Text , (long)AutoDir , TAG_DONE );
	    AddWinC( DirSetWnd , HandleDirSetIDCMP );
	}
    } else {
	WindowToFront( DirSetWnd );
	ActivateWindow( DirSetWnd );
    }
}

/****************************************************************************
***									  ***
***	Gestion de la fenêtre Compiler Options				  ***
***									  ***
****************************************************************************/

int ProjectCompilerOpt( void )
{
    if ( !CompilerWnd ) {
	if ( !OpenCompilerWindow( ) ) {
	    memcpy( &Config2 , &Config , sizeof( struct CompilerOpts ) );
	    GT_SetGadgetAttrs( CompilerGadgets[0] , CompilerWnd , NULL , GTMX_Active , (long)Config2.CPU , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[1] , CompilerWnd , NULL , GTMX_Active , (long)Config2.FPU , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[2] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Code , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[3] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Data , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[4] , CompilerWnd , NULL , GTMX_Active , (long)Config2.RCalls , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[5] , CompilerWnd , NULL , GTMX_Active , (long)Config2.HunkCode , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[6] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.ICalls , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[7] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.CPP , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[8] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.Proto , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[9] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.Resident , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[10] ,CompilerWnd , NULL , GTCB_Checked , (long)Config2.DStack , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[11] ,CompilerWnd , NULL , GTCB_Checked , (long)Config2.DebugL , TAG_DONE );
	    GT_SetGadgetAttrs( CompilerGadgets[12] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Prof , TAG_DONE );
	    AddWinC( CompilerWnd , HandleCompilerIDCMP );
	}
    } else {
	WindowToFront( CompilerWnd );
	ActivateWindow( CompilerWnd );
    }
}

int CompilerVanillaKey( long code ) {
    switch( code ) {
	case 'U':
	case 'u':
	    CompilerUseClicked();
	    break;
	case 'a':
	case 'A':
	    CompilerCancelClicked();
	    break;
	case '0':
	case '2':
	case '3':
	    code -= '0';
	    if ( code )
		code--;
	    Config2.CPU = code;
	    GT_SetGadgetAttrs( CompilerGadgets[0] , CompilerWnd , NULL , GTMX_Active , (long)Config2.CPU , TAG_DONE );
	    break;
	case 'n':
	case 'N':
	    code = '5';
	case '6':
	    code -= '5';
	case '8':
	    if ( code > 1 )
		code = 2;
	    Config2.FPU = code;
	    GT_SetGadgetAttrs( CompilerGadgets[1] , CompilerWnd , NULL , GTMX_Active , (long)Config2.FPU , TAG_DONE );
	    break;
	case 's':
	case 'S':
	    code = 'k';
	case 'L':
	case 'l':
	    Config2.Code = tolower(code) - 'k';
	    GT_SetGadgetAttrs( CompilerGadgets[2] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Code , TAG_DONE );
	    break;
	case 'M':
	case 'm':
	    code = 'e' - 1;
	case 'e':
	case 'E':
	    Config2.Data = tolower( code ) - 'e' + 1;
	    GT_SetGadgetAttrs( CompilerGadgets[3] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Data , TAG_DONE );
	    break;
	case 'r':
	case 'R':
	    code = 's';
	case 't':
	case 'T':
	    Config2.RCalls = tolower( code ) - 's';
	    GT_SetGadgetAttrs( CompilerGadgets[4] , CompilerWnd , NULL , GTMX_Active , (long)Config2.RCalls , TAG_DONE );
	    break;
	case 'o':
	case 'O':
	    code = 'g';
	case 'h':
	case 'H':
	    code = tolower(code) - 'g';
	case 'P':
	case 'p':
	    if ( code > 1 )
		code = 2;
	    Config2.HunkCode = code;
	    GT_SetGadgetAttrs( CompilerGadgets[5] , CompilerWnd , NULL , GTMX_Active , (long)Config2.HunkCode , TAG_DONE );
	    break;
	case 'i':
	case 'I':
	    Config2.ICalls = 1 - Config2.ICalls ;
	    GT_SetGadgetAttrs( CompilerGadgets[6] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.ICalls , TAG_DONE );
	    break;
	case '+':
	    Config2.CPP = 1 - Config2.CPP ;
	    GT_SetGadgetAttrs( CompilerGadgets[7] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.CPP , TAG_DONE );
	    break;
	case 'f':
	case 'F':
	    Config2.Proto = 1 - Config2.Proto ;
	    GT_SetGadgetAttrs( CompilerGadgets[8] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.Proto , TAG_DONE );
	    break;
	case 'c':
	case 'C':
	    Config2.Resident = 1 - Config2.Resident ;
	    GT_SetGadgetAttrs( CompilerGadgets[9] , CompilerWnd , NULL , GTCB_Checked , (long)Config2.Resident , TAG_DONE );
	    break;
	case 'd':
	case 'D':
	    Config2.DStack = 1 - Config2.DStack ;
	    GT_SetGadgetAttrs( CompilerGadgets[10] ,CompilerWnd , NULL , GTCB_Checked , (long)Config2.DStack , TAG_DONE );
	    break;
	case '1':
	    Config2.DebugL = 1 - Config2.DebugL;
	    GT_SetGadgetAttrs( CompilerGadgets[11] ,CompilerWnd , NULL , GTCB_Checked , (long)Config2.DebugL , TAG_DONE );
	    break;
	case 'g':
	case 'G':
	    code = 'x';
	case 'y':
	case 'Y':
	    code = tolower( code ) - 'x';
	case 'b':
	case 'B':
	    if ( code > 1 )
		code = 2;
	    Config2.Prof = code;
	    GT_SetGadgetAttrs( CompilerGadgets[12] , CompilerWnd , NULL , GTMX_Active , (long)Config2.Prof , TAG_DONE );
	    break;
    }
}

/****************************************************************************
***									  ***
***	Gestion de la fenêtre Linker Options				  ***
***									  ***
****************************************************************************/

int ProjectLinkerOpt( void ) {
    if ( !LinkerWnd ) {
	if ( !OpenLinkerWindow( ) ) {
	    memcpy( &Config2 , &Config , sizeof( struct CompilerOpts ) );
	    GT_SetGadgetAttrs( LinkerGadgets[2] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Chip , TAG_DONE );
	    GT_SetGadgetAttrs( LinkerGadgets[3] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Hunk , TAG_DONE );
	    GT_SetGadgetAttrs( LinkerGadgets[4] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.DebugI , TAG_DONE );
	    GT_SetGadgetAttrs( LinkerGadgets[5] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Frag , TAG_DONE );
	    GT_SetGadgetAttrs( LinkerGadgets[6] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Unix , TAG_DONE );
	    AddWinC( LinkerWnd , HandleLinkerIDCMP );
	}
    } else {
	WindowToFront( LinkerWnd );
	ActivateWindow( LinkerWnd );
    }
}

int LinkerVanillaKey( long code ) {
    switch( code ) {
	case 'U':
	case 'u':
	    LinkerUseClicked();
	    break;
	case 'a':
	case 'A':
	    LinkerCancelClicked();
	    break;
	case 'I':
	case 'i':
	    Config2.Chip = 1-Config2.Chip;
	    GT_SetGadgetAttrs( LinkerGadgets[2] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Chip , TAG_DONE );
	    break;
	case 'H':
	case 'h':
	    Config2.Hunk = 1-Config2.Hunk;
	    GT_SetGadgetAttrs( LinkerGadgets[3] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Hunk , TAG_DONE );
	    break;
	case 'd':
	case 'D':
	    Config2.DebugI = 1-Config2.DebugI;
	    GT_SetGadgetAttrs( LinkerGadgets[4] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.DebugI , TAG_DONE );
	    break;
	case 'F':
	case 'f':
	    Config2.Frag = 1-Config2.Frag;
	    GT_SetGadgetAttrs( LinkerGadgets[5] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Frag , TAG_DONE );
	    break;
	case 'l':
	case 'L':
	    Config2.Unix = 1-Config2.Unix;
	    GT_SetGadgetAttrs( LinkerGadgets[6] , LinkerWnd , NULL , GTCB_Checked , (long)Config2.Unix , TAG_DONE );
	    break;
    }
}

/****************************************************************************
***									  ***
***	Gestion de la fenêtre Screen Options				  ***
***									  ***
****************************************************************************/

int ProjectScreenOpt( void )
{
    ScreenPrefs( ScreenTags );
}

/****************************************************************************
***									  ***
***	Gestion de la fenêtre Editor Options				  ***
***									  ***
****************************************************************************/

int ProjectEditorOpt( void ) {
  struct FileRequester *fr;
  char *name;

    if ( fr = AskFile( Editor , "Select editor executable" , "" ) ) {
	name = PathName( fr->rf_Dir , fr->rf_File );
	ReplaceChar( &Editor , name );
	free( name );
	FreeAslRequest(fr);
    }
}

/****************************************************************************
***									  ***
***	Actions pour lire et ecrire les options 			  ***
***									  ***
****************************************************************************/

BOOL LoadOptions( struct IFFHandle *iff ) {
struct StoredProperty *buf;
char *data;

    PropChunk( iff , ID_PREF , ID_COPT );
    PropChunk( iff , ID_PREF , ID_DIRS );
    PropChunk( iff , ID_PREF , ID_WPOS );
    PropChunk( iff , ID_PREF , ID_LOPT );
    StopOnExit( iff , ID_PREF , ID_FORM );

    LoadScreenTags( iff );

    ParseIFF( iff , IFFPARSE_SCAN );
    if ( buf = FindProp( iff , ID_PREF , ID_DIRS ) ) {
	data = (char *)buf->sp_Data;
	ChangeDICEDir( data );
	data += strlen(data)+1;
	ReplaceChar( &SourceDir , data );
	data += strlen(data)+1;
	ReplaceChar( &DestDir , data );
	data += strlen(data)+1;
	ReplaceChar( &IncludeDir , data );
	data += strlen(data)+1;
	ReplaceChar( &LibDir , data );
	data += strlen(data)+1;
	ReplaceChar( &ObjDir , data );
	data += strlen(data)+1;
	ReplaceChar( &Editor , data );
	data += strlen(data)+1;
	if ( data < (char *)buf->sp_Data + buf->sp_Size )
	    ReplaceChar( &AutoDir , data );
    } else {
	Message( StrMessages[ MSG_MESSAGE_CANT_OPTION ] , StrMessages[MSG_MESSAGE_CONTINUE] );
	return( FALSE );
    }
    if ( buf = FindProp( iff , ID_PREF , ID_WPOS ) ) {
	ProjectTop = ((UWORD *)buf->sp_Data)[0];
	ProjectLeft = ((UWORD *)buf->sp_Data)[1];
	ProjectWidth = ((UWORD *)buf->sp_Data)[2];
	ProjectHeight = ((UWORD *)buf->sp_Data)[3];
	MessTop = ((UWORD *)buf->sp_Data)[4];
	MessLeft = ((UWORD *)buf->sp_Data)[5];
	MessWidth = ((UWORD *)buf->sp_Data)[6];
	MessHeight = ((UWORD *)buf->sp_Data)[7];
    }
    if ( buf = FindProp( iff , ID_PREF , ID_COPT ) ) {
	memcpy( &Config , buf->sp_Data , buf->sp_Size );
	MakeOptions( );
    }
    if ( buf = FindProp( iff , ID_PREF , ID_LOPT ) ) {
	ReplaceChar( &ParmsLine , buf->sp_Data );
    }
    RemoveAssign( );
    MakeAssign( );
    return( TRUE );
}

void SaveOptions( struct IFFHandle *iff ) {
    PushChunk( iff , ID_PREF , ID_FORM , IFFSIZE_UNKNOWN );

    SaveScreenTags( iff );

    PushChunk( iff , ID_PREF , ID_COPT , IFFSIZE_UNKNOWN );
    WriteChunkBytes( iff , &Config , sizeof(struct CompilerOpts) );
    PopChunk( iff );

    PushChunk( iff , ID_PREF , ID_LOPT , strlen( ParmsLine )+1 );
    WriteChunkBytes( iff , ParmsLine , strlen( ParmsLine ) + 1 );
    PopChunk( iff );

    PushChunk( iff , ID_PREF , ID_DIRS , IFFSIZE_UNKNOWN );
    WriteChunkBytes( iff , DICEDir , strlen(DICEDir)+1 );
    WriteChunkBytes( iff , SourceDir , strlen(SourceDir)+1 );
    WriteChunkBytes( iff , DestDir , strlen(DestDir)+1 );
    WriteChunkBytes( iff , IncludeDir , strlen(IncludeDir)+1 );
    WriteChunkBytes( iff , LibDir , strlen(LibDir)+1 );
    WriteChunkBytes( iff , ObjDir , strlen(ObjDir)+1 );
    WriteChunkBytes( iff , Editor , strlen(Editor)+1 );
    WriteChunkBytes( iff , AutoDir , strlen(AutoDir)+1 );
    PopChunk( iff );

    PushChunk( iff , ID_PREF , ID_WPOS , 16 );
    WriteChunkBytes( iff , &ProjectTop , 2 );
    WriteChunkBytes( iff , &ProjectLeft , 2 );
    WriteChunkBytes( iff , &ProjectWidth , 2 );
    WriteChunkBytes( iff , &ProjectHeight , 2 );
    WriteChunkBytes( iff , &MessTop , 2 );
    WriteChunkBytes( iff , &MessLeft , 2 );
    WriteChunkBytes( iff , &MessWidth , 2 );
    WriteChunkBytes( iff , &MessHeight , 2 );
    PopChunk( iff );

    PopChunk( iff );
}

void LoadPrefs( void )
{
  struct IFFHandle *iff;

    if ( iff = OpenIffFile( "ENV:project.prefs" , MODE_OLDFILE ) ) {
	LoadOptions( iff );
	CloseIffFile( iff );
    }
}

void SavePrefs( void )
{
  struct IFFHandle *iff;

    if ( iff = OpenIffFile( "ENVARC:project.prefs" , MODE_NEWFILE ) ) {
	SaveOptions( iff );
	CloseIffFile( iff );
    }
    if ( iff = OpenIffFile( "ENV:project.prefs" , MODE_NEWFILE ) ) {
	SaveOptions( iff );
	CloseIffFile( iff );
    }
}

