		/*************************************
		 *                                   *
		 *             Editor v1.0           *
		 *   by Torsten Jürgeleit in 08/91   *
		 *                                   *
		 *             Edit part 2           *
		 *                                   *
		 *************************************/

	/* Includes */

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

	/* Defines */

#define EDIT_MODE_NORMAL	1
#define EDIT_MODE_SPECIAL	2

	/* Defines */

#define EDIT_TITLE_LEFT_EDGE	0
#define EDIT_TITLE_TOP_EDGE	5
#define EDIT_TITLE_TYPE		TEXT_DATA_TYPE_TEXT
#define EDIT_TITLE_FLAGS	(TEXT_DATA_FLAG_CENTER | TEXT_DATA_FLAG_BOLD)
#define EDIT_TITLE_TEXT_ATTR	&topaz80_attr

	/* Edit template data */

   SHORT
edit_template_data_action(struct Template  *old_tp, APTR normal_gl,
			   APTR special_gl1, APTR special_gl2, APTR edit_gl)
{
   struct TemplateList  *tl = &template_list;
   struct Template      *pred_tp, *new_tp, *swap_tp;
   struct MsgPort       *up = ewin->UserPort;
   struct IntuiMessage  *msg;
   APTR   gl;
   BYTE   title[80];
   USHORT entry, mode = EDIT_MODE_NORMAL, new_mode = EDIT_MODE_NORMAL;
   ULONG  value;
   BOOL   keepon, exit = FALSE;
   SHORT  status = EDITOR_STATUS_NORMAL;

   /* Make clone of selected template and remove it from template list */
   if (!(new_tp = clone_template(old_tp, TRUE))) {
      status = EDITOR_ERROR_OUT_OF_MEM;
   } else {
      pred_tp = get_pred(&old_tp->tp_Node);   /* needed for Insert() */
      Remove(&old_tp->tp_Node);

      /* Outer loop */
      do {

	 /* Init title text */
	 switch (TEMPLATE_GROUP(old_tp)) {
	    case TEMPLATE_GROUP_BORDER :
	       strcpy(&title[0], "Edit Border Data");
	       break;
	    case TEMPLATE_GROUP_TEXT :
	       strcpy(&title[0], "Edit Text Data");
	       break;
	    case TEMPLATE_GROUP_GADGET :
	       if (mode == EDIT_MODE_NORMAL) {
		  SPrintf(&title[0], "Edit normal %s Gadget Data",
				 template_type_text_array[old_tp->tp_Type]);
	       } else {
		  SPrintf(&title[0], "Edit special %s Gadget Data",
				 template_type_text_array[old_tp->tp_Type]);
	       }
	       break;
	 }

	 /* Init edit display */
	 IClearRenderWindow(eri, ewin, 0, 0, -1, -1);
	 IPrintText(eri, ewin, &title[0], EDIT_TITLE_LEFT_EDGE,
		     EDIT_TITLE_TOP_EDGE, EDIT_TITLE_TYPE, EDIT_TITLE_FLAGS,
						      EDIT_TITLE_TEXT_ATTR);
	 if (mode == EDIT_MODE_NORMAL) {
	    IDisplayGadgets(ewin, normal_gl);
	 } else {
	    if (special_gl1) {
	       ISetGadgetAttributes(special_gl1, 0, 0L, USE_CURRENT_VALUE,
				   USE_CURRENT_VALUE, &new_tp->tp_TextList);
	       change_text_list_editor_mode(special_gl1, DEFAULT_LIST_MODE);
	       IDisplayGadgets(ewin, special_gl1);
	    }
	    if (special_gl2) {
	       IDisplayGadgets(ewin, special_gl2);
	    }
	 }
	 IDisplayGadgets(ewin, edit_gl);

	 /* Inner loop */
	 keepon = TRUE;
	 do {
	    WaitPort(up);
	    while (msg = IGetMsg(up)) {
	       switch (msg->Class) {
		  case CLOSEWINDOW :
		     status = EDITOR_STATUS_QUIT;
		     keepon = FALSE;
		     exit   = TRUE;
		     break;
		  case ISUP_ID :
		     gl    = (APTR)msg->SpecialLink;
		     entry = msg->Code;
		     value = (ULONG)msg->IAddress;
		     if (gl == edit_gl) {

			/* Perform edit gadget action */
			switch (entry) {
			   case EDIT_GADGET_OK :
			      exit = TRUE;
			      break;
			   case EDIT_GADGET_DEFAULT :
			      free_template_data(new_tp);
			      if ((status = init_default_template_data(new_tp,
					   TRUE)) != EDITOR_STATUS_NORMAL) {
				 swap_tp = old_tp;
				 old_tp  = new_tp;
				 new_tp  = swap_tp;
			      } else {
				 tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
			      }
			      exit = TRUE;
			      break;
			   case EDIT_GADGET_SWITCH :
			      if (mode == EDIT_MODE_NORMAL) {
				 new_mode = EDIT_MODE_SPECIAL;
			      } else {
				 new_mode = EDIT_MODE_NORMAL;
			      }
			      break;
			   case EDIT_GADGET_CANCEL :
			      swap_tp = old_tp;
			      old_tp  = new_tp;
			      new_tp  = swap_tp;
			      exit    = TRUE;
			      break;
			}
			keepon = FALSE;
		     } else {

			/* Perform data gadget action */
			if (mode == EDIT_MODE_NORMAL) {
			   if ((status = change_normal_template_data(normal_gl,
						   new_tp, entry, value)) !=
						     EDITOR_STATUS_NORMAL) {
			      keepon = FALSE;
			      exit   = TRUE;
			   }
			} else {
			   if (gl = special_gl1) {
			      status = perform_text_list_editor_action(special_gl1,
						      new_tp, entry, value);
			   } else {
			      status = change_special_template_data(special_gl2,
						      new_tp, entry, value);

			   }
			   if (status != EDITOR_STATUS_NORMAL) {
			      keepon = FALSE;
			      exit   = TRUE;
			   }
			}
			tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
		     }
		     break;
	       }
	       IReplyMsg(msg);
	    }
	 } while (keepon == TRUE);

	 IRemoveGadgets(edit_gl);
	 if (mode == EDIT_MODE_NORMAL) {
	    IRemoveGadgets(normal_gl);
	 } else {
	    if (special_gl1) {
	       IRemoveGadgets(special_gl1);
	    }
	    if (special_gl2) {
	       IRemoveGadgets(special_gl2);
	    }
	 }
	 if (new_mode != mode) {
	    mode = new_mode;
	 }
      } while (exit == FALSE);

      /* Insert new template in list and free old one */
      Insert(&tl->tl_List, &new_tp->tp_Node, &pred_tp->tp_Node);
      ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
			USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
      free_template(old_tp);
      refresh_all_templates();
   }
   show_error(status);
   MWCheck();
   return(status);
}
	/* Change normal template data */

   SHORT
change_normal_template_data(APTR gl, struct Template  *tp, USHORT entry,
								ULONG value)
{
   struct Box         *box = &tp->tp_Box;
   struct BorderData  *bd;
   struct TextData    *td;
   struct GadgetData  *gd;
   struct TextFont    *tf;
   BYTE   *old_text, buffer[40];
   USHORT old_type, old_pos;
   UWORD  old_size;
   SHORT  status = EDITOR_STATUS_NORMAL;

   switch (TEMPLATE_GROUP(tp)) {
      case TEMPLATE_GROUP_BORDER :
	 bd = &tp->tp_Data.tp_BorderData;
	 switch (entry) {
	    case BORDER_GADGET_NAME :
	       strcpy(&tp->tp_TemplateName[0], (BYTE *)value);
	       tp->tp_Flags &= ~TEMPLATE_FLAG_DEFAULT_NAME;
	       break;
	    case BORDER_GADGET_TYPE :
	       bd->bd_Type = value + 1;
	       break;
	 }
	 break;
      case TEMPLATE_GROUP_TEXT :
	 gd = &text_gadget_data[TEXT_GADGET_TEXT];
	 td = &tp->tp_Data.tp_TextData;
	 switch (entry) {
	    case TEXT_GADGET_NAME :
	       strcpy(&tp->tp_TemplateName[0], (BYTE *)value);
	       tp->tp_Flags &= ~TEMPLATE_FLAG_DEFAULT_NAME;
	       break;
	    case TEXT_GADGET_TEXT :
	       if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
		  old_text = td->td_Text;
		  if ((status = duplicate_string(&td->td_Text, (BYTE *)
					  value)) != EDITOR_STATUS_NORMAL) {
		     td->td_Text = old_text;
		  } else {
		     DosFreeMem(old_text);
		  }
	       } else {
		  td->td_Text = (BYTE *)Atol((BYTE *)value);
	       }
	       ISetGadgetAttributes(gl, TEXT_GADGET_TEXT, 0L,
			 USE_CURRENT_VALUE, USE_CURRENT_VALUE, td->td_Text);
	       break;
	    case TEXT_GADGET_FONT :
	       old_text                = (BYTE *)tp->tp_TextAttr.ta_Name;
	       tp->tp_TextAttr.ta_Name = (STRPTR)value;
	       if (!(tf = open_font(&tp->tp_TextAttr))) {
		  DisplayBeep(NULL);
		  tp->tp_TextAttr.ta_Name = (STRPTR)old_text;
		  ISetGadgetAttributes(gl, TEXT_GADGET_FONT, 0L,
			    USE_CURRENT_VALUE, USE_CURRENT_VALUE, old_text);
	       } else {
		  if ((status = duplicate_string((BYTE **)
				&tp->tp_TextAttr.ta_Name, (BYTE *)value)) !=
						     EDITOR_STATUS_NORMAL) {
		     tp->tp_TextAttr.ta_Name = (STRPTR)old_text;
		  } else {
		     DosFreeMem(old_text);
		  }
		  if (tf->tf_YSize != tp->tp_TextAttr.ta_YSize) {
		     tp->tp_TextAttr.ta_YSize = tf->tf_YSize;
		     ISetGadgetAttributes(gl, TEXT_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
						      (VOID *)tf->tf_YSize);
		  }
		  close_font(tf);
	       }
	       break;
	    case TEXT_GADGET_SIZE :
	       old_size                 = tp->tp_TextAttr.ta_YSize;
	       tp->tp_TextAttr.ta_YSize = value;
	       if (!(tf = open_font(&tp->tp_TextAttr))) {
		  DisplayBeep(NULL);
		  tp->tp_TextAttr.ta_YSize = old_size;
		  ISetGadgetAttributes(gl, TEXT_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
							  (VOID *)old_size);
	       } else {
		  if (tf->tf_YSize != value) {
		     DisplayBeep(NULL);
		     tp->tp_TextAttr.ta_YSize = tf->tf_YSize;
		     ISetGadgetAttributes(gl, TEXT_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
						      (VOID *)tf->tf_YSize);
		  }
		  close_font(tf);
	       }
	       break;
	    case TEXT_GADGET_TYPE :
	       old_type      = td->td_Type;
	       old_text      = td->td_Text;
	       td->td_Type   = value + 1;
	       gd->gd_Flags &= ~(GADGET_DATA_FLAG_STRING_UNSIGNED_DEC |
					GADGET_DATA_FLAG_STRING_SIGNED_DEC |
					       GADGET_DATA_FLAG_STRING_HEX |
					       GADGET_DATA_FLAG_STRING_BIN);
	       if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
		  IConvertUnsignedDec((ULONG)old_text, &buffer[0]);
		  if ((status = duplicate_string(&td->td_Text, (BYTE *)
				     &buffer[0])) != EDITOR_STATUS_NORMAL) {
		     td->td_Type = old_type;
		     td->td_Text = old_text;
		  }
	       } else {
		  switch (td->td_Type) {
		     case TEXT_DATA_TYPE_NUM_UNSIGNED_DEC :
			gd->gd_Flags |= GADGET_DATA_FLAG_STRING_UNSIGNED_DEC;
			break;
		     case TEXT_DATA_TYPE_NUM_SIGNED_DEC :
			gd->gd_Flags |= GADGET_DATA_FLAG_STRING_SIGNED_DEC;
			break;
		     case TEXT_DATA_TYPE_NUM_HEX :
			gd->gd_Flags |= GADGET_DATA_FLAG_STRING_HEX;
			break;
		     case TEXT_DATA_TYPE_NUM_BIN :
			gd->gd_Flags |= GADGET_DATA_FLAG_STRING_BIN;
			break;
		  }
		  if (old_type == TEXT_DATA_TYPE_TEXT) {
		     td->td_Text = (BYTE *)Atol(old_text);
		     DosFreeMem(old_text);
		  }
	       }
	       ISetGadgetAttributes(gl, TEXT_GADGET_TEXT, 0L,
			 USE_CURRENT_VALUE, USE_CURRENT_VALUE, td->td_Text);
	       break;
	    case TEXT_GADGET_BOLD :
	       if (value) {
		  td->td_Flags |= TEXT_DATA_FLAG_BOLD;
	       } else {
		  td->td_Flags &= ~TEXT_DATA_FLAG_BOLD;
	       }
	       break;
	    case TEXT_GADGET_ITALIC :
	       if (value) {
		  td->td_Flags |= TEXT_DATA_FLAG_ITALIC;
	       } else {
		  td->td_Flags &= ~TEXT_DATA_FLAG_ITALIC;
	       }
	       break;
	    case TEXT_GADGET_UNDERLINED :
	       if (value) {
		  td->td_Flags |= TEXT_DATA_FLAG_UNDERLINED;
	       } else {
		  td->td_Flags &= ~TEXT_DATA_FLAG_UNDERLINED;
	       }
	       break;
	    case TEXT_GADGET_COLOR2 :
	       if (value) {
		  td->td_Flags |= TEXT_DATA_FLAG_COLOR2;
	       } else {
		  td->td_Flags &= ~TEXT_DATA_FLAG_COLOR2;
	       }
	       break;
	    case TEXT_GADGET_COMPLEMENT :
	       if (value) {
		  td->td_Flags |= TEXT_DATA_FLAG_COMPLEMENT;
	       } else {
		  td->td_Flags &= ~TEXT_DATA_FLAG_COMPLEMENT;
	       }
	       break;
	 }

	 /* Calc size of new text for template 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;
	 break;
      case TEMPLATE_GROUP_GADGET :
	 gd = &tp->tp_Data.tp_GadgetData;
	 switch (entry) {
	    case NORMAL_GADGET_NAME :
	       strcpy(&tp->tp_TemplateName[0], (BYTE *)value);
	       tp->tp_Flags &= ~TEMPLATE_FLAG_DEFAULT_NAME;
	       break;
	    case NORMAL_GADGET_TEXT :
	       old_text = gd->gd_Text;
	       if ((status = duplicate_string(&gd->gd_Text, (BYTE *)value))
						  != EDITOR_STATUS_NORMAL) {
		  DisplayBeep(NULL);
		  gd->gd_Text = old_text;
		  ISetGadgetAttributes(gl, NORMAL_GADGET_TEXT, 0L,
			    USE_CURRENT_VALUE, USE_CURRENT_VALUE, old_text);
	       } else {
		  DosFreeMem(old_text);
	       }
	       break;
	    case NORMAL_GADGET_FONT :
	       old_text                = (BYTE *)tp->tp_TextAttr.ta_Name;
	       tp->tp_TextAttr.ta_Name = (STRPTR)value;
	       if (!(tf = open_font(&tp->tp_TextAttr))) {
		  DisplayBeep(NULL);
		  tp->tp_TextAttr.ta_Name = (STRPTR)old_text;
		  ISetGadgetAttributes(gl, NORMAL_GADGET_FONT, 0L,
			    USE_CURRENT_VALUE, USE_CURRENT_VALUE, old_text);
	       } else {
		  if ((status = duplicate_string((BYTE **)
				&tp->tp_TextAttr.ta_Name, (BYTE *)value)) !=
						     EDITOR_STATUS_NORMAL) {
		     DisplayBeep(NULL);
		     tp->tp_TextAttr.ta_Name = (STRPTR)old_text;
		     ISetGadgetAttributes(gl, NORMAL_GADGET_FONT, 0L,
			    USE_CURRENT_VALUE, USE_CURRENT_VALUE, old_text);
		  } else {
		     DosFreeMem(old_text);
		  }
		  if (tf->tf_YSize != tp->tp_TextAttr.ta_YSize) {
		     tp->tp_TextAttr.ta_YSize = tf->tf_YSize;
		     ISetGadgetAttributes(gl, NORMAL_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
						      (VOID *)tf->tf_YSize);
		  }
		  close_font(tf);
	       }
	       break;
	    case NORMAL_GADGET_SIZE :
	       old_size                 = tp->tp_TextAttr.ta_YSize;
	       tp->tp_TextAttr.ta_YSize = value;
	       if (!(tf = open_font(&tp->tp_TextAttr))) {
		  DisplayBeep(NULL);
		  tp->tp_TextAttr.ta_YSize = old_size;
		  ISetGadgetAttributes(gl, NORMAL_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
							  (VOID *)old_size);
	       } else {
		  if (tf->tf_YSize != value) {
		     DisplayBeep(NULL);
		     tp->tp_TextAttr.ta_YSize = tf->tf_YSize;
		     ISetGadgetAttributes(gl, NORMAL_GADGET_SIZE, 0L,
				       USE_CURRENT_VALUE, USE_CURRENT_VALUE,
						      (VOID *)tf->tf_YSize);
		  }
		  close_font(tf);
	       }
	       break;
	    case NORMAL_GADGET_POS :
	       switch (GADGET_TEXT_POS_MASK(gd->gd_Flags)) {
		  case GADGET_DATA_FLAG_TEXT_LEFT :
		     old_pos = TEXT_POS_LEFT;
		     break;
		  case GADGET_DATA_FLAG_TEXT_RIGHT :
		     old_pos = TEXT_POS_RIGHT;
		     break;
		  case GADGET_DATA_FLAG_TEXT_ABOVE :
		     old_pos = TEXT_POS_ABOVE;
		     break;
		  case GADGET_DATA_FLAG_TEXT_BELOW :
		     old_pos = TEXT_POS_BELOW;
		     break;
		  default :
		     old_pos = TEXT_POS_INSIDE;
		     break;
	       }

	       /* Check if text position possible for selected gadget type */
	       switch (gd->gd_Type) {
		  case GADGET_DATA_TYPE_MX :
		     if (value != TEXT_POS_LEFT && value != TEXT_POS_RIGHT) {
			value = USE_CURRENT_VALUE;
		     }
		     break;
		  case GADGET_DATA_TYPE_LISTVIEW :
		  case GADGET_DATA_TYPE_PALETTE :
		     if (value != TEXT_POS_ABOVE) {
			value = USE_CURRENT_VALUE;
		     }
		     break;
		  default :
		     break;
	       }
	       if (value == USE_CURRENT_VALUE) {
		  DisplayBeep(NULL);
		  ISetGadgetAttributes(gl, NORMAL_GADGET_POS, 0L,
					  USE_CURRENT_VALUE, (ULONG)old_pos,
						 (VOID *)USE_CURRENT_VALUE);
	       } else {
		  gd->gd_Flags &= ~(GADGET_DATA_FLAG_TEXT_LEFT |
					       GADGET_DATA_FLAG_TEXT_RIGHT |
					       GADGET_DATA_FLAG_TEXT_ABOVE |
					       GADGET_DATA_FLAG_TEXT_BELOW);
		  switch (value) {
		     case TEXT_POS_LEFT :
			gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_LEFT;
			break;
		     case TEXT_POS_RIGHT :
			gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_RIGHT;
			break;
		     case TEXT_POS_ABOVE :
			gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_ABOVE;
			break;
		     case TEXT_POS_BELOW :
			gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_BELOW;
			break;
		     case TEXT_POS_INSIDE :
			break;
		  }
	       }
	       break;
	    case NORMAL_GADGET_DISABLED :
	       if (value) {
		  gd->gd_Flags |= GADGET_DATA_FLAG_DISABLED;
	       } else {
		  gd->gd_Flags &= ~GADGET_DATA_FLAG_DISABLED;
	       }
	       break;
	    case NORMAL_GADGET_NO_BORDER :
	       if (value) {
		  gd->gd_Flags |= GADGET_DATA_FLAG_NO_BORDER;
	       } else {
		  gd->gd_Flags &= ~GADGET_DATA_FLAG_NO_BORDER;
	       }
	       break;
	    case NORMAL_GADGET_HIGHCOMP :
	       if (value) {
		  gd->gd_Flags |= GADGET_DATA_FLAG_HIGH_COMP;
	       } else {
		  gd->gd_Flags &= ~GADGET_DATA_FLAG_HIGH_COMP;
	       }
	       break;
	    case NORMAL_GADGET_HOTKEY :
	       if (value) {
		  gd->gd_Flags |= GADGET_DATA_FLAG_HOT_KEY;
	       } else {
		  gd->gd_Flags &= ~GADGET_DATA_FLAG_HOT_KEY;
	       }
	       break;
	    case NORMAL_GADGET_COLOR2 :
	       if (value) {
		  gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_COLOR2;
	       } else {
		  gd->gd_Flags &= ~GADGET_DATA_FLAG_TEXT_COLOR2;
	       }
	       break;
	 }
	 break;
   }
   return(status);
}
	/* Change special template data */

   SHORT
change_special_template_data(APTR gl, struct Template  *tp, USHORT entry,
								ULONG value)
{
   SHORT status = EDITOR_STATUS_NORMAL;

   return(status);
}
