		/*************************************
		 *                                   *
		 *            Editor v1.0            *
		 *   by Torsten Jürgeleit in 07/91   *
		 *                                   *
		 *           Template part           *
		 *                                   *
		 *************************************/

	/* Includes */

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

	/* Get current template by given ordinal number from list */

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

   for (tp = get_head(&template_list.tl_List); 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);
}
	/* Get current template by given mouse pos from list */

   struct Template *
get_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(&template_list.tl_List); 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;
   SHORT temp;

   if (box->bo_X1 > box->bo_X2) {
      temp       = box->bo_X2;
      box->bo_X2 = box->bo_X1;
      box->bo_X1 = temp;
   }
   if (box->bo_Y1 > box->bo_Y2) {
      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(VOID)
{
   struct TemplateList  *tl = &template_list;
   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(tp, FALSE)) !=
						     EDITOR_STATUS_NORMAL) {
	 free_template(tp);
	 tp = NULL;
      } else {

	 /* Add new template to list and increment counters */
	 AddTail(&tl->tl_List, &tp->tp_Node);
	 tl->tl_ListEntries++;
	 switch (TEMPLATE_GROUP(tp)) {
	    case TEMPLATE_GROUP_BORDER :
	       tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
	       break;

	    case TEMPLATE_GROUP_TEXT :
	       tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
	       break;

	    case TEMPLATE_GROUP_GADGET :
	       tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
	       break;

	 }
	 build_default_template_name(tp);
	 ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
			USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
      }
   }
   show_error(status);
   return(tp);
}
	/* Build default template name */

   VOID
build_default_template_name(struct Template  *tp)
{
   BYTE   *buffer = &tp->tp_TemplateName[0];
   USHORT num = tp->tp_GroupEntryNum;

   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 SPrintf(buffer, "BORDER%d", num);
	 break;

      case TEMPLATE_GROUP_TEXT :
	 SPrintf(buffer, "TEXT%d", num);
	 break;

      case TEMPLATE_GROUP_GADGET :
	 SPrintf(buffer, "GADGET%d", num);
	 break;
   }
   tp->tp_Flags = TEMPLATE_FLAG_DEFAULT_NAME;
}
	/* Init default template data */

   SHORT
init_default_template_data(struct Template  *tp, BOOL default_name)
{
   struct TemplateList  *tl = &template_list;
   struct BorderData    *bd;
   struct TextData      *td;
   struct GadgetData    *gd;
   struct Box           *box = &tp->tp_Box;
   UBYTE  group = TEMPLATE_GROUP(tp);
   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(tp);
   }

   /* Init default font */
   CopyMem((BYTE *)&topaz80_attr, (BYTE *)&tp->tp_TextAttr, (LONG)
						   sizeof(struct TextAttr));
   if ((status = duplicate_string((BYTE **)&tp->tp_TextAttr.ta_Name,
		(BYTE *)tp->tp_TextAttr.ta_Name)) == EDITOR_STATUS_NORMAL) {

      /* Init default template data */
      switch (group) {
	 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;
	    td->td_TextAttr = &tp->tp_TextAttr;
	    if ((status = duplicate_string(&td->td_Text, "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;
	    gd->gd_TextAttr = &tp->tp_TextAttr;
	    switch (gd->gd_Type) {
	       case GADGET_DATA_TYPE_BUTTON :
		  status = duplicate_string(&gd->gd_Text, "Button");
		  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(&gd->gd_SpecialData.gd_InputData.gd_InputDefault, "String");
		  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 Template  *old_tp, BOOL full_clone)
{
   struct TemplateList  *tl = &template_list;
   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(old_tp, new_tp)) !=
						     EDITOR_STATUS_NORMAL) {
	 free_template(new_tp);
	 new_tp = NULL;
      } else {
	 if (full_clone == FALSE) {

	    /* Add new template to list and increment counters */
	    AddTail(&tl->tl_List, &new_tp->tp_Node);
	    tl->tl_ListEntries++;
	    switch (TEMPLATE_GROUP(new_tp)) {
	       case TEMPLATE_GROUP_BORDER :
		  new_tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
		  break;

	       case TEMPLATE_GROUP_TEXT :
		  new_tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
		  break;

	       case TEMPLATE_GROUP_GADGET :
		  new_tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
		  break;
	    }
	    build_default_template_name(new_tp);
	    ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
			USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
	 }
      }
   }
   show_error(status);
   return(new_tp);
}
	/* Clone template data */

   STATIC SHORT
clone_template_data(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 */
   new_tp->tp_TextAttr.ta_Name = NULL;
   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;
	 }
	 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;
	 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 */
   if ((status = duplicate_string((BYTE **)&new_tp->tp_TextAttr.ta_Name,
	    (BYTE *)old_tp->tp_TextAttr.ta_Name)) == EDITOR_STATUS_NORMAL) {
      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;
	    new_td->td_TextAttr = &new_tp->tp_TextAttr;
	    if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
	       status = duplicate_string(&new_td->td_Text, old_td->td_Text);
	    }
	    break;

	 case TEMPLATE_GROUP_GADGET :
	    new_gd->gd_LeftEdge = box->bo_X1;
	    new_gd->gd_TopEdge  = box->bo_Y1;
	    new_gd->gd_TextAttr = &new_tp->tp_TextAttr;
	    if ((status = duplicate_string(&new_gd->gd_Text,
				old_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(&new_gd->gd_SpecialData.gd_InputData.gd_InputDefault, old_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 GadgetData  *gd;
   struct TextFont    *tf;
   APTR   gl;
   USHORT *dim;

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

      case TEMPLATE_GROUP_TEXT :
	 tf = open_font(&tp->tp_TextAttr);
	 IDisplayTexts(pri, pwin, &tp->tp_Data.tp_TextData, 0, 0);
	 close_font(tf);
	 break;

      case TEMPLATE_GROUP_GADGET :
	 gd = &tp->tp_Data.tp_GadgetData;
	 if (!(gl = ICreateGadgets(pri, gd, 0, 0))) {
	    show_error(EDITOR_ERROR_OUT_OF_MEM);
	 } else {
	    IDisplayGadgets(pwin, gl);

	    /* Update template box with gadget size */
	    dim = (USHORT *)(IGadgetAddress(gl, 0) + 1);
	    switch (gd->gd_Type) {
	       case GADGET_DATA_TYPE_CHECK :
	       case GADGET_DATA_TYPE_MX :
	       case GADGET_DATA_TYPE_PALETTE :
	       case GADGET_DATA_TYPE_LISTVIEW :
		  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;

	       case GADGET_DATA_TYPE_STRING :
	       case GADGET_DATA_TYPE_INTEGER :
		  tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
		  if (gd->gd_Flags & GADGET_DATA_FLAG_NO_BORDER) {
		     tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
		  } else {
		     tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] + 5;
		  }
		  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(&tl->tl_List); tp; tp = get_succ(&tp->tp_Node)) {
	 if (TEMPLATE_GROUP(tp) != TEMPLATE_GROUP_GADGET) {
	    display_template(tp);
	 }
      }
   } else {
      for (tp = get_head(&tl->tl_List); tp; tp = get_succ(&tp->tp_Node)) {
	 display_template(tp);
      }
   }
}
	/* Free template list */

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

   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;
      }
      tl->tl_ListEntries--;
      free_template(tp);
   }
   tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
   MWCheck();
}
	/* Free template */

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

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

   DosFreeMem(tp->tp_TextAttr.ta_Name);
   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 break;

      case TEMPLATE_GROUP_TEXT :
	 td = &tp->tp_Data.tp_TextData;
	 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;
	 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);
   tl->tl_ListEntries--;
   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(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(tp);
	 }
      }
   }
   ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, USE_CURRENT_VALUE,
					   USE_CURRENT_VALUE, &tl->tl_List);
   refresh_all_templates();
   tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
}
