#include "jcabc2ps.h"
#include "text.h"
#include "misc.h"

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Return a printable char* string from a Text item.
*/
char* TextStr(
	Text* tp)
{
	if (tp == 0)    return "[nil]";
	if (tp->t == 0) return "[null]";
	if (tp->l == 0) return "";
	return tp->t;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Append a string to the value of a Text item.
*/
int TextAppend(
	Text* tp,	// Add to this text
	char* st)	// String to append
{	char* F="TextAppend";
	int   sl = strlen(st);
	int   tl = tp->l + sl;
	char* p;
	if (!tp) {
		V1 "%s: ### Called with tp NULL ###\n",F V;
		return 0;
	}
	if (!tp->t) {
		if (!TextInit(&tp,strlen(st)+1)) {
			return 0;
		}
	}
	if (tl >= tp->m) {
		if (!(p = (char*)Malloc(tl+1,"txt+txt"))) {
			V1 "%s: ### Can't enlarge text string from %d to %d bytes ###\n",F,tp->m,tl+1 V;
			return 0;
		}
		bcopy(tp->t,p,tp->l+1);	// Copy old initial value
		Free(tp->t,"txt+txt");	// Free old value
		tp->t = p;				// Plug in new value
		V3 "%s: --- Realloc Text string from %d to %d bytes\n",F,tp->m,tl+1 V;
		tp->m = tl+1;			// Note new allocated size
	}
	V6 "%s:  Text changed from \"%s\"",F,tp->t V;
	strcpy(tp->t + tp->l, st);	// Append new string.
	V6 "%s: to \"%s\" (%d bytes)\n",F,tp->t,tl V;
	tp->l = tl;					// Note new length.
	return tl;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Initialize a Text pointer.  We get a pointer to the pointer.  Our job is  to *
* put  it  into  a  known  initial  state.   This  entails  mallocing space if *
* necessary, and zeroing things out. The return value is 1 if we succeed and 0 *
* if we can't get space.                                                       *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int TextInit(
	Text** tpp,	// Where to create Text object
	int    len)	// Min length of text string
{	char*  F = "TextInit";
	Text*  tp = *tpp;	/* Local copy of pointer */
	if (!tp) {			/* Does the Text struct exist yet? */
		if (!(tp = (Text*)Malloc(sizeof(Text),"Text"))) {
			V1 "### Can't get %lu bytes for Text struct ###\n",sizeof(Text) V;
			return 0;
		}
		V5 "%s: Malloc %lu bytes at %lX for Text struct.\n",F,sizeof(Text),(ulong)tp V;
		bzero(tp,sizeof(Text));
		*tpp = tp;		/* Save the struct's address in the pointer */
	}
	if (!(tp->t)) {		/* Does it have a text string? */
		if (!(tp->t = (char*)Malloc(len,"text"))) {
			V1 "### Can't get %d bytes for initial Text string ###\n",32 V;
			return 0;
		}
		V5 "%s: Malloc %d bytes at %lX for initial Text string.\n",F,len,(ulong)tp->t V;
		bzero(tp->t,len);
		tp->m = len;	/* Initial size */
	}
	tp->t[0] = 0;	/* Make sure that the string is null */
	tp->l = 0;		/* Its length must also be zero */
	return 1;		/* Success */
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Wipe out a Text struct.  We free its malloc'd space and zero out the struct.
*/
void  zapText(
	Text*tp,
	char*dsc)
{	char *F="zapText";
	if (!tp) {
		V1 "%s: ### Called with null Text pointer ###\n",F V;
		return;
	}
	if (tp->t) {
		Free(tp->t,dsc);
		V6 "Forget tp->t=%08X",(uint)tp->t V;
		tp->t = 0;
	}
	bzero(tp,sizeof(Text));
}
