/* $Revision Header *** Header built automatically - do not edit! ***********
 *
 *	(C) Copyright 1991 by Torsten Jürgeleit
 *
 *	Name .....: template.c
 *	Created ..: Sunday 22-Dec-91 21:23:14
 *	Revision .: 2
 *
 *	Date        Author                 Comment
 *	=========   ====================   ====================
 *	22-Apr-91   Torsten Jürgeleit      changed get_template_by_xxx to
 *                                         select_template_by_xxx
 *	31-Dec-91   Torsten Jürgeleit      new font management
 *	22-Dec-91   Torsten Jürgeleit      Created this file!
 *
 ****************************************************************************
 *
 *	Template part
 *
 * $Revision Header ********************************************************/

	/* Includes */

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

	/* Select template by given ordinal number from list */

   struct Template *
select_template_by_num(LONG num)
{
   struct Template  *tp;

   for (tp = get_head((struct List *)&template_list.tl_Templates); tp;
					      tp = get_succ(&tp->tp_Node)) {
      if (!num--) {
	 CopyMem((BYTE *)&tp->tp_Box, (BYTE *)&current_box, (LONG)
							sizeof(struct Box));
	 break;
      }
   }
   selected_template = tp;
   return(tp);
}
	/* Select template by given mouse pos from list */

   struct Template *
select_template_by_pos(SHORT x, SHORT y)
{
   struct Template  *tp;

   if (tp = find_template_by_pos(x, y)) {
      CopyMem((BYTE *)&tp->tp_Box, (BYTE *)&current_box, (LONG)
							sizeof(struct Box));
   }
   selected_template = tp;
   return(tp);
}
	/* Find template by given mouse pos from list */

   struct Template *
find_template_by_pos(SHORT x, SHORT y)
{
   struct Template  *tp;
   struct Box       *box;

   /* First check info template */
   if (info_displayed == TRUE) {
      tp  = info_template;
      box = &tp->tp_Box;
      if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
							       box->bo_Y2) {
	 return(tp);
      }
   }

   /* Now check templates in list (from last to first) */
   for (tp = get_tail((struct List *)&template_list.tl_Templates); tp;
					      tp = get_pred(&tp->tp_Node)) {
      box = &tp->tp_Box;
      if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
							       box->bo_Y2) {
	 return(tp);
      }
   }
   return(NULL);
}
	/* Fix bounds of current template */

   VOID
fix_template_bounds(VOID)
{
   struct Box  *box = &current_box;

   if (box->bo_X1 > box->bo_X2) {
      SHORT temp = box->bo_X2;

      box->bo_X2 = box->bo_X1;
      box->bo_X1 = temp;
   }
   if (box->bo_Y1 > box->bo_Y2) {
      SHORT temp = box->bo_Y2;

      box->bo_Y2 = box->bo_Y1;
      box->bo_Y1 = temp;
   }
   if (box->bo_X1 < 0) {
      box->bo_X1 = 0;
   }
   if (box->bo_Y1 < 0) {
      box->bo_Y1 = 0;
   }
   if (box->bo_X2 > pwin->Width) {
      box->bo_X2 = pwin->Width;
   }
   if (box->bo_Y2 > pwin->Height) {
      box->bo_Y2 = pwin->Height;
   }
}
	/* Get modify mode from selected position */

   USHORT
get_modify_mode(SHORT x, SHORT y)
{
   struct Template  *tp = selected_template;
   struct Box       *box = &tp->tp_Box;
   UBYTE  type = tp->tp_Type;
   USHORT part_width  = (box->bo_X2 - box->bo_X1) / 8,
	  part_height = (box->bo_Y2 - box->bo_Y1) / 4,
	  modify_mode = MODIFY_MODE_MOVE;

   if (type != TEMPLATE_TYPE_TEXT && type != TEMPLATE_TYPE_CHECK &&
						 type != TEMPLATE_TYPE_MX) {
      if (x >= (box->bo_X2 - part_width) && x <= box->bo_X2 &&
		       y >= (box->bo_Y2 - part_height) && y <= box->bo_Y2) {
	 modify_mode = MODIFY_MODE_RESIZE;
      }
   }
   return(modify_mode);
}
	/* Create new template and add it to template list */

   struct Template *
create_template(struct TemplateList  *tl)
{
   struct Template  *tp;
   SHORT status = EDITOR_STATUS_NORMAL;

   if (!(tp = AllocMem((LONG)sizeof(struct Template),
					 (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
      status = EDITOR_ERROR_OUT_OF_MEM;
   } else {

      /* Init template */
      tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
      tp->tp_Type         = template_type;
      CopyMem((BYTE *)&current_box, (BYTE *)&tp->tp_Box, (LONG)
							sizeof(struct Box));
      NewList(&tp->tp_TextList);
      if ((status = init_default_template_data(tl, tp, FALSE)) !=
						     EDITOR_STATUS_NORMAL) {
	 free_template(tl, tp);
	 tp = NULL;
      } else {

	 /* Add new template to list and refresh list view */
	 add_template_to_list(tl, tp, TRUE);
	 ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
		   USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
      }
   }
   show_error(status);
   return(tp);
}
	/* Add template to list */

   VOID
add_template_to_list(struct TemplateList  *tl, struct Template  *tp,
							  BOOL default_name)
{
   struct List  *list = (struct List *)&tl->tl_Templates;
   USHORT num, pos;

   /* Get group data */
   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 num = ++tl->tl_BorderTemplates;
	 pos = num - 1;
	 break;

      case TEMPLATE_GROUP_TEXT :
	 num = ++tl->tl_TextTemplates;
	 pos = tl->tl_BorderTemplates + num - 1;
	 break;

      case TEMPLATE_GROUP_GADGET :
	 num = ++tl->tl_GadgetTemplates;
	 pos = tl->tl_BorderTemplates + tl->tl_TextTemplates + num - 1;
	 break;
   }

   /* Init template and insert it into template list */
   tp->tp_GroupEntryNum = num;
   if (default_name == TRUE) {
      build_default_template_name(tl, tp);
   }
   Insert(list, &tp->tp_Node, (pos ? get_node(list, pos - 1) : NULL));
}
	/* Build default template name */

   VOID
build_default_template_name(struct TemplateList  *tl, struct Template  *tp)
{
   BYTE *fmt;

   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 fmt = "BORDER%d";
	 break;

      case TEMPLATE_GROUP_TEXT :
	 fmt = "TEXT%d";
	 break;

      case TEMPLATE_GROUP_GADGET :
	 fmt = "GADGET%d";
	 break;
   }
   SPrintf(&tp->tp_TemplateName[0], fmt, tp->tp_GroupEntryNum);
   tp->tp_Flags = TEMPLATE_FLAG_DEFAULT_NAME;
}
	/* Init default template data */

   SHORT
init_default_template_data(struct TemplateList  *tl, struct Template  *tp,
							  BOOL default_name)
{
   struct Box         *box = &tp->tp_Box;
   struct BorderData  *bd;
   struct TextData    *td;
   struct GadgetData  *gd;
   USHORT width = box->bo_X2 - box->bo_X1 + 1,
	  height = box->bo_Y2 - box->bo_Y1 + 1;
   SHORT  status = EDITOR_STATUS_NORMAL;

   /* Init default template name */
   if (default_name == TRUE) {
      build_default_template_name(tl, tp);
   }

   /* Init default template data */
   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 bd              = &tp->tp_Data.tp_BorderData;
	 bd->bd_Type     = BORDER_DATA_TYPE_BOX2_IN;
	 bd->bd_LeftEdge = box->bo_X1;
	 bd->bd_TopEdge  = box->bo_Y1;
	 bd->bd_Width    = width;
	 bd->bd_Height   = height;

	 /* Mark end of border data */
	 (bd + 1)->bd_Type = INTUISUP_DATA_END;
         break;

      case TEMPLATE_GROUP_TEXT :
	 td              = &tp->tp_Data.tp_TextData;
	 td->td_Type     = TEXT_DATA_TYPE_TEXT;
	 td->td_Flags    = 0;
	 td->td_LeftEdge = box->bo_X1;
	 td->td_TopEdge  = box->bo_Y1;
	 if (!(td->td_TextAttr = open_template_font_by_attributes(tl,
				  DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE))) {
	    status = EDITOR_ERROR_INVALID_FONT;
	 } else {
	    if ((status = duplicate_string("Text", &td->td_Text)) ==
						     EDITOR_STATUS_NORMAL) {
	       /* Calc size of text for template box */
	       box        = &tp->tp_Box;
	       box->bo_X2 = box->bo_X1 + IPrintText(pri, pwin, td->td_Text,
			       td->td_LeftEdge, td->td_TopEdge, td->td_Type,
			      TEXT_DATA_FLAG_NO_PRINT, td->td_TextAttr) - 1;
	       box->bo_Y2 = box->bo_Y1 + td->td_TextAttr->ta_YSize - 1;
	    }

	    /* Mark end of text data */
	    (td + 1)->td_Type = INTUISUP_DATA_END;
	 }
	 break;

      case TEMPLATE_GROUP_GADGET :
	 gd              = &tp->tp_Data.tp_GadgetData;
	 gd->gd_Type     = tp->tp_Type - FIRST_GADGET_TEMPLATE_TYPE + 1;
	 gd->gd_Flags    = 0;
	 gd->gd_LeftEdge = box->bo_X1;
	 gd->gd_TopEdge  = box->bo_Y1;
	 gd->gd_Width    = width;
	 gd->gd_Height   = height;
	 gd->gd_Text     = NULL;
	 if (!(gd->gd_TextAttr = open_template_font_by_attributes(tl,
				  DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE))) {
	    status = EDITOR_ERROR_INVALID_FONT;
	 } else {
	    switch (gd->gd_Type) {
	       case GADGET_DATA_TYPE_BUTTON :
		  status = duplicate_string("Button", &gd->gd_Text);
		  break;

	       case GADGET_DATA_TYPE_CHECK :
		  gd->gd_SpecialData.gd_CheckData.gd_CheckSelected = 1;
		  break;

	       case GADGET_DATA_TYPE_MX :
		  gd->gd_Flags                                 |= GADGET_DATA_FLAG_TEXT_LEFT;
		  gd->gd_SpecialData.gd_MXData.gd_MXSpacing     = 1;
		  gd->gd_SpecialData.gd_MXData.gd_MXActiveEntry = 0;
		  if ((status = build_template_text_list(tp,
					      &default_mx_text_array[0])) ==
						     EDITOR_STATUS_NORMAL) {
		     status = build_template_text_array(tp);
		  }
		  break;

	       case GADGET_DATA_TYPE_STRING :
		  gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
		  gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
		  gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
		  status = duplicate_string("String",
			  &gd->gd_SpecialData.gd_InputData.gd_InputDefault);
		  break;

	       case GADGET_DATA_TYPE_INTEGER :
		  gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
		  gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
		  gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
		  gd->gd_SpecialData.gd_InputData.gd_InputDefault      = (BYTE *)123;
		  break;

	       case GADGET_DATA_TYPE_SLIDER :
		  if (width / 2 < height) {
		     gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
		  }
		  gd->gd_SpecialData.gd_SliderData.gd_SliderMin   = 0;
		  gd->gd_SpecialData.gd_SliderData.gd_SliderMax   = 10;
		  gd->gd_SpecialData.gd_SliderData.gd_SliderLevel = 5;
		  break;

	       case GADGET_DATA_TYPE_SCROLLER :
		  if (width / 2 < height) {
		     gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
		  }
		  gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible = 2;
		  gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal   = 10;
		  gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTop     = 5;
		  break;

	       case GADGET_DATA_TYPE_CYCLE :
		  gd->gd_SpecialData.gd_CycleData.gd_CycleActive = 0;
		  if ((status = build_template_text_list(tp,
					   &default_cycle_text_array[0])) ==
						     EDITOR_STATUS_NORMAL) {
		     status = build_template_text_array(tp);
		  }
		  break;

	       case GADGET_DATA_TYPE_COUNT :
		  gd->gd_SpecialData.gd_CountData.gd_CountMin   = 10;
		  gd->gd_SpecialData.gd_CountData.gd_CountMax   = 50;
		  gd->gd_SpecialData.gd_CountData.gd_CountValue = 30;
		  break;

	       case GADGET_DATA_TYPE_LISTVIEW :
		  gd->gd_Flags                                         |= GADGET_DATA_FLAG_TEXT_ABOVE;
		  gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing = 0;
		  gd->gd_SpecialData.gd_ListViewData.gd_ListViewTop     = 0;
		  gd->gd_SpecialData.gd_ListViewData.gd_ListViewList    = &tp->tp_TextList;
		  status = build_template_text_list(tp,
					   &default_listview_text_array[0]);
		  break;

	       case GADGET_DATA_TYPE_PALETTE :
		  if (width / 2 < height) {
		     gd->gd_Flags |= GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
		  }
		  gd->gd_Flags                                           |= GADGET_DATA_FLAG_TEXT_ABOVE;
		  gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth       = 2;
		  gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset = 0;
		  gd->gd_SpecialData.gd_PaletteData.gd_PaletteActiveColor = 2;
		  break;
	    }

	    /* Mark end of gadget data */
	    (gd + 1)->gd_Type = INTUISUP_DATA_END;
	 }
	 break;
   }
   return(status);
}
	/* Clone template and optional add it to template list */

   struct Template *
clone_template(struct TemplateList  *tl, struct Template  *old_tp,
							    BOOL full_clone)
{
   struct Template  *new_tp;
   SHORT status = EDITOR_STATUS_NORMAL;

   if (!(new_tp = AllocMem((LONG)sizeof(struct Template),
					 (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
      status = EDITOR_ERROR_OUT_OF_MEM;
   } else {

      /* Init template */
      CopyMem((BYTE *)old_tp, (BYTE *)new_tp, (LONG)sizeof(struct Template));
      new_tp->tp_Node.ln_Name = &new_tp->tp_TemplateName[0];
      NewList(&new_tp->tp_TextList);
      if (full_clone == FALSE) {
	 CopyMem((BYTE *)&current_box, (BYTE *)&new_tp->tp_Box, (LONG)
							sizeof(struct Box));
      }
      if ((status = clone_template_data(tl, old_tp, new_tp)) !=
						     EDITOR_STATUS_NORMAL) {
	 free_template(tl, new_tp);
	 new_tp = NULL;
      } else {
	 if (full_clone == FALSE) {

	    /* Add new template to list and refresh list view */
	    add_template_to_list(tl, new_tp, TRUE);
	    ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
		   USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
	 }
      }
   }
   show_error(status);
   return(new_tp);
}
	/* Clone template data */

   STATIC SHORT
clone_template_data(struct TemplateList  *tl, struct Template  *old_tp,
						   struct Template  *new_tp)
{
   struct BorderData  *new_bd;
   struct TextData    *old_td, *new_td;
   struct GadgetData  *old_gd, *new_gd;
   struct Box         *box = &new_tp->tp_Box;
   SHORT status = EDITOR_STATUS_NORMAL;

   /* Clear data pointers */
   switch (TEMPLATE_GROUP(new_tp)) {
      case TEMPLATE_GROUP_BORDER :
	 new_bd = &new_tp->tp_Data.tp_BorderData;
         break;

      case TEMPLATE_GROUP_TEXT :
	 old_td = &old_tp->tp_Data.tp_TextData;
	 new_td = &new_tp->tp_Data.tp_TextData;
	 if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
	    new_td->td_Text = NULL;
	 }
	 new_td->td_TextAttr = NULL;
	 break;

      case TEMPLATE_GROUP_GADGET :
	 old_gd              = &old_tp->tp_Data.tp_GadgetData;
	 new_gd              = &new_tp->tp_Data.tp_GadgetData;
	 new_gd->gd_Text     = NULL;
	 new_gd->gd_TextAttr = NULL;
	 switch (new_gd->gd_Type) {
	    case GADGET_DATA_TYPE_BUTTON :
	    case GADGET_DATA_TYPE_CHECK :
	    case GADGET_DATA_TYPE_INTEGER :
	    case GADGET_DATA_TYPE_SLIDER :
	    case GADGET_DATA_TYPE_SCROLLER :
	    case GADGET_DATA_TYPE_COUNT :
	    case GADGET_DATA_TYPE_PALETTE :
	       break;

	    case GADGET_DATA_TYPE_MX :
	       new_gd->gd_SpecialData.gd_MXData.gd_MXTextArray = NULL;
	       break;

	    case GADGET_DATA_TYPE_CYCLE :
	       new_gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = NULL;
	       break;

	    case GADGET_DATA_TYPE_STRING :
	       new_gd->gd_SpecialData.gd_InputData.gd_InputDefault = NULL;
	       break;

	    case GADGET_DATA_TYPE_LISTVIEW :
	       new_gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &new_tp->tp_TextList;
	       break;
	 }
	 break;
   }

   /* Allocate new data */
   switch (TEMPLATE_GROUP(new_tp)) {
      case TEMPLATE_GROUP_BORDER :
	 new_bd->bd_LeftEdge = box->bo_X1;
	 new_bd->bd_TopEdge  = box->bo_Y1;
	 break;

      case TEMPLATE_GROUP_TEXT :
	 new_td->td_LeftEdge = box->bo_X1;
	 new_td->td_TopEdge  = box->bo_Y1;
	 if (!(new_td->td_TextAttr = open_template_font_by_attributes(tl,
				       (BYTE *)old_td->td_TextAttr->ta_Name,
					  old_td->td_TextAttr->ta_YSize))) {
	    status = EDITOR_ERROR_INVALID_FONT;
	 } else {
	    if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
	       status = duplicate_string(old_td->td_Text, &new_td->td_Text);
	    }
	 }
	 break;

      case TEMPLATE_GROUP_GADGET :
	 new_gd->gd_LeftEdge = box->bo_X1;
	 new_gd->gd_TopEdge  = box->bo_Y1;
	 if (!(new_gd->gd_TextAttr = open_template_font_by_attributes(tl,
				       (BYTE *)old_gd->gd_TextAttr->ta_Name,
					  old_gd->gd_TextAttr->ta_YSize))) {
	    status = EDITOR_ERROR_INVALID_FONT;
	 } else {
	    if ((status = duplicate_string(old_gd->gd_Text,
			       &new_gd->gd_Text)) == EDITOR_STATUS_NORMAL) {
	       switch (new_gd->gd_Type) {
		  case GADGET_DATA_TYPE_BUTTON :
		  case GADGET_DATA_TYPE_CHECK :
		  case GADGET_DATA_TYPE_INTEGER :
		  case GADGET_DATA_TYPE_SLIDER :
		  case GADGET_DATA_TYPE_SCROLLER :
		  case GADGET_DATA_TYPE_COUNT :
		  case GADGET_DATA_TYPE_PALETTE :
		     break;

		  case GADGET_DATA_TYPE_MX :
		  case GADGET_DATA_TYPE_CYCLE :
		     if ((status = duplicate_text_list(old_tp, new_tp)) ==
						     EDITOR_STATUS_NORMAL) {
			status = build_template_text_array(new_tp);
		     }
		     break;

		  case GADGET_DATA_TYPE_STRING :
		     status = duplicate_string(old_gd->gd_SpecialData.gd_InputData.gd_InputDefault, &new_gd->gd_SpecialData.gd_InputData.gd_InputDefault);
		     break;

		  case GADGET_DATA_TYPE_LISTVIEW :
		     status = duplicate_text_list(old_tp, new_tp);
		     break;
	       }
	    }
	 }
	 break;
   }
   return(status);
}
	/* Display template */

   VOID
display_template(struct Template  *tp)
{
   struct TextData    *td;
   struct GadgetData  *gd;
   APTR gl;

   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 IDisplayBorders(pri, pwin, &tp->tp_Data.tp_BorderData, 0, 0);
	 break;

      case TEMPLATE_GROUP_TEXT :
	 td = &tp->tp_Data.tp_TextData;
	 IDisplayTexts(pri, pwin, td, 0, 0, NULL);
	 break;

      case TEMPLATE_GROUP_GADGET :
	 gd = &tp->tp_Data.tp_GadgetData;
	 if (!(gl = ICreateGadgets(pri, gd, 0, 0, NULL))) {
	    show_error(EDITOR_ERROR_OUT_OF_MEM);
	 } else {
	    USHORT *dim = (USHORT *)(IGadgetAddress(gl, 0) + 1);

	    /* Update template box with gadget size */
	    IDisplayGadgets(pwin, gl);
	    switch (gd->gd_Type) {
	       case GADGET_DATA_TYPE_CHECK :
	       case GADGET_DATA_TYPE_MX :
	       case GADGET_DATA_TYPE_PALETTE :
	       case GADGET_DATA_TYPE_LISTVIEW :
	       case GADGET_DATA_TYPE_STRING :
	       case GADGET_DATA_TYPE_INTEGER :
		  tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
		  tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
		  break;
	    }
	    IRemoveGadgets(gl);
	    IFreeGadgets(gl);
	 }
	 break;
   }
}
	/* Refresh all templates */

   VOID
refresh_all_templates(VOID)
{
   struct TemplateList  *tl = &template_list;
   struct Template      *tp;

   clear_project_window(tl->tl_Flags);
   print_project_window_title();
   if (editor_mode == EDITOR_MODE_USE) {
      IRefreshGadgets(use_gl);

      /* Refresh non gadget templates */
      for (tp = get_head((struct List *)&tl->tl_Templates); tp;
					      tp = get_succ(&tp->tp_Node)) {
	 if (TEMPLATE_GROUP(tp) != TEMPLATE_GROUP_GADGET) {
	    display_template(tp);
	 }
      }
   } else {
      for (tp = get_head((struct List *)&tl->tl_Templates); tp;
					      tp = get_succ(&tp->tp_Node)) {
	 display_template(tp);
      }
   }
}
	/* Free template list */

   VOID
free_template_list(struct TemplateList  *tl)
{
   struct Template  *tp;
   struct List      *list = (struct List *)&tl->tl_Templates;

   free_font_list(tl);
   while (tp = (struct Template *)RemHead(list)) {
      switch (TEMPLATE_GROUP(tp)) {
	 case TEMPLATE_GROUP_BORDER :
	    tl->tl_BorderTemplates--;
	    break;

	 case TEMPLATE_GROUP_TEXT :
	    tl->tl_TextTemplates--;
	    break;

	 case TEMPLATE_GROUP_GADGET :
	    tl->tl_GadgetTemplates--;
	    break;
      }
      free_template(tl, tp);
   }
   tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
   MWCheck();
}
	/* Free template */

   VOID
free_template(struct TemplateList  *tl, struct Template  *tp)
{
   if (tl && tp) {
      free_template_data(tl, tp);
      FreeMem(tp, (LONG)sizeof(struct Template));
   }
}
	/* Free template data */

   VOID
free_template_data(struct TemplateList  *tl, struct Template  *tp)
{
   struct TextData    *td;
   struct GadgetData  *gd;

   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 break;

      case TEMPLATE_GROUP_TEXT :
	 td = &tp->tp_Data.tp_TextData;
	 close_template_font(tl, td->td_TextAttr);
	 if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
	    DosFreeMem(td->td_Text);
	 }
	 td->td_Text = NULL;
	 break;

      case TEMPLATE_GROUP_GADGET :
	 gd = &tp->tp_Data.tp_GadgetData;
	 close_template_font(tl, gd->gd_TextAttr);
	 DosFreeMem(gd->gd_Text);
	 gd->gd_Text = NULL;
	 switch (gd->gd_Type) {
	    case GADGET_DATA_TYPE_BUTTON :
	    case GADGET_DATA_TYPE_CHECK :
	    case GADGET_DATA_TYPE_INTEGER :
	    case GADGET_DATA_TYPE_SLIDER :
	    case GADGET_DATA_TYPE_SCROLLER :
	    case GADGET_DATA_TYPE_COUNT :
	    case GADGET_DATA_TYPE_PALETTE :
	       break;

	    case GADGET_DATA_TYPE_MX :
	    case GADGET_DATA_TYPE_CYCLE :
	       free_template_text_array(tp);
	    case GADGET_DATA_TYPE_LISTVIEW :
	       free_template_text_list(tp);
	       break;

	    case GADGET_DATA_TYPE_STRING :
	       DosFreeMem(gd->gd_SpecialData.gd_InputData.gd_InputDefault);
	       break;
	 }
	 break;
   }
}
	/* Delete template */

   VOID
delete_template(struct Template  *tp)
{
   struct TemplateList  *tl = &template_list;
   struct Template      *succ_tp;
   UBYTE group = TEMPLATE_GROUP(tp);

   /* Remove template from list, decrement counters and free template */
   succ_tp = get_succ(&tp->tp_Node);
   Remove(&tp->tp_Node);
   switch (group) {
      case TEMPLATE_GROUP_BORDER :
	 tl->tl_BorderTemplates--;
	 break;

      case TEMPLATE_GROUP_TEXT :
	 tl->tl_TextTemplates--;
	 break;

      case TEMPLATE_GROUP_GADGET :
	 tl->tl_GadgetTemplates--;
	 break;
   }
   free_template(tl, tp);

   /* Update default template names and refresh template list */
   for (tp = succ_tp; tp; tp = get_succ(&tp->tp_Node)) {
      if (TEMPLATE_GROUP(tp) == group) {
	 tp->tp_GroupEntryNum--;
	 if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME) {
	    build_default_template_name(tl, tp);
	 }
      }
   }
   ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
		   USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
   refresh_all_templates();
   tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
}
