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

 /* Includes */

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

 /* Draw box in given window */

VOID
draw_box(struct Window * win, struct Box * box)
{
	struct RastPort *rp = win->RPort;

	SetDrMd(rp, (LONG) COMPLEMENT);
	Move(rp, (LONG) box->bo_X1, (LONG) box->bo_Y1);
	Draw(rp, (LONG) box->bo_X2, (LONG) box->bo_Y1);
	Draw(rp, (LONG) box->bo_X2, (LONG) box->bo_Y2);
	Draw(rp, (LONG) box->bo_X1, (LONG) box->bo_Y2);
	Draw(rp, (LONG) box->bo_X1, (LONG) box->bo_Y1);
}

 /* Draw box in given window with border of 1 pixel */

VOID
draw_box_with_border(struct Window *win, struct Box *box)
{
	struct RastPort *rp = win->RPort;

	SetDrMd(rp, (LONG) COMPLEMENT);
	Move(rp, (LONG) (box->bo_X1 - 1), (LONG) (box->bo_Y1 - 1));
	Draw(rp, (LONG) (box->bo_X2 + 1), (LONG) (box->bo_Y1 - 1));
	Draw(rp, (LONG) (box->bo_X2 + 1), (LONG) (box->bo_Y2 + 1));
	Draw(rp, (LONG) (box->bo_X1 - 1), (LONG) (box->bo_Y2 + 1));
	Draw(rp, (LONG) (box->bo_X1 - 1), (LONG) (box->bo_Y1 - 1));
}

 /* Draw box in given window with offset */

VOID
draw_box_with_offset(struct Window *win, struct Box *box, SHORT xoffset,
					 SHORT yoffset)
{
	struct RastPort *rp = win->RPort;

	SetDrMd(rp, (LONG) COMPLEMENT);
	Move(rp, (LONG) (box->bo_X1 + xoffset), (LONG) (box->bo_Y1 + yoffset));
	Draw(rp, (LONG) (box->bo_X2 + xoffset), (LONG) (box->bo_Y1 + yoffset));
	Draw(rp, (LONG) (box->bo_X2 + xoffset), (LONG) (box->bo_Y2 + yoffset));
	Draw(rp, (LONG) (box->bo_X1 + xoffset), (LONG) (box->bo_Y2 + yoffset));
	Draw(rp, (LONG) (box->bo_X1 + xoffset), (LONG) (box->bo_Y1 + yoffset));
}

 /* Get head of EXEC list */

VOID *
get_head(struct List *list)
{
	struct Node *node = list->lh_Head;

	/* Check for empty list ? */
	if (!node->ln_Succ)
	{
		node = NULL;
	}
	return ((VOID *) node);
}

 /* Get tail of EXEC list */

VOID *
get_tail(struct List * list)
{
	struct Node *node = list->lh_TailPred;

	/* Check for empty list ? */
	if (!node->ln_Pred)
	{
		node = NULL;
	}
	return ((VOID *) node);
}

 /* Get next node of EXEC list entry */

VOID *
get_succ(struct Node * node)
{
	/* Check for end of list ? */
	node = node->ln_Succ;
	if (!node->ln_Succ)
	{
		node = NULL;
	}
	return ((VOID *) node);
}

 /* Get previous node of EXEC list entry */

VOID *
get_pred(struct Node * node)
{
	/* Check for start of list ? */
	node = node->ln_Pred;
	if (!node->ln_Pred)
	{
		node = NULL;
	}
	return ((VOID *) node);
}

 /* Get node from list by given number */

VOID *
get_node(struct List * list, USHORT num)
{
	struct Node *node;

	if (node = get_head(list))
	{
		while (num-- && (node = get_succ(node)));
	}
	return ((VOID *) node);
}

 /* Duplicate text string */

SHORT
duplicate_string(BYTE * text, BYTE ** ptr)
{
	LONG len;
	SHORT status = EDITOR_STATUS_NORMAL;

	if (!text || (len = strlen(text) + 1) == 1)
	{
		*ptr = NULL;
	}
	else
	{
		if (!(*ptr = (BYTE *)malloc(len)))
		{
			status = EDITOR_ERROR_OUT_OF_MEM;
		}
		else
		{
			CopyMem(text, *ptr, len);
		}
	}
	return (status);
}

 /* Convert string to lower case */

VOID
lower_string(BYTE * text, BYTE * ptr)
{
	if (ptr && text)
	{
		BYTE c;

		while ((c = *text++) != '\0')
		{
			*ptr++ = tolower(c);
		}
		*ptr = '\0';
	}
}

 /* Convert string to upper case */

VOID
upper_string(BYTE * text, BYTE * ptr)
{
	if (ptr && text)
	{
		BYTE c;

		while ((c = *text++) != '\0')
		{
			*ptr++ = toupper(c);
		}
		*ptr = '\0';
	}
}

 /* Duplicate text list */

SHORT
duplicate_text_list(struct Template *old_tp, struct Template *new_tp)
{
	struct Node *node;
	SHORT status = EDITOR_STATUS_NORMAL;

	NewList(&new_tp->tp_TextList);
	for (node = get_head(&old_tp->tp_TextList); node &&
		 status == EDITOR_STATUS_NORMAL; node = get_succ(node))
	{
		status = add_template_text_list_entry(new_tp, node->ln_Name);
	}
	return (status);
}

 /* Build template text list from given text array */

SHORT
build_template_text_list(struct Template * tp, BYTE ** text_array)
{
	BYTE *text;
	SHORT status = EDITOR_STATUS_NORMAL;

	NewList(&tp->tp_TextList);
	for (text = *text_array; text && status == EDITOR_STATUS_NORMAL;
		 text = *++text_array)
	{
		status = add_template_text_list_entry(tp, text);
	}
	if (status != EDITOR_STATUS_NORMAL)
	{
		free_template_text_list(tp);
	}
	return (status);
}

 /* Build text list entry */

struct Node *
build_text_list_entry(BYTE * text)
{
	struct Node *node;

	if (node = AllocMem((LONG) sizeof(struct Node), (LONG) MEMF_PUBLIC |
						MEMF_CLEAR))
	{
		if (!(node->ln_Name = (BYTE *)malloc((LONG) (strlen(text) + 1))))
		{
			FreeMem(node, (LONG) sizeof(struct Node));
			node = NULL;
		}
		else
		{
			strcpy(node->ln_Name, text);
		}
	}
	return (node);
}

 /* Add text entry to template text list */

SHORT
add_template_text_list_entry(struct Template * tp, BYTE * text)
{
	struct Node *node;
	SHORT status = EDITOR_STATUS_NORMAL;

	if (!(node = build_text_list_entry(text)))
	{
		status = EDITOR_ERROR_OUT_OF_MEM;
	}
	else
	{
		AddTail(&tp->tp_TextList, node);
	}
	return (status);
}

 /* Free template text list */

VOID
free_template_text_list(struct Template * tp)
{
	struct List *list = &tp->tp_TextList;
	struct Node *node;

	while (node = RemHead(list))
	{
		free_text_list_entry(node);
	}
}

 /* Free text list entry */

VOID
free_text_list_entry(struct Node *node)
{
	free(node->ln_Name);
	FreeMem(node, (LONG) sizeof(struct Node));
}

 /* Build template text array from template text list */

SHORT
build_template_text_array(struct Template *tp)
{
	struct List *list = &tp->tp_TextList;
	struct Node *node;
	BYTE **text_array;
	USHORT count = 0;
	SHORT status = EDITOR_STATUS_NORMAL;

	/* Count entries in text list */
	for (node = get_head(list); node; node = get_succ(node))
	{
		count++;
	}
	if (!(text_array = (BYTE **)malloc((LONG) (count + 1) * sizeof(BYTE *))))
	{
		status = EDITOR_ERROR_OUT_OF_MEM;
	}
	else
	{
		struct GadgetData *gd = &tp->tp_Data.tp_GadgetData;

		switch (tp->tp_Type)
		{
		case TEMPLATE_TYPE_MX:
			gd->gd_SpecialData.gd_MXData.gd_MXTextArray = text_array;
			break;
		case TEMPLATE_TYPE_CYCLE:
			gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = text_array;
			break;
		}

		/* Fill text array with pointers to text list entries */
		for (node = get_head(list); node && status == EDITOR_STATUS_NORMAL;
			 node = get_succ(node))
		{
			*text_array++ = node->ln_Name;
		}
		*text_array = NULL;		/* mark end of text array */
	}
	return (status);
}

 /* Free template text array */

VOID
free_template_text_array(struct Template * tp)
{
	struct GadgetData *gd = &tp->tp_Data.tp_GadgetData;
	BYTE **text_array;

	switch (tp->tp_Type)
	{
	case TEMPLATE_TYPE_MX:
		text_array = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
		gd->gd_SpecialData.gd_MXData.gd_MXTextArray = NULL;
		break;
	case TEMPLATE_TYPE_CYCLE:
		text_array = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
		gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = NULL;
		break;
	default:
		text_array = NULL;
		break;
	}
	free(text_array);
}
