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

	/* Includes */

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

	/* Defines for text list editor gadgets */

#define LIST_GADGET_LISTVIEW		0
#define LIST_GADGET_STRING		1
#define LIST_GADGET_EDIT		2
#define LIST_GADGET_ADD			3
#define LIST_GADGET_INSERT		4
#define LIST_GADGET_DELETE		5

#define LIST_GADGET1_TYPE		GADGET_DATA_TYPE_LISTVIEW
#define LIST_GADGET1_FLAGS		GADGET_DATA_FLAG_HOTKEY
#define LIST_GADGET1_TEXT		"Text _list"
#define LIST_GADGET1_LEFT_EDGE		10
#define LIST_GADGET1_TOP_EDGE		28
#define LIST_GADGET1_WIDTH		196
#define LIST_GADGET1_HEIGHT		31
#define LIST_GADGET1_TEXT_ATTR		&topaz80_attr
#define LIST_GADGET1_SPACING		1
#define LIST_GADGET1_TOP		0
#define LIST_GADGET1_LIST		NULL

#define LIST_GADGET2_TYPE		GADGET_DATA_TYPE_STRING
#define LIST_GADGET2_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_TEXT_RIGHT)
#define LIST_GADGET2_LEFT_EDGE		LIST_GADGET1_LEFT_EDGE
#define LIST_GADGET2_TOP_EDGE		(LIST_GADGET1_TOP_EDGE + LIST_GADGET1_HEIGHT + 1)
#define LIST_GADGET2_WIDTH		(LIST_GADGET1_WIDTH - (4 + 1) * 8)
#define LIST_GADGET2_HEIGHT		12
#define LIST_GADGET2_TEXT		"_Text"
#define LIST_GADGET2_TEXT_ATTR		&topaz80_attr
#define LIST_GADGET2_INPUT_LEN		80
#define LIST_GADGET2_INPUT_NEXT		0
#define LIST_GADGET2_INPUT_DEFAULT	NULL

#define LIST_GADGET3_TYPE		GADGET_DATA_TYPE_BUTTON
#define LIST_GADGET3_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_BUTTON_TOGGLE)
#define LIST_GADGET3_LEFT_EDGE		LIST_GADGET1_LEFT_EDGE
#define LIST_GADGET3_TOP_EDGE		(LIST_GADGET2_TOP_EDGE + LIST_GADGET2_HEIGHT + 3)
#define LIST_GADGET3_WIDTH		((LIST_GADGET1_WIDTH - 3 * 4) / 4)
#define LIST_GADGET3_HEIGHT		13
#define LIST_GADGET3_TEXT		"_Edit"
#define LIST_GADGET3_TEXT_ATTR		&topaz80_attr

#define LIST_GADGET4_TYPE		GADGET_DATA_TYPE_BUTTON
#define LIST_GADGET4_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_BUTTON_TOGGLE)
#define LIST_GADGET4_LEFT_EDGE		(LIST_GADGET3_LEFT_EDGE + LIST_GADGET3_WIDTH + 4)
#define LIST_GADGET4_TOP_EDGE		LIST_GADGET3_TOP_EDGE
#define LIST_GADGET4_WIDTH		LIST_GADGET3_WIDTH
#define LIST_GADGET4_HEIGHT		LIST_GADGET3_HEIGHT
#define LIST_GADGET4_TEXT		"_Add"
#define LIST_GADGET4_TEXT_ATTR		&topaz80_attr

#define LIST_GADGET5_TYPE		GADGET_DATA_TYPE_BUTTON
#define LIST_GADGET5_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_BUTTON_TOGGLE)
#define LIST_GADGET5_LEFT_EDGE		(LIST_GADGET4_LEFT_EDGE + LIST_GADGET4_WIDTH + 4)
#define LIST_GADGET5_TOP_EDGE		LIST_GADGET4_TOP_EDGE
#define LIST_GADGET5_WIDTH		LIST_GADGET4_WIDTH
#define LIST_GADGET5_HEIGHT		LIST_GADGET4_HEIGHT
#define LIST_GADGET5_TEXT		"_Ins"
#define LIST_GADGET5_TEXT_ATTR		&topaz80_attr

#define LIST_GADGET6_TYPE		GADGET_DATA_TYPE_BUTTON
#define LIST_GADGET6_FLAGS		(GADGET_DATA_FLAG_HOTKEY | GADGET_DATA_FLAG_BUTTON_TOGGLE)
#define LIST_GADGET6_LEFT_EDGE		(LIST_GADGET5_LEFT_EDGE + LIST_GADGET5_WIDTH + 4)
#define LIST_GADGET6_TOP_EDGE		LIST_GADGET5_TOP_EDGE
#define LIST_GADGET6_WIDTH		LIST_GADGET5_WIDTH
#define LIST_GADGET6_HEIGHT		LIST_GADGET5_HEIGHT
#define LIST_GADGET6_TEXT		"_Del"
#define LIST_GADGET6_TEXT_ATTR		&topaz80_attr

	/* Statics for text list editor gadgets */

struct GadgetData  list_gadget_data[] = {
   {
	LIST_GADGET1_TYPE,		/* gd_Type */
	LIST_GADGET1_FLAGS,		/* gd_Flags */
	LIST_GADGET1_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET1_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET1_WIDTH,		/* gd_Width */
	LIST_GADGET1_HEIGHT,		/* gd_Height */
	LIST_GADGET1_TEXT,		/* *gd_Text */
	LIST_GADGET1_TEXT_ATTR,		/* *gd_TextAttr */
	{
	LIST_GADGET1_SPACING,		/* gd_ListViewSpacing */
	LIST_GADGET1_TOP,		/* gd_ListViewTop */
	LIST_GADGET1_LIST		/* gd_ListViewList */
	}
   }, {
	LIST_GADGET2_TYPE,		/* gd_Type */
	LIST_GADGET2_FLAGS,		/* gd_Flags */
	LIST_GADGET2_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET2_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET2_WIDTH,		/* gd_Width */
	LIST_GADGET2_HEIGHT,		/* gd_Height */
	LIST_GADGET2_TEXT,		/* *gd_Text */
	LIST_GADGET2_TEXT_ATTR,		/* *gd_TextAttr */
	{
	LIST_GADGET2_INPUT_LEN,		/* gd_InputLen */
	LIST_GADGET2_INPUT_NEXT,	/* gd_InputActivateNext/Prev */
	LIST_GADGET2_INPUT_DEFAULT	/* gd_InputDefault */
	}
   }, {
	LIST_GADGET3_TYPE,		/* gd_Type */
	LIST_GADGET3_FLAGS,		/* gd_Flags */
	LIST_GADGET3_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET3_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET3_WIDTH,		/* gd_Width */
	LIST_GADGET3_HEIGHT,		/* gd_Height */
	LIST_GADGET3_TEXT,		/* *gd_Text */
	LIST_GADGET3_TEXT_ATTR,		/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	LIST_GADGET4_TYPE,		/* gd_Type */
	LIST_GADGET4_FLAGS,		/* gd_Flags */
	LIST_GADGET4_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET4_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET4_WIDTH,		/* gd_Width */
	LIST_GADGET4_HEIGHT,		/* gd_Height */
	LIST_GADGET4_TEXT,		/* *gd_Text */
	LIST_GADGET4_TEXT_ATTR,		/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	LIST_GADGET5_TYPE,		/* gd_Type */
	LIST_GADGET5_FLAGS,		/* gd_Flags */
	LIST_GADGET5_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET5_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET5_WIDTH,		/* gd_Width */
	LIST_GADGET5_HEIGHT,		/* gd_Height */
	LIST_GADGET5_TEXT,		/* *gd_Text */
	LIST_GADGET5_TEXT_ATTR,	/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	LIST_GADGET6_TYPE,		/* gd_Type */
	LIST_GADGET6_FLAGS,		/* gd_Flags */
	LIST_GADGET6_LEFT_EDGE,		/* gd_LeftEdge */
	LIST_GADGET6_TOP_EDGE,		/* gd_TopEdge */
	LIST_GADGET6_WIDTH,		/* gd_Width */
	LIST_GADGET6_HEIGHT,		/* gd_Height */
	LIST_GADGET6_TEXT,		/* *gd_Text */
	LIST_GADGET6_TEXT_ATTR,		/* *gd_TextAttr */
	{ 0, 0, 0 }
   }, {
	INTUISUP_DATA_END		/* mark end of gadget data array */
   }
};
STATIC struct Node  *last_node;		/* last selected text list entry */
STATIC BYTE   *last_text;		/* last text defined by string gadget */
STATIC USHORT list_mode;

	/* Change mode of text list editor mode */

   VOID
change_text_list_editor_mode(APTR gl, USHORT mode)
{
   /* Unselect old mode gadget */
   ISetGadgetAttributes(gl, LIST_GADGET_EDIT + list_mode, 0L, 0L,
			      USE_CURRENT_VALUE, (VOID *)USE_CURRENT_VALUE);
   /* Select new mode gadget */
   ISetGadgetAttributes(gl, LIST_GADGET_EDIT + mode, 0L, 1L,
			      USE_CURRENT_VALUE, (VOID *)USE_CURRENT_VALUE);
   list_mode = mode;

   /* Reset string gadget and some variables */
   ISetGadgetAttributes(gl, LIST_GADGET_STRING, 0L, USE_CURRENT_VALUE,
						   USE_CURRENT_VALUE, NULL);
   last_node = NULL;
   last_text = NULL;
}
	/* Perform gadget action text list editor */

   SHORT
perform_text_list_editor_action(APTR gl, struct Template  *tp, USHORT entry,
								ULONG value)
{
   struct List  *list = &tp->tp_TextList;
   struct Node  *node;
   SHORT status = EDITOR_STATUS_NORMAL;

   switch (entry) {
      case LIST_GADGET_LISTVIEW :
	 node = last_node = get_node(list, (USHORT)value);
	 switch (list_mode) {
	    case LIST_MODE_EDIT :
	    case LIST_MODE_ADD :

	       /* Copy selected text to string gadget */
	       ISetGadgetAttributes(gl, LIST_GADGET_STRING, 0L,
		       USE_CURRENT_VALUE, USE_CURRENT_VALUE, node->ln_Name);
	       break;

	    case LIST_MODE_INSERT :

	       /* Insert text from string gadget before selected entry */
	       if (last_text) {
		  struct Node  *list_node = get_pred(node);

		  if (!(node = build_text_list_entry(last_text))) {
		     status = EDITOR_ERROR_OUT_OF_MEM;
		  } else {
		     Insert(list, node, list_node);
		     ISetGadgetAttributes(gl, LIST_GADGET_LISTVIEW, 0L,
				USE_CURRENT_VALUE, USE_CURRENT_VALUE, list);
		  }
	       }
	       break;

	    case LIST_MODE_DELETE :

	       /* Delete selected entry */
	       Remove(node);
	       free_text_list_entry(node);
	       ISetGadgetAttributes(gl, LIST_GADGET_LISTVIEW, 0L,
				USE_CURRENT_VALUE, USE_CURRENT_VALUE, list);
	       break;
	 }
	 break;

      case LIST_GADGET_STRING :
	 last_text = (BYTE *)value;
	 switch (list_mode) {
	    case LIST_MODE_EDIT :

	       /* Replace text of last selected entry by this one */
	       if (last_node) {
		  BYTE *text;

		  if (!(text = DosAllocMem((LONG)(strlen((BYTE *)value) +
								     1)))) {
		     status = EDITOR_ERROR_OUT_OF_MEM;
		  } else {
		     DosFreeMem(last_node->ln_Name);
		     last_node->ln_Name = text;
		     strcpy(text, (BYTE *)value);
		     ISetGadgetAttributes(gl, LIST_GADGET_LISTVIEW, 0L,
				USE_CURRENT_VALUE, USE_CURRENT_VALUE, list);
		  }
	       }
	       break;

	    case LIST_MODE_ADD :

	       /* Add text to end of list */
	       if (!(node = build_text_list_entry((BYTE *)value))) {
		  status = EDITOR_ERROR_OUT_OF_MEM;
	       } else {
		  AddTail(list, node);
		  ISetGadgetAttributes(gl, LIST_GADGET_LISTVIEW, 0L,
				USE_CURRENT_VALUE, USE_CURRENT_VALUE, list);
	       }
	       break;
	 }
	 break;

      default :

	 /* Set new text list editor mode */
	 change_text_list_editor_mode(gl, entry - LIST_GADGET_EDIT);
	 break;
   }
   if (status == EDITOR_STATUS_NORMAL) {
      struct GadgetData  *gd = &tp->tp_Data.tp_GadgetData;
      BYTE **text_array;

      /* Change template data */
      switch (gd->gd_Type) {
	 case GADGET_DATA_TYPE_MX :
	    text_array = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
	    if ((status = build_template_text_array(tp)) !=
						     EDITOR_STATUS_NORMAL) {
	       gd->gd_SpecialData.gd_MXData.gd_MXTextArray = text_array;
	    } else {
	       DosFreeMem(text_array);
	    }
	    break;
	 case GADGET_DATA_TYPE_CYCLE :
	    text_array = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
	    if ((status = build_template_text_array(tp)) !=
						     EDITOR_STATUS_NORMAL) {
	       gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = text_array;
	    } else {
	       DosFreeMem(text_array);
	    }
	    break;
	 case GADGET_DATA_TYPE_LISTVIEW :
	    gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
	    break;
      }
   }
   return(status);
}
