/*
 * propmod.c
 * Copyright (C) 2001 A.J. van Os; Released under GPL
 *
 * Description:
 * Build, read and destroy a list (array) of Word property modifiers
 */

#include <stdio.h>
#include <string.h>
#include "antiword.h"

#if defined(DEBUG)
#define ELEMENTS_TO_ADD	 3
#else
#define ELEMENTS_TO_ADD	30
#endif /* DEBUG */

/* Variables needed to write the property modifier list */
static unsigned char	**ppAnchor = NULL;
static int		iNextFree = 0;
static int		iMaxElements = 0;


/*
 * vDestroyPropModList - destroy the property modifier list
 */
void
vDestroyPropModList(void)
{
	int	iIndex;

	DBG_MSG("vDestroyPropModList");

	/* Free all the elements of the list */
	for (iIndex = 0; iIndex < iNextFree; iIndex++) {
		ppAnchor[iIndex] = xfree(ppAnchor[iIndex]);
	}
	/* Free the list itself */
	ppAnchor = xfree(ppAnchor);
	/* Reset all control variables */
	iNextFree = 0;
	iMaxElements = 0;
} /* end of vDestroyPropModList */

/*
 * vAdd2PropModList - add an element to the property modifier list
 */
void
vAdd2PropModList(const unsigned char *pucPropMod)
{
	size_t	tSize, tLen;

	fail(pucPropMod == NULL);

	DBG_MSG("vAdd2PropModList");

	if (iNextFree >= iMaxElements) {
		iMaxElements += ELEMENTS_TO_ADD;
		tSize = iMaxElements * sizeof(unsigned char **);
		ppAnchor = xrealloc(ppAnchor, tSize);
	}
	DBG_DEC(iNextFree);

	tLen = 2 + (size_t)usGetWord(0, pucPropMod);
	DBG_HEX(tLen);
	DBG_PRINT_BLOCK(pucPropMod, tLen);
	ppAnchor[iNextFree] = xmalloc(tLen);
	memcpy(ppAnchor[iNextFree], pucPropMod, tLen);
	iNextFree++;
} /* end of vAdd2PropModList */

/*
 * pucGetPropModListItem - get an item of the property modifier list
 */
const unsigned char *
pucReadPropModListItem(unsigned short usPropMod)
{
	int	iIndex;
	static unsigned char	aucBuffer[4];

	if (usPropMod == IGNORE_PROPMOD) {
		/* This Properties Modifier must be ignored */
		return NULL;
	}

	if (!odd(usPropMod)) {
		/* Variant 1: The information is in the input ifself */
		aucBuffer[0] = 2;
		aucBuffer[1] = 0;
		aucBuffer[2] = (unsigned char)((usPropMod & 0x00fe) >> 1);
		aucBuffer[3] = (unsigned char)((usPropMod & 0xff00) >> 8);
		return aucBuffer;
	}

	if (ppAnchor == NULL) {
		/* No information available */
		return NULL;
	}

	/* Variant 2: The input contains an index */
	iIndex = (int)(usPropMod >> 1);
	if (iIndex < 0 || iIndex >= iNextFree) {
		DBG_HEX(usPropMod);
		DBG_DEC(iIndex);
		DBG_DEC(iNextFree);
		return NULL;
	}
	return ppAnchor[iIndex];
} /* end of pucGetPropModListItem */
