/* $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,
						 0L, USE_CURRENT_VALUE, (VOID *) USE_CURRENT_VALUE);
	/* Select new mode gadget */
	ISetGadgetAttributes(gl, LIST_GADGET_EDIT + mode, 0L, 0L,
						 1L, USE_CURRENT_VALUE, (VOID *) USE_CURRENT_VALUE);
	list_mode = mode;

	/* Reset string gadget and some variables */
	ISetGadgetAttributes(gl, LIST_GADGET_STRING, 0L, 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, 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, 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, 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 = (BYTE *)malloc((LONG) (strlen((BYTE *) value) +
											1))))
				{
					status = EDITOR_ERROR_OUT_OF_MEM;
				}
				else
				{
					free(last_node->ln_Name);
					last_node->ln_Name = text;
					strcpy(text, (BYTE *) value);
					ISetGadgetAttributes(gl, LIST_GADGET_LISTVIEW, 0L, 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, 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
			{
				free(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
			{
				free(text_array);
			}
			break;
		case GADGET_DATA_TYPE_LISTVIEW:
			gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
			break;
		}
	}
	return (status);
}
