/* This file contains empty template routines that
 * the IDCMP handler will call uppon. Fill out these
 * routines with your code or use them as a reference
 * to create your program.
 */

#include <exec/types.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/nodes.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 <libraries/asl.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <dos/datetime.h>
#include <dos/dostags.h>
#include <dos/dos.h>

#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/asl_protos.h>
#include <clib/intuition_protos.h>
#include <clib/icon_protos.h>
#include <clib/wb_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>

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

#include "project.h"

/*  Variables global de status	*/

BOOL done=FALSE;
BOOL named = FALSE;
BOOL saved = TRUE;

struct List *ModuleList;

struct ModuleNode *CurrentModule;

/*  Variables du menu options	*/

struct TagItem gtag[] = { GTLV_Labels , 0 , 0 };

struct TagItem ttag[] = { GTTX_Text , 0 , 0 };

/****************************************************************************
***									  ***
***	Gestion de la liste des modules 				  ***
***									  ***
****************************************************************************/

/****************************************************************
***	Liste des modules au niveau de GadTools 	      ***
****************************************************************/

void DettachList( void ) {
    gtag[0].ti_Data = 0;
    GT_SetGadgetAttrsA( ProjectGadgets[0] , ProjectWnd , NULL , gtag );
}

void AttachList( void ) {
    gtag[0].ti_Data = (long)ModuleList;
    GT_SetGadgetAttrsA( ProjectGadgets[0] , ProjectWnd , NULL , gtag );
}

/****************************************************************
***	Creation du nom devant ętre affiché dans la liste     ***
****************************************************************/

void MakeRealNameList( struct ModuleNode *mn ) {
  char *name,*objfile;
  struct FileInfoBlock fib;
  char size[10];

    if ( stricmp( mn->directory , SourceDir ) )
	name = mn->pathfile;
    else
	name = mn->filename;
    mn->namelist = malloc( strlen(name) + 20 );
    *mn->namelist = 0;
    if ( mn->type=='c' && GetInfo( &fib , mn->pathfile ) ) {
	ltoa( size , fib.fib_Size );
	while( strlen( mn->namelist ) + strlen( size ) < 6 )
	    strcat( mn->namelist , " " );
	strcat( mn->namelist , size );
    } else
	strcat( mn->namelist , "  --  " );
    if ( mn->type == 'c' ) {
	objfile = PathName( ObjDir , mn->filename );
	MakeObject( objfile );
    } else
	objfile = strdup( mn->pathfile );
    if ( GetInfo( &fib , objfile ) ) {
	ltoa( size , fib.fib_Size );
	while( strlen( mn->namelist ) + strlen( size ) < 13 )
	    strcat( mn->namelist , " " );
	strcat( mn->namelist , size );
    } else
	strcat( mn->namelist , "   --  " );
    free( objfile );
    if ( IsCommented( mn->pathfile ) )
	strcat( mn->namelist , "  * " );
    else
	strcat( mn->namelist , "    " );
    strcat( mn->namelist , name );
    mn->node.ln_Name = mn->namelist;
    mn->name = &mn->namelist[17];
}

/****************************************************************
***	Mise ŕ jour des noms apparaissant dans la liste       ***
****************************************************************/

void UpdateNameList( void ) {
  struct ModuleNode *mn=ModuleList->lh_Head;

    DettachList( );
    while( mn->node.ln_Succ ) {
	MakeRealNameList( mn );
	mn = mn->node.ln_Succ;
    }
    AttachList( );
}

/****************************************************************
***	Liste des modules dans le chainage d'Exec             ***
****************************************************************/

BOOL FindName2( char *search ) {
  struct ModuleNode *wn=ModuleList->lh_Head;

    while( wn->node.ln_Succ ) {
	if ( !stricmp( wn->name , search ) )
	    return( TRUE );
	wn = wn->node.ln_Succ;
    }
    return( FALSE );
}

struct ModuleNode *AddModuleNode( struct List *list , char *name , char *directory ) {
  struct ModuleNode *wn;
  struct ModuleNode *bn = list->lh_TailPred;
  int r;
  char *t;

    if ( (wn = malloc( sizeof(struct ModuleNode) )) ) {
	if ( !strchr( directory , ':' ) )
	    wn->directory = PathName( SourceDir , directory );
	else
	    wn->directory = strdup( directory );
	wn->pathfile = PathName( wn->directory , name );
	wn->filename = BaseName( wn->pathfile );
	r = stricmp( wn->directory , SourceDir );
	if ( (r && FindName2( wn->pathfile )) ||
			    (!r && FindName2( wn->filename )) ) {
	    free( wn->directory );
	    free( wn->pathfile );
	    free( wn );
	    return;
	}
	wn->node.ln_Type = MODULE_NODE;
	if ( t = strchr( wn->filename , '.' ) )
	    wn->type = tolower( t[1] );
	else
	    wn->type = 0;
	if ( list == ModuleList ) {
	    saved = FALSE;
	    MakeRealNameList( wn );
	} else
	    wn->node.ln_Name = wn->namelist = wn->name = strdup( wn->filename );

	while( (struct List *)bn!=list && stricmp( wn->name , bn->name ) < 0 )
	    bn = bn->node.ln_Pred;
	if ( (struct List *)bn!=list )
	    Insert( list , (struct Node *)wn , (struct Node *)bn );
	else
	    AddHead( list , (struct Node *)wn );
	return( wn );
    }
    return( NULL );
}

/****************************************************************
***	Detruit un module dans une liste		      ***
****************************************************************/

void RemModuleNode( struct ModuleNode *wn ) {

    free( wn->directory );
    free( wn->pathfile );
    free( wn->namelist );
    Remove( (struct Node *)wn );
    free( wn );
}

/****************************************************************
***	Detruit tous les modules d'une list                   ***
****************************************************************/

void FreeModuleNodes( struct List *list ) {
  struct ModuleNode *wn,*nn;

    wn = list->lh_Head;
    while( wn->node.ln_Succ ) {
	nn = wn->node.ln_Succ;
	RemModuleNode( wn );
	wn = nn;
    }
}

/****************************************************************
***	Detruit une liste ainsi que ses modules 	      ***
****************************************************************/

void FreeList( struct List *list ) {
    FreeModuleNodes( list );
    free( list );
}

/****************************************************************
***	Genere une liste des fichiers include		      ***
****************************************************************/

void AddIncludeList( struct List *list , struct ModuleNode *wn ) {
  FILE *in;
  char temp[500];

    if ( wn ) {
	if ( in = fopen( wn->pathfile , "r" ) ) {
	    while( !feof( in ) ) {
		fgets( temp , 500 , in );
		if ( !strnicmp( temp , "#include \"" , 10 ) ) {
		    temp[ strlen(temp) - 2 ] = 0;
		    AddIncludeList( list , AddModuleNode( list , &temp[10] , wn->directory ) );
		}
	    }
	    fclose( in );
	}
    }
}

struct List *BuildIncludeList( struct ModuleNode *wn ) {
  struct List *build;

    if ( build = malloc( sizeof( struct List ) ) ) {
	NewList( build );
	AddIncludeList( build , wn );
	return( build );
    }
    return( NULL );
}

/****************************************************************************
***									  ***
***	Initialisation / Liberation des variables globales		  ***
***									  ***
****************************************************************************/

int InitVar( void ) {
    ModuleList = malloc( sizeof( struct List ) );
    if ( !ModuleList )
	return( FALSE );
    NewList( ModuleList );

    SourceDir = getcwd( NULL , 500 );
    DestDir = strdup( SourceDir );
    IncludeDir = strdup( "Work:DICE/include" );
    LibDir = strdup( "Work:DICE/dlib" );
    ObjDir = strdup( SourceDir );
    PrgDir = strdup( "Work:DICE/bin/" );
    DICEDir = strdup( "Work:DICE" );
    MakeAssign( );
    ProjectPathName = strdup( "No Name" );
    ProjectName = strdup( "No Name" );
    WindowTitle = strdup( "Project Handler : No Name" );
    StartDir = getcwd( NULL , 500 );
    OptFile = strdup( "Env:project.prefs" );
    OptLine = strdup( "" );
    MakeOptions( );
    CurrentModule = NULL;
    return( TRUE );
}

void FreeVar( void ) {
    FreeList( ModuleList );
    RemoveAssign( );
    free( DICEDir );
    free( SourceDir );
    free( DestDir );
    free( IncludeDir );
    free( LibDir );
    free( ObjDir );
    free( PrgDir );
    free( ProjectPathName );
    free( ProjectName );
    free( WindowTitle );
    free( StartDir );
    free( OptFile );
    free( OptLine );
}


/****************************************************************************
***									  ***
***	Lecture des tooltypes de l'icone du programme                     ***
***									  ***
****************************************************************************/

void GetToolTypes( struct WBStartup *WBStart ) {
  struct WBArg *WBArg = WBStart->sm_ArgList;
  struct DiskObject *dobj;
  char **tt,*s;

    ProgramName = WBArg->wa_Name;
    if ( dobj = GetDiskObject( WBArg->wa_Name ) ) {
	tt = (char **)dobj->do_ToolTypes;
	if( s=(char *)FindToolType(tt,"TOPEDGE" ) )
	    ProjectTop = (UWORD)atol(s);
	if( s=(char *)FindToolType(tt,"LEFTEDGE" ) )
	    ProjectLeft = (UWORD)atol(s);
	if( s=(char *)FindToolType(tt,"WIDTH" ) ) {
	    ProjectWidth = (UWORD)atol(s);
	    ProjectWidth -= OffX + Scr->WBorRight;
	}
	if( s=(char *)FindToolType(tt,"HEIGHT" ) ) {
	    ProjectHeight = (UWORD)atol(s);
	    ProjectHeight -= OffY + Scr->WBorBottom;
	}
	if( s=(char *)FindToolType(tt,"MTOPEDGE" ) )
	    MessTop = (UWORD)atol(s);
	if( s=(char *)FindToolType(tt,"MLEFTEDGE" ) )
	    MessLeft = (UWORD)atol(s);
	if( s=(char *)FindToolType(tt,"MWIDTH" ) ) {
	    MessWidth = (UWORD)atol(s);
	    MessWidth -= OffX + Scr->WBorRight;
	}
	if( s=(char *)FindToolType(tt,"MHEIGHT" ) ) {
	    MessHeight = (UWORD)atol(s);
	    MessHeight -= OffY + Scr->WBorBottom;
	}
	RemoveAssign( );
	MakeAssign( );
	FreeDiskObject( dobj );
    }
}


/****************************************************************************
***									  ***
***	Action des boutons ( liste ) de la fenętre principale		  ***
***									  ***
****************************************************************************/

int ModuleListClicked( void )
{
  int n = ProjectMsg.Code;
  struct ModuleNode *wn = ModuleList->lh_Head;
  static ULONG sec=-1,mic;

    while( wn->node.ln_Succ && n-- ) {
	wn = wn->node.ln_Succ;
    }
    if ( wn->node.ln_Succ )
	CurrentModule = wn;
    if ( sec != -1 && DoubleClick( sec , mic , ProjectMsg.Seconds , ProjectMsg.Micros ) )
	ProjectEdit( );
    sec = ProjectMsg.Seconds;
    mic = ProjectMsg.Micros;
}


/****************************************************************************
***									  ***
***	Actions des menus de la fenętre principale			  ***
***									  ***
****************************************************************************/

int CancelForSave( void ) {
  int r=1;

    if ( !strcmp( ProjectName , "No Name" ) )
	return( 0 );
    while ( !saved && r==1 ) {
	r = 2-Message( ProjectWnd , "Current project is not saved !\nDo you want to save it before ?" , "Save|Don't|Cancel" );
	if ( r==2 )
	    return( 1 );
	if ( r==1 )
	    ProjectSave();
    }
    return( 0 );
}

int ProjectNew( void )
{
    if ( !CancelForSave() ) {
	DettachList( );
	FreeModuleNodes( ModuleList );
	ChangeProjectName( "No Name" );
	saved = TRUE;
    }
}

int ProjectOpen( void )
{
  struct FileRequester *fr;
  char *pf,name[200],name2[200];
  FILE *fin;
  ULONG OldDispID = DisplayScreen;

    if ( !CancelForSave() )
	if ( fr = AskFile( "Select project to open" , "*.prj" ) ) {
	    pf = PathName( fr->rf_Dir , fr->rf_File );
	    if ( fin = fopen( pf , "r" ) ) {
		if ( LoadOptions( pf , fin ) && VerifPrj( pf , "%MODULES%" , fin ) ) {
		    DettachList( );
		    RemoveAssign( );
		    MakeAssign( );
		    FreeModuleNodes( ModuleList );
		    while ( !feof( fin ) ) {
			InputString( name , 200 , fin );
			InputString( name2 , 200 , fin );
			if ( feof( fin ) )
			    break;
			AddModuleNode( ModuleList , name , name2 );
		    }
		    AttachList( );
		    named = TRUE;
		    saved = TRUE;
		    ChangeProjectName( pf );
		}
		fclose( fin );
	    } else {
		strcpy( name , "Can't open project \n" );
		strcat( name , BaseName( pf ) );
		Message( ProjectWnd , name , "OK" );
	    }
	    free( pf );
	    FreeAslRequest( fr );
	    if ( OldDispID != DisplayScreen )
		UpdateScreen( );
	}
}

void SaveProject( void ) {
  FILE *fout;
  struct ModuleNode *wn = (struct Node *)ModuleList->lh_Head;

    if ( fout=fopen( ProjectPathName , "w" ) ) {
	SaveOptions( fout );
	fputs( "%MODULES%\n" , fout );
	while( wn->node.ln_Succ ) {
	    OutputString( wn->filename , fout );
	    OutputString( wn->directory , fout );
	    wn = wn->node.ln_Succ;
	}
	fclose( fout );
	saved = TRUE;
    }
}

int ProjectSaveas( void )
{
  struct FileRequester *fr;
  char *pf;

    if ( fr = AskFile( "Enter project name" , "*.prj" ) ) {
	pf = PathName( fr->rf_Dir , fr->rf_File );
	if ( Overwrite( pf ) ) {
	    ChangeProjectName( pf );
	    SaveProject( );
	    named = TRUE;
	} else
	    free( pf );
	FreeAslRequest( fr );
    }
}

int ProjectSave( void )
{
    if ( !named ) {
	ProjectSaveas( );
    }
    SaveProject( );
}

/* Iconification : Ne marche pas pour l'instant ????? */

int ProjectIcon( void )
{
/*  struct DiskObject *dobj;
  struct MsgPort    *iconport;
  struct AppIcon    *appicon;
  struct AppMessage *appmsg;

    if ( dobj = GetDiskObject( ProgramName ) ) {
	dobj->do_Type = NULL;
	if ( iconport = CreateMsgPort( ) ) {
	    MessCloseWindow( );
	    CloseProjectWindow( );
	    CloseDownScreen( );
	    if ( appicon = AddAppIconA( 0L , 0L , "DICE Project" , iconport , NULL , dobj , NULL ) ) {
		WaitPort( iconport );
		RemoveAppIcon( appicon );
	    }
	    while( appmsg=(struct AppMessage *)GetMsg( iconport ) )
		ReplyMsg( (struct Message *)appmsg );
	    DeleteMsgPort( iconport );
	    SetupScreen( );
	    OpenProjectWindow( );
	    ChangeProjectName( ProjectPathName );
	    AttachList( );
	}
	FreeDiskObject( dobj );
    }*/
}

int ProjectAbout( void )
{
    Message( ProjectWnd ,
	     "Project Handler 1.1 ( 12 mars 1993 )\n\n"
	     "© Copyright 1993 Arcad Development\n"
	     " Written using DICE C v2.06.40 by\n"
	     "         Cedric Counotte\n\n"
	     " Thanks to Jan van den Baard\n"
	     "     for GadToolsBox 37.176\n"
	    , "Continue" );
}

int ProjectQuit( void )
{
    if ( !CancelForSave() )
	done = 1;
}

int ProjectEdit( void )
{
    if ( CurrentModule ) {
	EditModule( CurrentModule->pathfile );
    }
}

int ProjectInclude( void )
{
  struct List *IncludeList;
  struct ModuleNode *include;

    if ( CurrentModule ) {
	if ( IncludeList = BuildIncludeList( CurrentModule ) ) {
	    if ( IncludeList->lh_Head->ln_Succ ) {
		include = ChooseInList( "Select module to edit :" , IncludeList );
		if ( include )
		    EditModule( include->pathfile );
	    }
	    FreeList( IncludeList );
	}
    }
}

int ProjectComment( void )
{
  struct FileInfoBlock fib;
  char *commentfile;

    if ( CurrentModule ) {
	if ( CurrentModule->filename[ strlen(CurrentModule->filename)-1 ] == 'c' ) {
	    commentfile = CommentName( CurrentModule->pathfile );
	    if ( !GetInfo( &fib , commentfile ) )
		if ( !Message( ProjectWnd , "No comments currently binded to this module !\nDo you want to create one ?" , "Create|Forget" ) ) {
		    free( commentfile );
		    return( 0 );
		}
	    EditModule( commentfile );
	    DettachList( );
	    MakeRealNameList( CurrentModule );
	    AttachList( );
	    free( commentfile );
	} else
	    Message( ProjectWnd , "Sorry, you can't bind comments on this module !" , "Continue" );
    }
}

int ProjectCommentKill( void )
{
  char *commentfile,mess[200];

    if ( CurrentModule ) {
	if ( CurrentModule->filename[ strlen(CurrentModule->filename)-1 ] == 'c' ) {
	    commentfile = CommentName( CurrentModule->pathfile );
	    if ( IsCommented( CurrentModule->pathfile ) ) {
		strcpy( mess , "Comments binded to module " );
		strcat( mess , CurrentModule->filename );
		strcat( mess , " will be erased !\nAre you sure ?" );
		if ( Message( ProjectWnd , mess , "Erase|Forget" ) ) {
		    DeleteFile( commentfile );
		    DettachList( );
		    MakeRealNameList( CurrentModule );
		    AttachList( );
		}
	    } else
		Message( ProjectWnd , "Sorry, this module don't owned any comments !" , "Continue" );
	    free( commentfile );
	} else
	    Message( ProjectWnd , "Sorry, this module can't owned any comments !" , "Continue" );
    }
}

int ProjectAdd( void )
{
  struct FileRequester *fr;

    if (fr = AskFile( "Select module to add" , "(*.c|*.o|*.lib)" )) {
	DettachList( );
	AddModuleNode( ModuleList , fr->rf_File , fr->rf_Dir );
	AttachList( );
	FreeAslRequest(fr);
    }
}

int ProjectRem( void )
{
    if ( CurrentModule ) {
	DettachList( );
	RemModuleNode( CurrentModule );
	saved = FALSE;
	AttachList( );
	CurrentModule = NULL;
    }
}

int ProjectOther( void )
{
  struct FileRequester *fr;
  char *buf;

    if ( fr = AskFile( "Select module to edit" , "(*.c|*.h)" ) ) {
	buf = PathName( fr->rf_Dir , fr->rf_File );
	EditModule( buf );
	free( buf );
	FreeAslRequest( fr );
    }
}

int CheckDependencies( struct ModuleNode *wn ) {
  char *obj;
  struct FileInfoBlock fib1,fib2;
  struct List *includes;
  BOOL ret;

    CompileRender( TXT_CHECKING );
    obj = PathName( ObjDir , wn->filename );
    MakeObject( obj );
    ret = !GetInfo( &fib1 , obj );
    free( obj );

    if ( !ret && GetInfo( &fib2 , wn->pathfile ) )
	if ( CompareDates( &fib1.fib_Date , &fib2.fib_Date ) > 0 )
	    ret = TRUE;
    if ( !ret ) {
	includes = BuildIncludeList( wn );
	wn = includes->lh_Head;
	while( wn->node.ln_Succ ) {
	    if ( GetInfo( &fib2 , wn->pathfile ) )
		if ( CompareDates( &fib1.fib_Date , &fib2.fib_Date ) > 0 )
		    ret = TRUE;
	    wn = wn->node.ln_Succ;
	}
	FreeList( includes );
    }
    CompileRender( TXT_COMPILING );
    return( ret );
}

int ProjectCompile( void )
{
  char command[500];
  struct ModuleNode *wn = ModuleList->lh_Head;
  struct IntuiMessage *m=NULL;

    KeepMessages = FALSE;
    OpenCompileWindow( TXT_COMPILING );
    while( wn->node.ln_Succ ) {
	if ( wn->type == 'c' ) {
	    ttag[0].ti_Data = wn->name;
	    GT_SetGadgetAttrsA( CompileGadgets[0] , CompileWnd , NULL , ttag );
	    if ( CheckDependencies( wn ) ) {
		strcpy( command , PrgDir );
		strcat( command , "dcc >RAM:Compiler_Error -c " );
		strcat( command , wn->pathfile );
		strcat( command , " -o " );
		strcat( command , ObjDir );
		MakePath( command );
		strcat( command , wn->filename );
		MakeObject( command );
		strcat( command , OptLine );
		strcat( command , " -E \"ram:Compiler_Errors\"" );
		if ( strlen( command )>499 )
		    Message( ProjectWnd , "Warning : Command length greater than 500 !" , "Continue" );
		DeleteFile( "RAM:Compiler_Errors" );
		DeleteFile( "RAM:Compiler_Error" );
		Launch( command , FALSE );
		if ( (m = GT_GetIMsg( CompileWnd->UserPort )) || ViewErrors( "RAM:Compiler_Errors" ) ) {
		    if ( m )
			GT_ReplyIMsg( m );
		    CloseCompileWindow( );
		    UpdateNameList( );
		    return( FALSE );
		}
	    }
	}
	wn = wn->node.ln_Succ;
    }
    CloseCompileWindow( );
    UpdateNameList( );
    return( TRUE );
}

void CreateObjList( void ) {
  struct ModuleNode *wn = ModuleList->lh_Head;
  FILE *out;
  char *buf;

    if ( out = fopen( "ram:objlist" , "w" ) ) {
	while( wn->node.ln_Succ ) {
	    buf = strdup( wn->filename );
	    if ( wn->type == 'c' )
		MakeObject( buf );
	    OutputString( buf , out );
	    free( buf );
	    wn = wn->node.ln_Succ;
	}
	fclose( out );
    }
}

int ProjectLink( void )
{
  char command[500];

    OpenCompileWindow( TXT_LINKING );
    CreateObjList( );
    chdir( ObjDir );
    strcpy( command , PrgDir );
    strcat( command , "dcc >\"RAM:Linker_Error\" @RAM:objlist -E \"RAM:Linker_Errors\" -o " );
    strcat( command , DestDir );
    MakePath( command );
    strcat( command , ProjectName );
    strcat( command , OptLine );
    if ( strlen( command )>499 )
	Message( ProjectWnd , "Warning : Command length greater than 500 !" , "Continue" );
    DeleteFile( "RAM:Linker_Errors" );
    DeleteFile( "RAM:Linker_Error" );
    Launch( command , FALSE );
    chdir( StartDir );
    ViewErrors( "RAM:Linker_Errors" );
    CloseCompileWindow( );
}

int ProjectGenerate( void )
{
  char *temp;
  struct ModuleNode *wn = ModuleList->lh_Head;

    while( wn->node.ln_Succ ) {
	temp = PathName( ObjDir , wn->filename );
	MakeObject( temp );
	DeleteFile( temp );
	free( temp );
	wn = wn->node.ln_Succ;
    }
    if ( ProjectCompile( ) )
	ProjectLink( );
}

int ProjectLibrary( void )
{
  char command[500];

    ProjectCompile( );
    OpenCompileWindow( TXT_LIBMAKING );
    CreateObjList( );
    chdir( ObjDir );
    strcpy( command , PrgDir );
    strcat( command , "libmake RAM:objlist -mRR -proto -o ram: -l " );
    strcat( command , LibDir );
    MakePath( command );
    strcat( command , ProjectName );
    strcat( command , ".lib" );
    Launch( command , FALSE );
    chdir( StartDir );
    CloseCompileWindow( );
}

int ProjectMake( void )
{
    if ( ProjectCompile( ) )
	ProjectLink( );
}

int ProjectCodeInfo( void )
{
  struct FileInfoBlock fib;
  char mess[500];
  struct DateTime *dt;

    chdir( DestDir );
    if ( GetInfo( &fib , ProjectName ) ) {
	strcpy( mess , "Project Name : " );
	strcat( mess , ProjectName );
	strcat( mess , "\n\nExecutable : " );
	ltoa( &mess[ strlen(mess) ] , fib.fib_Size );
	strcat( mess , "\n\nDate : " );
	if ( dt = GetDate( &fib ) ) {
	    strcat( mess , dt->dat_StrDay );
	    strcat( mess , " " );
	    strcat( mess , dt->dat_StrDate );
	    strcat( mess , "\nTime : " );
	    strcat( mess , dt->dat_StrTime );
	}
	strcat( mess , "\n\n" );
	Message( ProjectWnd , mess , "Continue" );
    } else
	Message( ProjectWnd , "You must generate it before !" , "Continue" );
    chdir( StartDir );
}

int ProjectLaunch( void )
{
  char *command = PathName( DestDir , ProjectName );

    Launch( command , TRUE );
    free( command );
}

int ProjectLaunchWB( void )
{

}

/****************************************************************************
***									  ***
***	Actions des messages IDCMP					  ***
***									  ***
****************************************************************************/

int ProjectCloseWindow( void )
{
    ProjectQuit( );
}

int ProjectNewSize( void )
{
    DettachList( );

    CloseProjectWindow( );
    OpenProjectWindow( );
    ChangeProjectName( ProjectPathName );

    AttachList( );
}

int DirSetCloseWindow( void )
{
    RemoveAssign( );
    MakeAssign( );
    done = TRUE;
}

int CompilerOptCloseWindow( void )
{
    done = TRUE;
}


/****************************************************************************
***									  ***
***	Programme principale comme l'on peut le constater                 ***
***									  ***
****************************************************************************/

#define winsignal(win) (1 << win->UserPort->mp_SigBit)

int main( int argc , char **argv ) {
  LONG signal;

    if ( InitVar( ) ) {
	if ( !argc )
	    GetToolTypes( (struct WBStartup *)argv );
	else
	    ProgramName = argv[0];
	LoadPrefs( );
	if ( !SetupScreen( ) ) {
	    if ( !OpenProjectWindow( ) ) {
		while ( !done ) {
		    signal = winsignal(ProjectWnd);
		    if ( MessWnd )
			signal |= winsignal(MessWnd);
		    signal = Wait( signal );
		    if ( signal==winsignal(ProjectWnd) )
			HandleProjectIDCMP( );
		    else
			HandleMessIDCMP( );
		}
		MessCloseWindow( );
		CloseProjectWindow( );
	    }
	    CloseDownScreen( );
	}
	FreeVar( );
    }
    return( 0 );
}

int wbmain( struct WBStartup *WB ) {
    main( 0 , (char **)WB );
}

