
/*
 *
 *  (c) COPYRIGHT INRIA, 1996.
 *  Please first read the full copyright statement in file COPYRIGHT.
 *
 */

/*
 * Warning:
 * This module is part of the Thot library, which was originally
 * developed in French. That's why some comments are still in
 * French, but their translation is in progress and the full module
 * will be available in English in the next release.
 * 
 */

/*
 *
 * Author: I. Vatton (INRIA)
 *
 */

#include "thot_sys.h"
#include "constmedia.h"
#include "typemedia.h"
#include "app.h"
#include "menuaction.h"
#include "logo.xpm"
#include "logo.xbm"
#include "registry.h"
#include "fileaccess.h"
#include "thotdir.h"

#undef THOT_EXPORT
#define THOT_EXPORT extern
#include "appevents_tv.h"

extern PtrEventsSet pAppli;
extern PtrSSchema   pSSchema;
extern char        *RegisteredAppEvents[];
extern PtrAppName   SchemasUsed;
extern PtrAppName   MenusUsed;
extern PtrAppName   ItemsUsed;
extern PtrAppName   ActionsUsed;
extern PtrAppMenu   MainWindowMenus;
extern PtrAppMenu   DocWindowMenus;
extern PtrAppDocType DocTypeMenus;

static FILE        *AppFile;

#include "platform_f.h"
#include "memory_f.h"

/*----------------------------------------------------------------------
   WriteIncludes writes include files 	     		        
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteIncludes (char *fname, FILE * file)
#else  /* __STDC__ */
static void         WriteIncludes (fname, file)
char               *fname;
FILE               *file;

#endif /* __STDC__ */
{
   PtrAppName          menuAction;

   fprintf (file, "/* File generated by app - do not edit! */\n");
   fprintf (file, "/* #################################### */\n");
   fprintf (file, "/* Included files */\n");
   fprintf (file, "#include \"thot_gui.h\"\n");
   fprintf (file, "#include \"thot_sys.h\"\n");
   fprintf (file, "#include \"application.h\"\n");
   fprintf (file, "#include \"app.h\"\n");
   fprintf (file, "#include \"interface.h\"\n");
   fprintf (file, "#include \"%s.h\"\n", fname);
   /* regarde s'il y a des actions de menus non standard */
   menuAction = ActionsUsed;
   while (menuAction != NULL)
      if (!menuAction->AppStandardName)
	{
	   fprintf (file, "#include \"document.h\"\n");
	   fprintf (file, "#include \"view.h\"\n");
	   menuAction = NULL;
	}
      else
	 menuAction = menuAction->AppNextName;
}


/*----------------------------------------------------------------------
   WriteAnEvent generates event/action a specific event.           
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteAnEvent (char *eventName, PtrActionEvent pactevent)
#else  /* __STDC__ */
static void         WriteAnEvent (eventName, pactevent)
char               *eventName;
PtrActionEvent      pactevent;

#endif /* __STDC__ */
{
   if (pactevent == NULL)
      return;

   WriteAnEvent (eventName, pactevent->AEvNext);
   fprintf (AppFile, "  TteAddActionEvent (appliActions, %d, %s, %d, \"%s\");\n",
	    pactevent->AEvType,
	    eventName,
	    pactevent->AEvPre,
	    pactevent->AEvAction->ActName);
}


/*----------------------------------------------------------------------
   WriteEventsList generates list of event/action.			
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteEventsList (PtrEventsSet pAppli)
#else  /* __STDC__ */
static void         WriteEventsList (pAppli)
PtrEventsSet        pAppli;

#endif /* __STDC__ */
{
   int                 event;
   char                name[50];

   fprintf (AppFile, "   /* Generate event/action entries */\n");
   strcpy (name, "Tte");
   for (event = 0; event <= TteExit; event++)
     {
	strcpy (&name[3], RegisteredAppEvents[event]);
	WriteAnEvent (name, pAppli->EvSList[event]);
     }
   fprintf (AppFile, "\n");
}

/*----------------------------------------------------------------------
   PrintSubMenu                                                    
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         PrintSubMenu (PtrAppMenuItem item, WindowType winType, char *schemaName, char *menuName)

#else  /* __STDC__ */
static void         PrintSubMenus (item, winType, schemaName, menuName)
PtrAppMenuItem      item;
WindowType          winType;
char               *schemaName;
char               *menuName;

#endif /* __STDC__ */

{
   PtrAppMenuItem      subitem;
   int                 itemsNumber;

   /* calcule le nombre d'entrees dans le sous-menu */
   subitem = item->AppSubMenu;
   itemsNumber = 0;
   while (subitem != NULL)
     {
	itemsNumber++;
	subitem = subitem->AppNextItem;
     }
   fprintf (AppFile, "  TteAddSubMenu (");
   switch (winType)
	 {
	    case MainWindow:
	       fprintf (AppFile, "MainWindow");
	       break;
	    case DocWindow:
	       fprintf (AppFile, "DocWindow");
	       break;
	    case DocTypeWindow:
	       fprintf (AppFile, "DocTypeWindow");
	       break;
	 }
   fprintf (AppFile, ", \"%s\", %s, %s, %d);\n", schemaName, menuName,
	    item->AppItemName, itemsNumber);

   /* traite la liste des items du sous-menu */
   subitem = item->AppSubMenu;
   while (subitem != NULL)
     {
	fprintf (AppFile, "    TteAddMenuItem (");
	switch (winType)
	      {
		 case MainWindow:
		    fprintf (AppFile, "MainWindow");
		    break;
		 case DocWindow:
		    fprintf (AppFile, "DocWindow");
		    break;
		 case DocTypeWindow:
		    fprintf (AppFile, "DocTypeWindow");
		    break;
	      }
	fprintf (AppFile, ", \"%s\", %s, %s", schemaName, menuName, item->AppItemName);
	if (subitem->AppItemName == NULL)
	   fprintf (AppFile, ", 0");
	else
	   fprintf (AppFile, ", %s", subitem->AppItemName);
	if (subitem->AppItemActionName == NULL)
	   fprintf (AppFile, ", NULL, '%c');\n", subitem->AppItemType);
	else
	   fprintf (AppFile, ", \"%s\", '%c');\n", subitem->AppItemActionName, subitem->AppItemType);

	/* item suivant */
	subitem = subitem->AppNextItem;
     }
}


/*----------------------------------------------------------------------
   PrintMenus                                                      
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         PrintMenus (PtrAppMenu firstMenu, WindowType winType, char *schemaName)

#else  /* __STDC__ */
static void         PrintMenus (firstMenu, winType, schemaName)
PtrAppMenu          firstMenu;
WindowType          winType;
char               *schemaName;

#endif /* __STDC__ */

{
   PtrAppMenu          menu;
   PtrAppMenuItem      item;
   int                 itemsNumber;

   if (firstMenu == NULL)
     {
	fprintf (AppFile, "  TteZeroMenu (");
	switch (winType)
	      {
		 case MainWindow:
		    fprintf (AppFile, "MainWindow");
		    break;
		 case DocWindow:
		    fprintf (AppFile, "DocWindow");
		    break;
		 case DocTypeWindow:
		    fprintf (AppFile, "DocTypeWindow");
		    break;
	      }
	fprintf (AppFile, ", \"%s\");\n", schemaName);
     }
   else
     {
	menu = firstMenu;
	while (menu != NULL)
	  {
	     /* calcule le nombre d'entrees dans le menu */
	     itemsNumber = 0;
	     item = menu->AppMenuItems;
	     while (item != NULL)
	       {
		  itemsNumber++;
		  item = item->AppNextItem;
	       }

	     /*fprintf(AppFile, "\n"); */
	     fprintf (AppFile, "  TteAddMenu (");
	     switch (winType)
		   {
		      case MainWindow:
			 fprintf (AppFile, "MainWindow");
			 break;
		      case DocWindow:
			 fprintf (AppFile, "DocWindow");
			 break;
		      case DocTypeWindow:
			 fprintf (AppFile, "DocTypeWindow");
			 break;
		   }
	     fprintf (AppFile, ", \"%s\", %d, %s, %d", schemaName,
		      menu->AppMenuView, menu->AppMenuName, itemsNumber);
	     /* Declare les menus dynamiques */
	     if (!strcmp (menu->AppMenuName, "Attributes_"))
	       {
		  fprintf (AppFile, ", \"MenuAttribute\");\n");
		  fprintf (AppFile, "  AttributeMenuLoadResources();\n");
	       }
	     else if (!strcmp (menu->AppMenuName, "Selection_"))
	       {
		  fprintf (AppFile, ", \"MenuSelection\");\n");
		  fprintf (AppFile, "  SelectionMenuLoadResources();\n");
	       }
	     else if (!strcmp (menu->AppMenuName, "Help_"))
	       {
		  fprintf (AppFile, ", \"MenuHelp\");\n");
	       }
	     else
		fprintf (AppFile, ", \"\");\n");

	     /* traite la liste des items du menu */
	     item = menu->AppMenuItems;
	     while (item != NULL)
	       {
		  if (item->AppSubMenu != NULL)
		     /* traitement du sous-menu */
		     PrintSubMenu (item, winType, schemaName, menu->AppMenuName);
		  else
		    {
		       fprintf (AppFile, "    TteAddMenuItem (");
		       switch (winType)
			     {
				case MainWindow:
				   fprintf (AppFile, "MainWindow");
				   break;
				case DocWindow:
				   fprintf (AppFile, "DocWindow");
				   break;
				case DocTypeWindow:
				   fprintf (AppFile, "DocTypeWindow");
				   break;
			     }
		       fprintf (AppFile, ", \"%s\", %s, -1", schemaName, menu->AppMenuName);
		       if (item->AppItemName == NULL)
			  fprintf (AppFile, ", 0");
		       else
			  fprintf (AppFile, ", %s", item->AppItemName);
		       if (item->AppItemActionName == NULL)
			  fprintf (AppFile, ", NULL, '%c');\n", item->AppItemType);
		       else
			  fprintf (AppFile, ", \"%s\", '%c');\n", item->AppItemActionName, item->AppItemType);
		    }
		  /* item suivant */
		  item = item->AppNextItem;
	       }
	     menu = menu->AppNextMenu;
	  }
     }
}


/*----------------------------------------------------------------------
   WriteAppliInit                                                  
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteAppliInit (char *fname, PtrEventsSet pAppli)

#else  /* __STDC__ */
static void         WriteAppliInit (fname, pAppli)
char               *fname;
PtrEventsSet        pAppli;

#endif /* __STDC__ */

{
   if (strcmp (fname, "EDITOR") == 0)
     {
	fprintf (AppFile, "#include \"logo.xpm\"\n#include \"logo.xbm\"\n#include \"message.h\"\n\n");
	fprintf (AppFile, "int    appArgc;\nchar    **appArgv;\n");
	fprintf (AppFile, "Pixmap image;  /* logo pixmap */\n");
	fprintf (AppFile, "Pixmap image;  /* logo pixmap */\n");
	fprintf (AppFile, "Pixmap icon;   /* icon pixmap */\n\n");
     }
   fprintf (AppFile, "\n/*----------------------------------------------------------------------\n -----------------------------------------------------------------------*/\n");
   fprintf (AppFile, "void %sApplicationInitialise ()\n", fname);
   fprintf (AppFile, "{\n PtrEventsSet appliActions;\n\n");
   fprintf (AppFile, "  /* Create the new application context*/\n");
   fprintf (AppFile, "  appliActions = TteNewEventsSet (%d, \"%s\");\n",
	    pAppli->EvSStructId, pAppli->EvSName);

   WriteEventsList (pAppli);
   fprintf (AppFile, "}\n\n");
}


/*----------------------------------------------------------------------
   WriteActionList                                                 
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteActionList (char *fname)
#else  /* __STDC__ */
static void         WriteActionList (fname)
char               *fname;

#endif /* __STDC__ */
{
   PtrAction           action;
   char                actionFname[50];
   FILE               *actionFile;
   char                s[200];
   PtrAppDocType       menusDoc;
   PtrAppName          SchUsed;
   PtrAppName          menuAction;
   int                 nbActions;
   boolean             editingResource;
   boolean             structSelectResource;

   strcpy (actionFname, fname);
   strcat (actionFname, "actions.proto");
   actionFile = fopen (actionFname, "w");	/* Opens the skeleton action-file */

   WriteIncludes (fname, actionFile);	/* Writes the standard headers to the action-file */

   fprintf (AppFile, "/*########## Init Appplication action-list #################*/\n");
   /* Traite la commande USES */
   if (SchemasUsed != NULL)
     {
	SchUsed = SchemasUsed;
	while (SchUsed != NULL)
	  {
	     fprintf (AppFile, "extern void %sLoadResources ();\n",
		      SchUsed->AppNameValue);
	     SchUsed = SchUsed->AppNextName;
	  }
     }

   action = ActionList;
   fprintf (AppFile, "#ifdef __STDC__\n");
   while (action != NULL)
     {
	fprintf (actionFile, "\n/*----------------------------------------------------------------------\n -----------------------------------------------------------------------*/\n");
	fprintf (actionFile, "#ifdef __STDC__\n");
	strcpy (s, "#else /* __STDC__*/\n");
	fprintf (AppFile, "extern ");
	if (strcmp (action->ActName, "NoAction"))
	  {
	     /* Output the data to the actions-file */
	     if (action->ActPre)
	       {
		  fprintf (AppFile, "boolean %s (", action->ActName);
		  fprintf (actionFile, "boolean %s (", action->ActName);
		  strcat (s, "boolean ");
		  strcat (s, action->ActName);
		  strcat (s, "(");
	       }
	     else
	       {
		  fprintf (AppFile, "void %s (", action->ActName);
		  fprintf (actionFile, "void %s (", action->ActName);
		  strcat (s, "void ");
		  strcat (s, action->ActName);
		  strcat (s, "(");
	       }

	     switch (action->ActEvent)
		   {
		      case TteAttrMenu:
		      case TteAttrCreate:
		      case TteAttrModify:
		      case TteAttrRead:
		      case TteAttrSave:
		      case TteAttrExport:
		      case TteAttrDelete:
			 fprintf (AppFile, "NotifyAttribute *event);\n");
			 fprintf (actionFile, "NotifyAttribute *event)\n");
			 strcat (s, "event)\n     NotifyAttribute *event;\n");
			 break;
		      case TteElemMenu:
		      case TteElemNew:
		      case TteElemRead:
		      case TteElemSave:
		      case TteElemExport:
		      case TteElemDelete:
		      case TteElemSelect:
		      case TteElemExtendSelect:
		      case TteElemActivate:
		      case TteElemInclude:
		      case TteElemCopy:
		      case TteElemChange:
		      case TteElemMove:
		      case TteElemMouseOver:
		      case TteElemMouseOut:
			 fprintf (AppFile, "NotifyElement *event);\n");
			 fprintf (actionFile, "NotifyElement *event)\n");
			 strcat (s, "event)\n     NotifyElement *event;\n");
			 break;
		      case TteElemTransform:
			 fprintf (AppFile, "NotifyOnElementType *event);\n");
			 fprintf (actionFile, "NotifyOnElementType *event)\n");
			 strcat (s, "event)\n     NotifyOnElementType *event;\n");
			 break;
		      case TteElemSetReference:
		      case TteElemFetchInclude:
		      case TteElemTextModify:
			 fprintf (AppFile, "NotifyOnTarget *event);\n");
			 fprintf (actionFile, "NotifyOnTarget *event)\n");
			 strcat (s, "event)\n     NotifyOnTarget *event;\n");
			 break;
		      case TteElemPaste:
			 if (action->ActPre)
			   {
			      fprintf (AppFile, "NotifyOnValue *event);\n");
			      fprintf (actionFile, "NotifyOnValue *event)\n");
			      strcat (s, "event)\n     NotifyOnValue *event;\n");
			   }
			 else
			   {
			      fprintf (AppFile, "NotifyElement *event);\n");
			      fprintf (actionFile, "NotifyElement *event)\n");
			      strcat (s, "event)\n     NotifyElement *event;\n");
			   }
			 break;
		      case TteElemGraphModify:
			 fprintf (AppFile, "NotifyOnValue *event);\n");
			 fprintf (actionFile, "NotifyOnValue *event)\n");
			 strcat (s, "event)\n     NotifyOnValue *event;\n");
			 break;
		      case TtePRuleCreate:
		      case TtePRuleModify:
		      case TtePRuleDelete:
			 fprintf (AppFile, "NotifyPresentation *event);\n");
			 fprintf (actionFile, "NotifyPresentation *event)\n");
			 strcat (s, "event)\n     NotifyPresentation *event;\n");
			 break;
		      case TteDocOpen:
		      case TteDocTmpOpen:
		      case TteDocCreate:
		      case TteDocClose:
		      case TteDocSave:
		      case TteDocExport:
		      case TteViewOpen:
		      case TteViewClose:
			 fprintf (AppFile, "NotifyDialog *event);\n");
			 fprintf (actionFile, "NotifyDialog *event)\n");
			 strcat (s, "event)\n     NotifyDialog *event;\n");
			 break;
		      case TteViewResize:
		      case TteViewScroll:
			 fprintf (AppFile, "NotifyWindow *event);\n");
			 fprintf (actionFile, "NotifyWindow *event)\n");
			 strcat (s, "event)\n     NotifyWindow *event;\n");
			 break;
		      case TteInit:
		      case TteExit:
			 fprintf (AppFile, "NotifyEvent *event);\n");
			 fprintf (actionFile, "NotifyEvent *event)\n");
			 strcat (s, "event)\n     NotifyEvent *event;\n");
			 break;
		      case TteDocNatPresent:
			 fprintf (AppFile, "NotifyNaturePresent *event);\n");
			 fprintf (actionFile, "NotifyNaturePresent *event)\n");
			 strcat (s, "event)\n     NotifyNaturePresent *event;\n");
			 break;
		      default:
			 break;
		   }
	     fprintf (actionFile, s);
	     fprintf (actionFile, "#endif /* __STDC__*/\n{\n");
	     fprintf (actionFile, "  /* code to be written */\n");
	     if (action->ActPre)
		fprintf (actionFile, "  return FALSE; /* let Thot perform normal operation */\n");
	     fprintf (actionFile, "}\n\n");
	  }
	action = action->ActNext;
     }

   /* Seconde boucle */
   action = ActionList;
   fprintf (AppFile, "#else /* __STDC__*/\n");
   while (action != NULL)
     {
	fprintf (AppFile, "extern ");
	if (strcmp (action->ActName, "NoAction"))
	  {
	     /* Output the data to the actions-file */
	     if (action->ActPre)
		fprintf (AppFile, "boolean %s (", action->ActName);
	     else
		fprintf (AppFile, "void %s (", action->ActName);

	     switch (action->ActEvent)
		   {
		      case TteAttrMenu:
		      case TteAttrCreate:
		      case TteAttrModify:
		      case TteAttrRead:
		      case TteAttrSave:
		      case TteAttrExport:
		      case TteAttrDelete:
			 fprintf (AppFile, "/* NotifyAttribute *event */);\n");
			 break;
		      case TteElemMenu:
		      case TteElemNew:
		      case TteElemRead:
		      case TteElemSave:
		      case TteElemExport:
		      case TteElemDelete:
		      case TteElemSelect:
		      case TteElemExtendSelect:
		      case TteElemActivate:
		      case TteElemInclude:
		      case TteElemCopy:
		      case TteElemChange:
		      case TteElemMove:
		      case TteElemMouseOver:
		      case TteElemMouseOut:
			 fprintf (AppFile, "/* NotifyElement *event */);\n");
			 break;
		      case TteElemTransform:
			 fprintf (AppFile, "/* NotifyOnElementType *event */);\n");
			 break;
		      case TteElemSetReference:
		      case TteElemFetchInclude:
		      case TteElemTextModify:
			 fprintf (AppFile, "/* NotifyOnTarget *event */);\n");
			 break;
		      case TteElemPaste:
			 if (action->ActPre)
			    fprintf (AppFile, "/* NotifyOnValue *event */);\n");
			 else
			   {
			      fprintf (AppFile, "/* NotifyElement *event */);\n");
			   }
			 break;
		      case TteElemGraphModify:
			 fprintf (AppFile, "/* NotifyOnValue *event */);\n");
			 break;
		      case TtePRuleCreate:
		      case TtePRuleModify:
		      case TtePRuleDelete:
			 fprintf (AppFile, "/* NotifyPresentation *event */);\n");
			 break;
		      case TteDocOpen:
		      case TteDocTmpOpen:
		      case TteDocCreate:
		      case TteDocClose:
		      case TteDocSave:
		      case TteDocExport:
		      case TteViewOpen:
		      case TteViewClose:
			 fprintf (AppFile, "/* NotifyDialog *event */);\n");
			 break;
		      case TteViewResize:
		      case TteViewScroll:
			 fprintf (AppFile, "/* NotifyWindow *event */);\n");
			 break;
		      case TteInit:
		      case TteExit:
			 fprintf (AppFile, "/* NotifyEvent *event */);\n");
			 break;
		      case TteDocNatPresent:
			 fprintf (AppFile, "/* NotifyNaturePresent *event */);\n");
			 break;
		      default:
			 break;
		   }
	  }

	action = action->ActNext;
     }

   fprintf (AppFile, "#endif /* __STDC__*/\n\n");
   fprintf (AppFile, "void %sActionListInit ()\n", fname);
   fprintf (AppFile, "{\n");

   action = ActionList;
   while (action != NULL)
     {
	fprintf (AppFile, "  TteAddAction (\"%s\", (Proc)%s);\n",
		 action->ActName,
		 action->ActName);
	action = action->ActNext;
     }

   fprintf (AppFile, "}\n\n");

   if (strcmp (fname, "EDITOR") == 0)
     {
	/* c'est bien EDITOR.A qu'on compile, on ajoute le main avec les
	   initialisation qu'il faut */
	structSelectResource = FALSE;	/* no structselectResource */
	fprintf (AppFile, "\nvoid TteLoadApplications ()\n");
	fprintf (AppFile, "{\n");
	fprintf (AppFile, "  %sActionListInit ();\n", fname);
	fprintf (AppFile, "  %sApplicationInitialise ();\n", fname);
	/* Traite la commande USES */
	if (SchemasUsed != NULL)
	  {
	    SchUsed = SchemasUsed;
	    while (SchUsed != NULL)
	      {
		if (!strcmp (SchUsed->AppNameValue, "StructSelect")
		    || !strcmp (SchUsed->AppNameValue, "NoStructSelect"))
		  /* an explicit choice between struct and no struct */
		  structSelectResource = TRUE;
		fprintf (AppFile, "  %sLoadResources ();\n", SchUsed->AppNameValue);
		SchUsed = SchUsed->AppNextName;
	      }
	  }
	if (!structSelectResource)
	  /* an implicit choice */
	  fprintf (AppFile, "  NoStructSelectLoadResources ();\n");
	fprintf (AppFile, "}\n\n");

	/* compte les elements de la liste ActionsUsed */
	menuAction = ActionsUsed;
	nbActions = 0;
	fprintf (AppFile, "#ifdef __STDC__\n");
	while (menuAction != NULL)
	  {
	     nbActions++;
	     if (!menuAction->AppStandardName)
		/* declare les nouvelles fonctions non standard des menus */
		fprintf (AppFile, "extern void %s (Document document, View view);\n",
			 menuAction->AppNameValue);
	     menuAction = menuAction->AppNextName;
	  }
	/* Seconde boucle */
	fprintf (AppFile, "#else /* __STDC__*/\n");
	menuAction = ActionsUsed;
	while (menuAction != NULL)
	  {
	     if (!menuAction->AppStandardName)
		/* declare les nouvelles fonctions non standard des menus */
		fprintf (AppFile, "extern void %s (/*Document document, View view*/);\n",
			 menuAction->AppNameValue);
	     menuAction = menuAction->AppNextName;
	  }
	fprintf (AppFile, "#endif /* __STDC__*/\n\n");
	fprintf (AppFile, "/*################### Main program #########################*/\n");
	fprintf (AppFile, "#ifdef __STDC__\n");
	fprintf (AppFile, "int main (int argc, char **argv)\n");
	fprintf (AppFile, "#else /* __STDC__ */\n");
	fprintf (AppFile, "int main (argc, argv)\n");
	fprintf (AppFile, "        int argc;\n");
	fprintf (AppFile, "        char **argv;\n");
	fprintf (AppFile, "#endif /* __STDC__ */\n");
	fprintf (AppFile, "{\n");

	fprintf (AppFile, "  int lg; /* identify dialogue messages */\n");
	fprintf (AppFile, "  char appName[MAX_PATH]; /* name of the application */\n");
	fprintf (AppFile, "  char workName[MAX_PATH]; /* path of the application */\n");

	fprintf (AppFile, "  /* initialize the Registry */\n");
	fprintf (AppFile, "  TtaInitializeAppRegistry (argv[0]);\n");
	fprintf (AppFile, "  /* save argc and argv */\n");
	fprintf (AppFile, "  appArgc = argc;\n  appArgv = argv;\n");
	fprintf (AppFile, "  /* extract the name of the application */\n");
	fprintf (AppFile, "  TtaExtractName (argv[0], workName, appName);\n");
	fprintf (AppFile, "  /* application name is limited to 19 characters */\n");
	fprintf (AppFile, "  lg = strlen(appName);\n");
	fprintf (AppFile, "  if (lg > 19)\n");
	fprintf (AppFile, "    appName[19] = (char)0;\n");
	fprintf (AppFile, "  TtaInitialize (appName);\n");
	fprintf (AppFile, "\n  TteInitMenus (appName, %d);\n", nbActions);


	editingResource = FALSE;	/* no editing Resource loaded by default */
	menuAction = ActionsUsed;
	while (menuAction != NULL)
	  {
	     fprintf (AppFile, "  TteAddMenuAction(\"%s\", (Proc)%s);\n",
		      menuAction->AppNameValue, menuAction->AppNameValue);
	     if (!menuAction->AppStandardName)
		/* ecrit les fonctions non standard des menus dans XXXaction.c */
	       {
		  fprintf (actionFile, "\n/*----------------------------------------------------------------------\n -----------------------------------------------------------------------*/\n");
		  fprintf (actionFile, "#ifdef __STDC__\n");
		  fprintf (actionFile, "void %s (Document document, View view)\n",
			   menuAction->AppNameValue);
		  fprintf (actionFile, "#else /* __STDC__*/\n");
		  fprintf (actionFile, "void %s (document, view)\n",
			   menuAction->AppNameValue);
		  fprintf (actionFile, "     Document document;\n     View view;\n");
		  fprintf (actionFile, "#endif /* __STDC__*/\n{\n");
		  fprintf (actionFile, "  /* This function has to be written */\n");
		  fprintf (actionFile, "}\n\n");
	       }
	     else
	       {
		  /* Is it an editing standard function ? */
		  if (!strcmp (menuAction->AppNameValue, "TtcInsert")
		      || !strcmp (menuAction->AppNameValue, "TtcPasteFromClipboard")
		      || !strcmp (menuAction->AppNameValue, "TtcPaste")
		    || !strcmp (menuAction->AppNameValue, "TtcCutSelection")
		  || !strcmp (menuAction->AppNameValue, "TtcDeleteSelection")
		      || !strcmp (menuAction->AppNameValue, "TtcInsertChar")
		      || !strcmp (menuAction->AppNameValue, "TtcDeletePreviousChar")
		   || !strcmp (menuAction->AppNameValue, "TtcCopySelection")
		      || !strcmp (menuAction->AppNameValue, "TtcInclude"))
		     editingResource = TRUE;
	       }
	     menuAction = menuAction->AppNextName;
	  }

	fprintf (AppFile, "\n");
	PrintMenus (MainWindowMenus, MainWindow, "MAIN");

	fprintf (AppFile, "\n");
	PrintMenus (DocWindowMenus, DocWindow, "DOC");

	menusDoc = DocTypeMenus;
	while (menusDoc != NULL)
	  {
	     fprintf (AppFile, "\n");
	     PrintMenus (menusDoc->AppDocTypeMenus, DocTypeWindow,
			 menusDoc->AppDocTypeName);
	     menusDoc = menusDoc->AppNextDocType;
	  }

	fprintf (AppFile, "  /* load appName+\"dialogue\" message file */\n");
	fprintf (AppFile, "  strcpy(workName, appName);\n");
	fprintf (AppFile, "  strcat(workName, \"dialogue\");\n");
	fprintf (AppFile, "  TtaGetMessageTable (workName, MAX_EDITOR_LABEL);\n");
	/* if necessary load editing Resources */
	if (editingResource)
	   fprintf (AppFile, "  EditingLoadResources ();\n");
	fprintf (AppFile, "\n\n  image = TtaCreatePixmapLogo (logo_xpm);\n");
	fprintf (AppFile, "  icon = TtaCreateBitmapLogo (logo_width, logo_height, logo_bits);\n");
	fprintf (AppFile, "  TteOpenMainWindow (appName, image, icon);\n");
	fprintf (AppFile, "  TtaMainLoop ();\n  exit(0);\n");
	fprintf (AppFile, "}\n\n");

     }

   fprintf (AppFile, "void %sLoadResources ()\n", fname);
   fprintf (AppFile, "{\n");

   fprintf (AppFile, "  %sActionListInit ();\n", fname);
   fprintf (AppFile, "  %sApplicationInitialise ();\n}\n\n", fname);

   fclose (actionFile);
}


/*----------------------------------------------------------------------
   WriteIncludeFile                                                
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         WriteIncludeFile (FILE * dotHFile, FILE * dialogueFile)
#else  /* __STDC__ */
static void         WriteIncludeFile (dotHFile, dialogueFile)
FILE               *dotHFile;
FILE               *dialogueFile;

#endif /* __STDC__ */
{
   int                 i, num;
   PtrAppName          name;

   fprintf (dotHFile, "/* File generated by app - do not edit! */\n");
   fprintf (dotHFile, "/* #################################### */\n");
   fprintf (dotHFile, "/* Basic types */\n");
   for (i = 0; i < pSSchema->SsNRules; i++)
      fprintf (dotHFile, "#define %s  %d\n", pSSchema->SsRule[i].SrName, i + 1);

   /* liste tous les noms de menus et d'items reellement utilises */
   num = 0;
   fprintf (dotHFile, "\n/* Pull-down menus */\n");
   name = MenusUsed;
   while (name != NULL)
     {
	fprintf (dotHFile, "#define %s  %d\n", name->AppNameValue, num);
	fprintf (dialogueFile, "%d  %s\n", num, name->AppNameValue);
	name = name->AppNextName;
	num++;
     }

   fprintf (dotHFile, "\n/* Pull-down menu items */\n");
   name = ItemsUsed;
   while (name != NULL)
     {
	if (name->AppNameValue != NULL)
	  {
	     fprintf (dotHFile, "#define %s  %d\n", name->AppNameValue, num);
	     fprintf (dialogueFile, "%d  %s\n", num, name->AppNameValue);
	     num++;
	  }
	name = name->AppNextName;
     }
   fprintf (dotHFile, "\n#define MAX_EDITOR_LABEL       %d\n", num + 1);
}


/*----------------------------------------------------------------------
   GenerateApplication generates the application prototype.	
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                GenerateApplication (char *fname, PtrEventsSet pAppli)
#else  /* __STDC__ */
void                GenerateApplication (fname, pAppli)
char               *fname;
PtrEventsSet        pAppli;

#endif /* __STDC__ */
{
   int                 i;
   int                 lg, ht;
   char              **ptr;
   unsigned char      *bits;
   char               *fileSuffix;
   FILE               *dotHFile;
   FILE               *infoFILE;

   i = 0;
   fileSuffix = TtaStrdup (fname);

   /* met le suffixe APP.c a la fin du nom de fichier */
   while (fname[i] != ' ' && fname[i] != '\0')
      i++;
   fname[i] = '\0';
   strcpy (&fname[i], "APP.c");

   /* cree le fichier */
   AppFile = fopen (fname, "w");
   WriteIncludes (fileSuffix, AppFile);
   WriteAppliInit (fileSuffix, pAppli);
   WriteActionList (fileSuffix);
   fclose (AppFile);

   /* cree les fichiers EDITOR.h et EDITORdialogue */
   if (strcmp ("EDITOR", fileSuffix) == 0)
     {
	dotHFile = fopen ("EDITOR.h", "w");
	infoFILE = fopen ("EDITORdialogue", "w");
	WriteIncludeFile (dotHFile, infoFILE);
	fclose (infoFILE);
	fclose (dotHFile);
	if (!TtaFileExist ("logo.xpm"))
	  {
	     /* cree le fichier logo.xpm */
	     infoFILE = fopen ("logo.xpm", "w");
	     fprintf (infoFILE, "/* XPM */\nstatic char * logo_xpm[] = {\n");
	     ptr = logo_xpm;
	     lg = sizeof (logo_xpm) / sizeof (char *) - 1;

	     for (i = 0; i < lg; i++)
	       {
		  fprintf (infoFILE, "\"%s\",\n", ptr[i]);
	       }
	     fprintf (infoFILE, "\"%s\"};\n", ptr[i]);
	     fclose (infoFILE);
	  }
	if (!TtaFileExist ("logo.xbm"))
	  {
	     /* cree le fichier logo.xbm */
	     infoFILE = fopen ("logo.xbm", "w");
	     lg = logo_width;
	     ht = logo_height;
	     fprintf (infoFILE, "#define logo_width %d\n", lg);
	     fprintf (infoFILE, "#define logo_height %d\n", ht);
	     fprintf (infoFILE, "static unsigned char logo_bits[] = {\n");
	     bits = logo_bits;
	     lg = sizeof (logo_bits) / sizeof (unsigned char) - 1;

	     i = 0;
	     while (i < lg)
	       {
		  fprintf (infoFILE, " 0x%.2x,", (unsigned int) bits[i]);
		  i++;
		  if (i % 12 == 0)
		     fprintf (infoFILE, "\n");
	       }
	     fprintf (infoFILE, " 0x%.2x, };\n", (unsigned int) bits[i]);
	     fclose (infoFILE);
	  }
     }
   TtaFreeMemory (fileSuffix);
}
