/* $Revision Header *** Header built automatically - do not edit! ***********
 *
 *	(C) Copyright 1991 by Torsten Jürgeleit
 *
 *	Name .....: source.c
 *	Created ..: Sunday 22-Dec-91 21:35:45
 *	Revision .: 0
 *
 *	Date        Author                 Comment
 *	=========   ====================   ====================
 *	22-Dec-91   Torsten Jürgeleit      Created this file!
 *
 ****************************************************************************
 *
 *	C source code generator
 *
 * $Revision Header ********************************************************/

	/* Includes */

#include "includes.h"
#include "defines.h"
#include "imports.h"
#include "protos.h"

	/* Defines */

#define GADGET_TEXT	(gads ? gad_y : gad_n)

	/* Defines for source title */

#define SOURCE_TITLE_LEFT_EDGE	0
#define SOURCE_TITLE_TOP_EDGE	5
#define SOURCE_TITLE_TYPE	TEXT_DATA_TYPE_TEXT
#define SOURCE_TITLE_FLAGS	(TEXT_DATA_FLAG_CENTER | TEXT_DATA_FLAG_BOLD)
#define SOURCE_TITLE_TEXT	"Save C source code of project"
#define SOURCE_TITLE_TEXT_ATTR	&topaz80_attr

	/* Defines for source gadgets */

#define SOURCE_SELECTION_OK	1

#define SOURCE_GADGET_OK	0
#define SOURCE_GADGET_CANCEL	1
#define SOURCE_GADGET_ID	2
#define SOURCE_GADGET_STATIC	3
#define SOURCE_GADGET_INNER	4
#define SOURCE_GADGET_WINDOW	5
#define SOURCE_GADGET_PROGRAM	6

#define SOURCE_GADGET1_TYPE		GADGET_DATA_TYPE_BUTTON
#define SOURCE_GADGET1_FLAGS		GADGET_DATA_FLAG_HOTKEY
#define SOURCE_GADGET1_TEXT		"_Ok"
#define SOURCE_GADGET1_LEFT_EDGE	((EDITOR_WINDOW_WIDTH / 2 - SOURCE_GADGET1_WIDTH) / 2)
#define SOURCE_GADGET1_TOP_EDGE		(EDITOR_WINDOW_HEIGHT - SOURCE_GADGET1_HEIGHT - 5)
#define SOURCE_GADGET1_WIDTH		((6 + 2) * 8)
#define SOURCE_GADGET1_HEIGHT		15
#define SOURCE_GADGET1_TEXT_ATTR	&topaz80_attr

#define SOURCE_GADGET2_TYPE		GADGET_DATA_TYPE_BUTTON
#define SOURCE_GADGET2_FLAGS		GADGET_DATA_FLAG_HOTKEY
#define SOURCE_GADGET2_TEXT		"_Cancel"
#define SOURCE_GADGET2_LEFT_EDGE	(EDITOR_WINDOW_WIDTH / 2 + (EDITOR_WINDOW_WIDTH / 2 - SOURCE_GADGET1_WIDTH) / 2)
#define SOURCE_GADGET2_TOP_EDGE		(EDITOR_WINDOW_HEIGHT - SOURCE_GADGET1_HEIGHT - 5)
#define SOURCE_GADGET2_WIDTH		SOURCE_GADGET1_WIDTH
#define SOURCE_GADGET2_HEIGHT		SOURCE_GADGET1_HEIGHT
#define SOURCE_GADGET2_TEXT_ATTR	&topaz80_attr

#define SOURCE_GADGET3_TYPE		GADGET_DATA_TYPE_STRING
#define SOURCE_GADGET3_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_LEFT)
#define SOURCE_GADGET3_LEFT_EDGE	(110 + (10 + 1) * 8)
#define SOURCE_GADGET3_TOP_EDGE		22
#define SOURCE_GADGET3_WIDTH		76
#define SOURCE_GADGET3_HEIGHT		12
#define SOURCE_GADGET3_TEXT		"Project I_D"
#define SOURCE_GADGET3_TEXT_ATTR	&topaz80_attr
#define SOURCE_GADGET3_INPUT_LEN	MAX_PROJECT_ID_LEN
#define SOURCE_GADGET3_INPUT_ACTIVATE	0
#define SOURCE_GADGET3_INPUT_DEFAULT	NULL

#define SOURCE_GADGET4_TYPE		GADGET_DATA_TYPE_CHECK
#define SOURCE_GADGET4_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_RIGHT)
#define SOURCE_GADGET4_TEXT		"_Static data"
#define SOURCE_GADGET4_LEFT_EDGE	(SOURCE_GADGET3_LEFT_EDGE + SOURCE_GADGET3_WIDTH + 50)
#define SOURCE_GADGET4_TOP_EDGE		(SOURCE_GADGET3_TOP_EDGE + 1)
#define SOURCE_GADGET4_WIDTH		0
#define SOURCE_GADGET4_HEIGHT		0
#define SOURCE_GADGET4_TEXT_ATTR	&topaz80_attr

#define SOURCE_GADGET5_TYPE		GADGET_DATA_TYPE_CHECK
#define SOURCE_GADGET5_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_RIGHT)
#define SOURCE_GADGET5_TEXT		"_Inner window"
#define SOURCE_GADGET5_LEFT_EDGE	SOURCE_GADGET4_LEFT_EDGE
#define SOURCE_GADGET5_TOP_EDGE		(SOURCE_GADGET4_TOP_EDGE + 16)
#define SOURCE_GADGET5_WIDTH		0
#define SOURCE_GADGET5_HEIGHT		0
#define SOURCE_GADGET5_TEXT_ATTR	&topaz80_attr

#define SOURCE_GADGET6_TYPE		GADGET_DATA_TYPE_CHECK
#define SOURCE_GADGET6_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_RIGHT)
#define SOURCE_GADGET6_TEXT		"_Window"
#define SOURCE_GADGET6_LEFT_EDGE	SOURCE_GADGET5_LEFT_EDGE
#define SOURCE_GADGET6_TOP_EDGE		(SOURCE_GADGET5_TOP_EDGE + 16)
#define SOURCE_GADGET6_WIDTH		0
#define SOURCE_GADGET6_HEIGHT		0
#define SOURCE_GADGET6_TEXT_ATTR	&topaz80_attr

#define SOURCE_GADGET7_TYPE		GADGET_DATA_TYPE_CHECK
#define SOURCE_GADGET7_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_RIGHT)
#define SOURCE_GADGET7_TEXT		"_Program"
#define SOURCE_GADGET7_LEFT_EDGE	SOURCE_GADGET6_LEFT_EDGE
#define SOURCE_GADGET7_TOP_EDGE		(SOURCE_GADGET6_TOP_EDGE + 16)
#define SOURCE_GADGET7_WIDTH		0
#define SOURCE_GADGET7_HEIGHT		0
#define SOURCE_GADGET7_TEXT_ATTR	&topaz80_attr

	/* Statics for source requester */

STATIC struct GadgetData  source_gadget_data[] = {
   {
	SOURCE_GADGET1_TYPE,		/* gd_Type */
	SOURCE_GADGET1_FLAGS,		/* gd_Flags */
	SOURCE_GADGET1_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET1_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET1_WIDTH,		/* gd_Width */
	SOURCE_GADGET1_HEIGHT,		/* gd_Height */
	SOURCE_GADGET1_TEXT,		/* *gd_Text */
	SOURCE_GADGET1_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	SOURCE_GADGET2_TYPE,		/* gd_Type */
	SOURCE_GADGET2_FLAGS,		/* gd_Flags */
	SOURCE_GADGET2_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET2_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET2_WIDTH,		/* gd_Width */
	SOURCE_GADGET2_HEIGHT,		/* gd_Height */
	SOURCE_GADGET2_TEXT,		/* *gd_Text */
	SOURCE_GADGET2_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	SOURCE_GADGET3_TYPE,		/* gd_Type */
	SOURCE_GADGET3_FLAGS,		/* gd_Flags */
	SOURCE_GADGET3_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET3_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET3_WIDTH,		/* gd_Width */
	SOURCE_GADGET3_HEIGHT,		/* gd_Height */
	SOURCE_GADGET3_TEXT,		/* *gd_Text */
	SOURCE_GADGET3_TEXT_ATTR,	/* *gd_TextAttr */
	{
	SOURCE_GADGET3_INPUT_LEN,	/* gd_InputLen */
	SOURCE_GADGET3_INPUT_ACTIVATE,	/* gd_InputActivate */
	SOURCE_GADGET3_INPUT_DEFAULT	/* gd_InputDefault */
	}
   }, {
	SOURCE_GADGET4_TYPE,		/* gd_Type */
	SOURCE_GADGET4_FLAGS,		/* gd_Flags */
	SOURCE_GADGET4_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET4_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET4_WIDTH,		/* gd_Width */
	SOURCE_GADGET4_HEIGHT,		/* gd_Height */
	SOURCE_GADGET4_TEXT,		/* *gd_Text */
	SOURCE_GADGET4_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	SOURCE_GADGET5_TYPE,		/* gd_Type */
	SOURCE_GADGET5_FLAGS,		/* gd_Flags */
	SOURCE_GADGET5_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET5_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET5_WIDTH,		/* gd_Width */
	SOURCE_GADGET5_HEIGHT,		/* gd_Height */
	SOURCE_GADGET5_TEXT,		/* *gd_Text */
	SOURCE_GADGET5_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	SOURCE_GADGET6_TYPE,		/* gd_Type */
	SOURCE_GADGET6_FLAGS,		/* gd_Flags */
	SOURCE_GADGET6_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET6_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET6_WIDTH,		/* gd_Width */
	SOURCE_GADGET6_HEIGHT,		/* gd_Height */
	SOURCE_GADGET6_TEXT,		/* *gd_Text */
	SOURCE_GADGET6_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	SOURCE_GADGET7_TYPE,		/* gd_Type */
	SOURCE_GADGET7_FLAGS,		/* gd_Flags */
	SOURCE_GADGET7_LEFT_EDGE,	/* gd_LeftEdge */
	SOURCE_GADGET7_TOP_EDGE,	/* gd_TopEdge */
	SOURCE_GADGET7_WIDTH,		/* gd_Width */
	SOURCE_GADGET7_HEIGHT,		/* gd_Height */
	SOURCE_GADGET7_TEXT,		/* *gd_Text */
	SOURCE_GADGET7_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	INTUISUP_DATA_END		/* mark end of gadget data */
   }
};
	/* Save project as C source code */

   SHORT
save_c_source(VOID)
{
   struct TemplateList  *tl = &template_list;
   struct GadgetData    *gd = &source_gadget_data[0];
   APTR   gl;
   USHORT flags = tl->tl_Flags;
   SHORT  status;

   /* Init gadgets with current project data */
   (gd + SOURCE_GADGET_ID)->gd_SpecialData.gd_InputData.gd_InputDefault       = &tl->tl_ProjectID[0];
   (gd + SOURCE_GADGET_STATIC)->gd_SpecialData.gd_CheckData.gd_CheckSelected  = (flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ? 1 : 0);
   (gd + SOURCE_GADGET_INNER)->gd_SpecialData.gd_CheckData.gd_CheckSelected   = (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ? 1 : 0);
   (gd + SOURCE_GADGET_WINDOW)->gd_SpecialData.gd_CheckData.gd_CheckSelected  = (flags & TEMPLATE_LIST_FLAG_SOURCE_WINDOW ? 1 : 0);
   (gd + SOURCE_GADGET_PROGRAM)->gd_SpecialData.gd_CheckData.gd_CheckSelected = (flags & TEMPLATE_LIST_FLAG_SOURCE_PROGRAM ? 1 : 0);

   /* Print title and display gadgets */
   IClearWindow(eri, ewin, 0, 0, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_HEIGHT,
									 0);
   IPrintText(eri, ewin, SOURCE_TITLE_TEXT, SOURCE_TITLE_LEFT_EDGE,
	       SOURCE_TITLE_TOP_EDGE, SOURCE_TITLE_TYPE, SOURCE_TITLE_FLAGS,
						    SOURCE_TITLE_TEXT_ATTR);
   if (!(gl = ICreateGadgets(eri, &source_gadget_data[0], 0, 0, NULL))) {
      status = EDITOR_ERROR_OUT_OF_MEM;
   } else {
      IDisplayGadgets(ewin, gl);
      status = save_c_source_action(gl, tl);
      IRemoveGadgets(gl);
      IFreeGadgets(gl);

      /* Generate C source */
      if (status == SOURCE_SELECTION_OK) {
	 status = generate_c_source(tl);
      }
   }
   return(status);
}
	/* Perform action for source code generator */

   STATIC SHORT
save_c_source_action(APTR gl, struct TemplateList  *tl)
{
   struct MsgPort  *up = ewin->UserPort;
   BYTE   *id = NULL;
   USHORT flags = tl->tl_Flags;
   BOOL   keepon = TRUE;
   SHORT  status = EDITOR_STATUS_NORMAL;

   do {
      struct IntuiMessage  *msg;

      WaitPort(up);
      while (msg = IGetMsg(up)) {
	 ULONG value;

	 switch (msg->Class) {
	    case CLOSEWINDOW :
	       status = EDITOR_STATUS_QUIT;
	       keepon = FALSE;
	       break;

	    case ISUP_ID :
	       value = (ULONG)msg->IAddress;
	       switch (msg->Code) {
		  case SOURCE_GADGET_OK :

		     /* Change template list data */
		     if (id) {
			strcpy(&tl->tl_ProjectID[0], id);
		     }
		     tl->tl_Flags = flags;

		     /* Set status to generate C source code */
		     status = SOURCE_SELECTION_OK;
		     keepon = FALSE;
		     break;

		  case SOURCE_GADGET_CANCEL :
		     keepon = FALSE;
		     break;

		  case SOURCE_GADGET_ID :
		     id     = (BYTE *)value;
		     flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     break;

		  case SOURCE_GADGET_STATIC :
		     if (value) {
			flags |= TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA;
		     } else {
			flags &= ~TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA;
		     }
		     flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     break;

		  case SOURCE_GADGET_INNER :
		     if (value) {
			flags |= TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW;
		     } else {
			flags &= ~TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW;
		     }
		     flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     break;

		  case SOURCE_GADGET_WINDOW :
		     if (value) {
			flags |= TEMPLATE_LIST_FLAG_SOURCE_WINDOW;
		     } else {
			flags &= ~TEMPLATE_LIST_FLAG_SOURCE_WINDOW;
		     }
		     flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     break;

		  case SOURCE_GADGET_PROGRAM :
		     if (value) {
			flags |= TEMPLATE_LIST_FLAG_SOURCE_PROGRAM;
			if (!(flags & TEMPLATE_LIST_FLAG_SOURCE_WINDOW)) {
			   flags |= TEMPLATE_LIST_FLAG_SOURCE_WINDOW;
			   ISetGadgetAttributes(gl, SOURCE_GADGET_WINDOW,
						  0L, 1L, USE_CURRENT_VALUE,
						 (VOID *)USE_CURRENT_VALUE);
			}
		     } else {
			flags &= ~TEMPLATE_LIST_FLAG_SOURCE_PROGRAM;
		     }
		     flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     break;
	       }
	       break;
	 }
	 IReplyMsg(msg);
      }
   } while (keepon == TRUE);
   return(status);
}
	/* C source code generator */

   STATIC SHORT
generate_c_source(struct TemplateList  *tl)
{
   struct FileRequester  *freq = csource_file_requester;
   SHORT status = EDITOR_STATUS_NORMAL;

   /* Display ARP file requester and check if user selected cancel */
   IChangeMousePointer(ewin, NULL);
   freq->fr_FuncFlags |= FRF_DoColor;
   freq->fr_Hail       = CSOURCE_SAVE_HAIL_TEXT;
   if (FileRequest(freq)) {
      struct TemplateList  *tl = &template_list;
      BPTR  fh;
      BYTE  path[LONG_DSIZE + LONG_FSIZE + 1];
      SHORT len = strlen(freq->fr_File) - 2;

      /* Prepare file name */
      if (len < 1 || Strcmp(freq->fr_File + len, ".c")) {
	 strcat(freq->fr_File, ".c");
	 len += 2;
      }

      /* Build full path for project file */
      strcpy(&path[0], freq->fr_Dir);
      TackOn(&path[0], freq->fr_File);

      /* Check if file already exists and inform user */
      if (fh = Open(&path[0], (LONG)MODE_OLDFILE)) {
	 Close(fh);
      }
      if (!fh || ok_cancel_requester(" Save C source ", "File already"
		" exists.\\n\\nDo you really want to overwrite?") == TRUE) {

	 /* Open file and write C source */
	 if (!(fh = Open(&path[0], (LONG)MODE_NEWFILE))) {
	    status = EDITOR_ERROR_OPEN_FAILED;
	 } else {
	    if ((status = write_project_window(fh, tl)) ==
						     EDITOR_STATUS_NORMAL) {
	       if ((status = write_project_borders(fh, tl)) ==
						     EDITOR_STATUS_NORMAL) {
		  if ((status = write_project_fonts(fh, tl)) ==
						     EDITOR_STATUS_NORMAL) {
		     if ((status = write_project_texts(fh, tl)) ==
						     EDITOR_STATUS_NORMAL) {
			if ((status = write_project_gadgets(fh, tl)) ==
						     EDITOR_STATUS_NORMAL) {
			   status = write_project_program(fh, tl);
			}
		     }
		  }
	       }
	    }
	    Close(fh);

	    /* If any error then delete incomplete C source file */
	    if (status != EDITOR_STATUS_NORMAL) {
	       DeleteFile(&path[0]);
	    }
	 }
      }
   }
   IRestoreMousePointer(ewin);
   if (status != EDITOR_STATUS_NORMAL) {
      show_error(status);
   }
   return(status);
}
	/* Write project window data to save file */

   STATIC SHORT
write_project_window(BPTR fh, struct TemplateList  *tl)
{
   USHORT flags = tl->tl_Flags;
   SHORT  status = EDITOR_STATUS_NORMAL;

   if (FPrintf(fh, "\t\t/* Project: %s */\n\n",
					   &tl->tl_ProjectName[0]) == -1L) {
      status = EDITOR_ERROR_WRITE_FAILED;
   }
   if (status == EDITOR_STATUS_NORMAL &&
				flags & TEMPLATE_LIST_FLAG_SOURCE_PROGRAM) {
      if (FPrintf(fh,
		"\t/* Includes */\n\n"
		"#include <exec/types.h>\n"
		"#include <exec/lists.h>\n"
		"#include <intuition/intuition.h>\n"
		"#include <libraries/intuisup.h>\n"
		"#include <functions.h>\n\n") == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      }
   }
   if (status == EDITOR_STATUS_NORMAL &&
				 flags & TEMPLATE_LIST_FLAG_SOURCE_WINDOW) {
      struct Window  *win = pwin;
      BYTE id[MAX_PROJECT_ID_LEN];

      lower_string(&tl->tl_ProjectID[0], &id[0]);
      if (FPrintf(fh,
		"\t/* Defines and data for window */\n\n"
		"#define RENDER_INFO_FLAGS  %d\n"
		"#define OPEN_WINDOW_FLAGS  %d\n\n"
		"#define WINDOW_LEFT_EDGE   %d\n"
		"#define WINDOW_TOP_EDGE    %d\n"
		"#define WINDOW_WIDTH       %d\n"
		"#define WINDOW_HEIGHT      %d\n\n"
		"%sstruct NewWindow  %s_new_window = {\n"
		"   WINDOW_LEFT_EDGE, WINDOW_TOP_EDGE, WINDOW_WIDTH,"
		" WINDOW_HEIGHT, 0, 1,\n"
		"   CLOSEWINDOW | GADGET_IDCMP_FLAGS_ALL, WINDOWCLOSE |"
		" WINDOWDRAG |\n"
		"   WINDOWDEPTH | SMART_REFRESH | NOCAREREFRESH | ACTIVATE,"
		" NULL, NULL,\n"
		"   (UBYTE *)\"%s\", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN\n"
		"};\n",
				 ((flags & TEMPLATE_LIST_FLAG_SOURCE_INNER ?
					RENDER_INFO_FLAG_INNER_WINDOW : 0) |
				     (flags & TEMPLATE_LIST_FLAG_BACK_FILL ?
					   RENDER_INFO_FLAG_BACK_FILL : 0)),
				 (flags & TEMPLATE_LIST_FLAG_RENDER_COLORS ?
					  OPEN_WINDOW_FLAG_RENDER_PENS : 0),
						win->LeftEdge, win->TopEdge,
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
	      win->Width - win->BorderLeft - win->BorderRight : win->Width),
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
	    win->Height - win->BorderTop - win->BorderBottom : win->Height),
	   (flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ? "STATIC " : ""),
				   &id[0], &tl->tl_ProjectName[0]) == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      }
   }
   return(status);
}
	/* Write project border defines and data to save file */

   STATIC SHORT
write_project_borders(BPTR fh, struct TemplateList  *tl)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (tl->tl_BorderTemplates) {
      if (FPrintf(fh, "\t/* Defines and data for borders */\n\n") == -1L) {
         status = EDITOR_ERROR_WRITE_FAILED;
      }
      if (status == EDITOR_STATUS_NORMAL) {
	 struct Template  *tp;
	 BYTE   id[MAX_PROJECT_ID_LEN + 1];
	 USHORT count;

	 /* Write defines */
	 upper_string(&tl->tl_ProjectID[0], &id[0]);
	 for (count = 0, tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
				     count++, tp = get_succ(&tp->tp_Node)) {
	    if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_BORDER) {
	       BYTE name[MAX_TEMPLATE_NAME_LEN + 1];

	       upper_string(&tp->tp_TemplateName[0], &name[0]);
	       if (FPrintf(fh, "#define %s_BORDER_%s   %d\n",
					  &id[0], &name[0], count) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    }
	 }
	 if (status == EDITOR_STATUS_NORMAL) {
	    USHORT flags = tl->tl_Flags;

	    /* Write border data */
	    lower_string(&tl->tl_ProjectID[0], &id[0]);
	    if (FPrintf(fh, "\n%sstruct BorderData  %s_border_data[] = {\n"
			    "   {\n",
			    (flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
					  "STATIC " : ""), &id[0]) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    } else {
	       struct Window  *win = pwin;

	       for (tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
		  if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_BORDER) {
		     struct BorderData  *bd = &tp->tp_Data.tp_BorderData;
	       
		     if (FPrintf(fh, "      %d, %d, %d, %d, %d\n"
				     "   }, {\n", bd->bd_Type,
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					 bd->bd_LeftEdge - win->BorderLeft :
							   bd->bd_LeftEdge),
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					   bd->bd_TopEdge - win->BorderTop :
							    bd->bd_TopEdge),
				      bd->bd_Width, bd->bd_Height) == -1L) {
			status = EDITOR_ERROR_WRITE_FAILED;
		     }
		  }
	       }
	       if (status == EDITOR_STATUS_NORMAL) {
		  if (FPrintf(fh, "      INTUISUP_DATA_END\n"
				  "   }\n"
				  "};\n") == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  }
	       }
	    }
	 }
      }
   }
   return(status);
}
	/* Write project font data to save file */

   STATIC SHORT
write_project_fonts(BPTR fh, struct TemplateList  *tl)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (tl->tl_TextTemplates || tl->tl_GadgetTemplates) {
      BYTE id[MAX_PROJECT_ID_LEN + 1];

      lower_string(&tl->tl_ProjectID[0], &id[0]);
      if (FPrintf(fh, "\t/* Data for fonts */\n\n"
		      "%sstruct TextAttr  %s_text_attr[] = {\n"
		      "   {\n",
		     (tl->tl_Flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
					  "STATIC " : ""), &id[0]) == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      } else {
	 struct TemplateFont  *tf = get_head((struct List *)&tl->tl_Fonts);

	 while (tf && status == EDITOR_STATUS_NORMAL) {
	    struct TextAttr  *ta = &tf->tf_TextAttr;
	       
	    tf = get_succ((struct Node *)&tf->tf_MinNode);
	    if (FPrintf(fh, "      (STRPTR)\"%s\", %d, FS_NORMAL, FPF_ROMFONT\n"
			    "   }%s", ta->ta_Name, ta->ta_YSize,
					(tf ? ", {\n" : "\n};\n")) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	 }
      }
   }
   return(status);
}
	/* Write project text defines and data to save file */

   STATIC SHORT
write_project_texts(BPTR fh, struct TemplateList  *tl)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (tl->tl_TextTemplates) {
      if (FPrintf(fh, "\t/* Defines and data for texts */\n\n") == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      }
      if (status == EDITOR_STATUS_NORMAL) {
	 struct Template  *tp;
	 BYTE   id[MAX_PROJECT_ID_LEN + 1];
	 USHORT count;

	 /* Write defines */
	 upper_string(&tl->tl_ProjectID[0], &id[0]);
	 for (count = 0, tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
	    if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_TEXT) {
	       BYTE name[MAX_TEMPLATE_NAME_LEN + 1];

	       upper_string(&tp->tp_TemplateName[0], &name[0]);
	       if (FPrintf(fh, "#define %s_TEXT_%s   %d\n",
					  &id[0], &name[0], count) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       } else {
		  count++;
	       }
	    }
	 }
	 if (status == EDITOR_STATUS_NORMAL) {
	    USHORT flags = tl->tl_Flags;

	    /* Write text data */
	    lower_string(&tl->tl_ProjectID[0], &id[0]);
	    if (FPrintf(fh, "\n%sstruct TextData  %s_text_data[] = {\n"
			    "   {\n",
			    (flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
					  "STATIC " : ""), &id[0]) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    } else {
	       struct Window  *win = pwin;

	       for (tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
		  if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_TEXT) {
		     struct TextData  *td = &tp->tp_Data.tp_TextData;
	       
		     if (FPrintf(fh, "      %d, %d, %d, %d,\n"
				     "      \"%s\", &%s_text_attr[%d]\n"
				     "   }, {\n", td->td_Type, td->td_Flags,
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					 td->td_LeftEdge - win->BorderLeft :
							   td->td_LeftEdge),
			   (flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					   td->td_TopEdge - win->BorderTop :
							    td->td_TopEdge),
			      td->td_Text, &id[0], get_template_font_num(tl,
						 td->td_TextAttr)) == -1L) {
			status = EDITOR_ERROR_WRITE_FAILED;
		     }
		  }
	       }
	       if (status == EDITOR_STATUS_NORMAL) {
		  if (FPrintf(fh, "      INTUISUP_DATA_END\n"
				  "   }\n"
				  "};\n") == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  }
	       }
	    }
	 }
      }
   }
   return(status);
}
	/* Write project gadget defines and data to save file */

   STATIC SHORT
write_project_gadgets(BPTR fh, struct TemplateList  *tl)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (tl->tl_GadgetTemplates) {
      if (FPrintf(fh, "\t/* Defines and data for gadgets */\n\n") == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      }
      if (status == EDITOR_STATUS_NORMAL) {
	 struct Template  *tp;
	 BYTE   id[MAX_PROJECT_ID_LEN + 1];
         USHORT count;

	 /* Write defines */
	 upper_string(&tl->tl_ProjectID[0], &id[0]);
	 for (count = 0, tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
	    if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_GADGET) {
	       BYTE name[MAX_TEMPLATE_NAME_LEN + 1];

	       upper_string(&tp->tp_TemplateName[0], &name[0]);
	       if (FPrintf(fh, "#define %s_GADGET_%s   %d\n%s",
					  &id[0], &name[0], count) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       } else {
		  count++;
	       }
	    }
	 }
	 if (status == EDITOR_STATUS_NORMAL) {
	    if (FPrintf(fh, "\n") == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    } else {
	
	       /* Write text arrays and lists */
	       lower_string(&tl->tl_ProjectID[0], &id[0]);
	       for (count = 1, tp = get_head((struct List *)&tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
		  if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_GADGET) {
		     struct GadgetData  *gd = &tp->tp_Data.tp_GadgetData;

		     switch (gd->gd_Type) {
			case GADGET_DATA_TYPE_MX :
			   status = write_gadget_text_array(fh, tl, &id[0], count,
			       gd->gd_SpecialData.gd_MXData.gd_MXTextArray);
			   break;

			case GADGET_DATA_TYPE_CYCLE :
			   status = write_gadget_text_array(fh, tl, &id[0], count,
			   gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray);
			   break;

			case GADGET_DATA_TYPE_LISTVIEW :
			   status = write_gadget_list(fh, tl, &id[0], count,
			   gd->gd_SpecialData.gd_ListViewData.gd_ListViewList);
			   break;
		     }
		     count++;
		  }
	       }
	       if (status == EDITOR_STATUS_NORMAL) {
		  USHORT flags = tl->tl_Flags;

		  /* Write gadget data */
		  if (FPrintf(fh, "%sstruct GadgetData  %s_gadget_data[] = {\n"
				  "   {\n",
			    (flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
					  "STATIC " : ""), &id[0]) == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  } else {
		     struct Window  *win = pwin;

		     for (count = 1, tp = get_head((struct List *)
							 &tl->tl_Templates);
				       tp && status == EDITOR_STATUS_NORMAL;
					      tp = get_succ(&tp->tp_Node)) {
			if (TEMPLATE_GROUP(tp) == TEMPLATE_GROUP_GADGET) {
			   struct GadgetData  *gd = &tp->tp_Data.tp_GadgetData;
	       
			   if (FPrintf(fh, "      %ld, %ld, %d, %d, %d, %d,\n"
					   "      \"%s\", &%s_text_attr[%d],\n",
						  gd->gd_Type, gd->gd_Flags,
				(flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					 gd->gd_LeftEdge - win->BorderLeft :
							   gd->gd_LeftEdge),
				(flags & TEMPLATE_LIST_FLAG_SOURCE_INNER_WINDOW ?
					   gd->gd_TopEdge - win->BorderTop :
							    gd->gd_TopEdge),
				   gd->gd_Width, gd->gd_Height, gd->gd_Text,
					   &id[0], get_template_font_num(tl,
						 gd->gd_TextAttr)) == -1L) {
			      status = EDITOR_ERROR_WRITE_FAILED;
			   } else {
			      if ((status = write_gadget_special_data(fh, &id[0],
				      count, gd)) == EDITOR_STATUS_NORMAL) {
				 count++;
			      }
			   }
			}
		     }
		     if (status == EDITOR_STATUS_NORMAL) {
			if (FPrintf(fh, "      INTUISUP_DATA_END\n"
					"   }\n"
					"};\n") == -1L) {
			   status = EDITOR_ERROR_WRITE_FAILED;
			}
		     }
		  }
	       }
	    }
	 }
      }
   }
   return(status);
}
	/* Write gadget text array to save file*/

   STATIC SHORT
write_gadget_text_array(BPTR fh, struct TemplateList  *tl, BYTE *id,
						 USHORT count, BYTE **array)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (FPrintf(fh, "%sBYTE *%s_gadget%d_text_array[] = {\n",
		     (tl->tl_Flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
				       "STATIC " : ""), id, count) == -1L) {
      status = EDITOR_ERROR_WRITE_FAILED;
   } else {
      BYTE *text;

      while ((text = *array++) && status == EDITOR_STATUS_NORMAL) {
	 if (FPrintf(fh, "   \"%s\",\n", text) == -1L) {
	    status = EDITOR_ERROR_WRITE_FAILED;
	 }
      }
      if (status == EDITOR_STATUS_NORMAL) {
	 if (FPrintf(fh, "   NULL\n"
			 "};\n") == -1L) {
	    status = EDITOR_ERROR_WRITE_FAILED;
	 }
      }
   }
   return(status);
}
	/* Write gadget list to save file*/

   STATIC SHORT
write_gadget_list(BPTR fh, struct TemplateList  *tl, BYTE *id, USHORT count,
							 struct List  *list)
{
   USHORT num = 0;
   SHORT status = EDITOR_STATUS_NORMAL;

   if (list->lh_Head->ln_Succ) {
      if (FPrintf(fh, "IMPORT struct List  %s_gadget%d_list;\n"
		      "%sstruct Node  %s_gadget%d_node[] = {\n"
		      "   {\n", id, count,
		     (tl->tl_Flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
				       "STATIC " : ""), id, count) == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      } else {
	 struct Node  *node = get_head(list);

	 /* Write node array */
	 while (node && status == EDITOR_STATUS_NORMAL) {
	    BYTE *text = node->ln_Name;

	    /* Write node pred */
	    node = get_succ(node);
	    if (node) {
	       if (FPrintf(fh, "      &%s_gadget%d_node[%d], ",
					   &id[0], count, num + 1) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    } else {
	       if (FPrintf(fh, "      (struct Node *)"
		     "&%s_gadget%d_list.lh_Tail, ", &id[0], count) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    }
	    if (status == EDITOR_STATUS_NORMAL) {

	       /* Write node succ */
	       if (num) {
		  if (FPrintf(fh, "&%s_gadget%d_node[%d]",
					   &id[0], count, num - 1) == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  }
	       } else {
		  if (FPrintf(fh, "(struct Node *)&%s_gadget%d_list.lh_Head",
						    &id[0], count) == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  }
	       }
	       if (status == EDITOR_STATUS_NORMAL) {

		  /* Write node text */
		  if (FPrintf(fh, ", 0, 0,\n"
				  "      \"%s\"\n"
				  "   }%s", text,
				      (node ? ", {\n" : "\n};\n")) == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  } else {
		     num++;
		  }
	       }
	    }
	 }
      }
   }
   if (status == EDITOR_STATUS_NORMAL) {

      /* Write list */
      if (FPrintf(fh, "%sstruct List  %s_gadget%d_list = {\n",
		     (tl->tl_Flags & TEMPLATE_LIST_FLAG_SOURCE_STATIC_DATA ?
				 "/* STATIC */ " : ""), id, count) == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      } else {

	 /* Write list head */
	 if (num) {
	    if (FPrintf(fh, "   &%s_gadget%d_node[0], NULL,\n",
							id, count) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	 } else {
	    if (FPrintf(fh, "   (struct Node *)&%s_gadget%d_list.lh_Tail,"
			    " NULL,\n", id, count) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	 }
	 if (status == EDITOR_STATUS_NORMAL) {

	    /* Write list tail */
	    if (num) {
	       if (FPrintf(fh, "   &%s_gadget%d_node[%d]",
					       id, count, num - 1) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    } else {
	       if (FPrintf(fh, "   (struct Node *)&%s_gadget%d_list.lh_Head",
							id, count) == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    }
	    if (status == EDITOR_STATUS_NORMAL) {

	       /* Write list type */
	       if (FPrintf(fh, ", 0, 0\n"
			       "};\n") == -1L) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       }
	    }
	 }
      }
   }
   return(status);
}
	/* Write special gadget data */

   STATIC SHORT
write_gadget_special_data(BPTR fh, BYTE *id, USHORT count,
						     struct GadgetData  *gd)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (FPrintf(fh, "      { ") == -1L) {
      status = EDITOR_ERROR_WRITE_FAILED;
   } else {
      switch (gd->gd_Type) {
	 case GADGET_DATA_TYPE_MX :
	 case GADGET_DATA_TYPE_CYCLE :
	    if (FPrintf(fh, "%ld, %ld, &%s_gadget%d_text_array[0]",
					gd->gd_SpecialData.gd_Data.gd_Data1,
		   gd->gd_SpecialData.gd_Data.gd_Data2, id, count) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	    break;

	 case GADGET_DATA_TYPE_STRING :
	    if (FPrintf(fh, "%ld, %ld, \"%s\"",
					gd->gd_SpecialData.gd_Data.gd_Data1,
					gd->gd_SpecialData.gd_Data.gd_Data2,
			      gd->gd_SpecialData.gd_Data.gd_Data3) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	    break;

	 case GADGET_DATA_TYPE_LISTVIEW :
	    if (FPrintf(fh, "%ld, %ld, &%s_gadget%d_list",
					gd->gd_SpecialData.gd_Data.gd_Data1,
		   gd->gd_SpecialData.gd_Data.gd_Data2, id, count) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	    break;

	 default :
	    if (FPrintf(fh, "%ld, %ld, (VOID *)%ld",
					gd->gd_SpecialData.gd_Data.gd_Data1,
					gd->gd_SpecialData.gd_Data.gd_Data2,
			      gd->gd_SpecialData.gd_Data.gd_Data3) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    }
	    break;
      }
      if (status == EDITOR_STATUS_NORMAL) {
	 if (FPrintf(fh, " }\n"
			 "   }, {\n") == -1L) {
	    status = EDITOR_ERROR_WRITE_FAILED;
	 }
      }
   }
   return(status);
}
	/* Write project test program */

   STATIC SHORT
write_project_program(BPTR fh, struct TemplateList  *tl)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   if (tl->tl_Flags & TEMPLATE_LIST_FLAG_SOURCE_PROGRAM) {
      BYTE   id[MAX_PROJECT_ID_LEN + 1];
      USHORT gads = tl->tl_GadgetTemplates;

      lower_string(&tl->tl_ProjectID[0], &id[0]);
      if (FPrintf(fh,
		"\nstruct Library  *IntuiSupBase;\n\n"
		"\t/* Test program */\n\n"
		"   LONG\n"
		"main(VOID)\n"
		"{\n"
		"   struct Window  *win;\n"
		"   APTR ri%s;\n"
		"\n"
		"   if (IntuiSupBase = OpenLibrary(IntuiSupName,"
		" IntuiSupVersion)) {\n"
		"      if (ri = IGetRenderInfo(NULL, RENDER_INFO_FLAGS)) {\n"
		"         if (win = IOpenWindow(ri, &%s_new_window,"
		" OPEN_WINDOW_FLAGS)) {\n",
				     (gads ? ", gl" : ""), &id[0]) == -1L) {
	 status = EDITOR_ERROR_WRITE_FAILED;
      } else {
	 if (gads && FPrintf(fh,
		"            if (gl = ICreateGadgets(ri,"
		" &%s_gadget_data[0], 0, 0, NULL)) {\n", &id[0]) == -1L) {
	    status = EDITOR_ERROR_WRITE_FAILED;
	 } else {
	    BYTE *gad_y = "   ", *gad_n = "";

	    if (FPrintf(fh,
			"%s            BOOL keepon = TRUE;\n"
			"\n", GADGET_TEXT) == -1L) {
	       status = EDITOR_ERROR_WRITE_FAILED;
	    } else {
	       if ((tl->tl_BorderTemplates && FPrintf(fh,
			"%s            IDisplayBorders(ri, win,"
			" &%s_border_data[0], 0, 0);\n",
					     GADGET_TEXT, &id[0]) == -1L) ||
		   (tl->tl_TextTemplates && FPrintf(fh,
			"%s            IDisplayTexts(ri, win,"
			" &%s_text_data[0], 0, 0, NULL);\n",
					     GADGET_TEXT, &id[0]) == -1L) ||
		   (gads && FPrintf(fh,
			"               IDisplayGadgets(win,"
			" gl);\n") == -1L)) {
		  status = EDITOR_ERROR_WRITE_FAILED;
	       } else {
		  if (FPrintf(fh,
			"%s            do {\n"
			"%s               struct IntuiMessage  *msg;\n\n"
			"%s               WaitPort(win->UserPort);\n"
			"%s               while (msg = IGetMsg(win->UserPort)) {\n"
			"%s                  if (msg->Class == CLOSEWINDOW) {\n"
			"%s                     keepon = FALSE;\n"
			"%s                  }\n"
			"%s                  IReplyMsg(msg);\n"
			"%s               }\n"
			"%s            } while (keepon == TRUE);\n"
			"%s"
			"            ICloseWindow(win, FALSE);\n"
			"         }\n"
			"         IFreeRenderInfo(ri);\n"
			"      }\n"
			"      CloseLibrary(IntuiSupBase);\n"
			"   }\n"
			"   return(0L);\n"
			"}\n",
			 GADGET_TEXT, GADGET_TEXT, GADGET_TEXT, GADGET_TEXT,
			 GADGET_TEXT, GADGET_TEXT, GADGET_TEXT, GADGET_TEXT,
						   GADGET_TEXT, GADGET_TEXT,
			 (gads ? "               IRemoveGadgets(gl);\n"
				 "               IFreeGadgets(gl);\n"
				 "            }\n" : gad_n)) == -1L) {
		     status = EDITOR_ERROR_WRITE_FAILED;
		  }
	       }
	    }
	 }
      }
   }
   return(status);
}
