/*
 * text-writer -- RTF-to-text translation writer code.
 *
 * Read RTF input, write text of document (text extraction).
 *
 * Wrapper must call WriterInit() once before processing any files,
 * then set up input and call BeginFile() for each input file.
 *
 * This installs callbacks for the text and control token classes.
 * The control class is necessary so that special characters such as
 * \par, \tab, \sect, etc.  can be converted.
 *
 * It's problematic what to do with text in headers and footers, and
 * what to do about tables.
 *
 * This really is quite a stupid program, for instance, it could keep
 * track of the current leader character and dump that out when a tab
 * is encountered.
 *
 * 04 Feb 91	Paul DuBois	dubois@primate.wisc.edu
 *
 * This software may be redistributed without restriction and used for
 * any purpose whatsoever.
 *
 * 04 Feb 91
 * -Created.
 * 27 Feb 91
 * - Updated for distribution 1.05.
 * 13 Jul 93
 * - Updated to compile under THINK C 6.0.
 * 31 Aug 93
 * - Added Mike Sendall's entries for Macintosh char map.
 * 07 Sep 93
 * - Uses charset map and output sequence map for character translation.
 * 11 Mar 94
 * - Updated for 1.10 distribution.
 */

#include <stdio.h>

#include "rtf.h"
#include "rtf2text.h"
#include "charlist.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

static void	TextClass ();
static void	ControlClass ();
static void	Destination ();
static void	SpecialChar ();
static void	PutStdChar ();
static void	PutLitChar ();
static void	PutLitStr ();

static char	*outMap[rtfSC_MaxChar];

static CHARLIST charlist = {0, NULL, NULL};

int RTFToBuffer(char* pBuffer, int nBufferSize);
int RTFToBuffer(char* pBuffer, int nBufferSize)
{

   /* check if the buffer is big enough to hold all characters  */
   /* we require one more for the '\0'                          */

   TRACE("\n");

   if(nBufferSize < charlist.nCount + 1) {
        return charlist.nCount + CHARLIST_CountChar(&charlist, '\n') + 1;
   }

   while(charlist.nCount)
   {
       *pBuffer = CHARLIST_Dequeue(&charlist);
       if(*pBuffer=='\n')
       {
         *pBuffer = '\r';
         pBuffer++;
         *pBuffer = '\n';
       }
       pBuffer++;
   }
   *pBuffer = '\0';

   return 0;
}


/*
 * Initialize the writer.
 */

void
WriterInit ()
{
	RTFReadOutputMap (outMap,1);
}


int
BeginFile ()
{
	/* install class callbacks */

	RTFSetClassCallback (rtfText, TextClass);
	RTFSetClassCallback (rtfControl, ControlClass);

	return (1);
}


/*
 * Write out a character.  rtfMajor contains the input character, rtfMinor
 * contains the corresponding standard character code.
 *
 * If the input character isn't in the charset map, try to print some
 * representation of it.
 */

static void
TextClass ()
{
char	buf[rtfBufSiz];

	TRACE("\n");

	if (rtfFormat == SF_TEXT)
	        PutLitChar (rtfMajor);
	else if (rtfMinor != rtfSC_nothing)
		PutStdChar (rtfMinor);
	else
	{
		if (rtfMajor < 128)	/* in ASCII range */
			sprintf (buf, "[[%c]]", rtfMajor);
		else
			sprintf (buf, "[[\\'%02x]]", rtfMajor);
		PutLitStr (buf);
	}
}


static void
ControlClass ()
{
	TRACE("\n");
	switch (rtfMajor)
	{
	case rtfDestination:
		Destination ();
		break;
	case rtfSpecialChar:
		SpecialChar ();
		break;
	}
}


/*
 * This function notices destinations that should be ignored
 * and skips to their ends.  This keeps, for instance, picture
 * data from being considered as plain text.
 */

static void
Destination ()
{

	TRACE("\n");

	switch (rtfMinor)
	{
	case rtfPict:
	case rtfFNContSep:
	case rtfFNContNotice:
	case rtfInfo:
	case rtfIndexRange:
	case rtfITitle:
	case rtfISubject:
	case rtfIAuthor:
	case rtfIOperator:
	case rtfIKeywords:
	case rtfIComment:
	case rtfIVersion:
	case rtfIDoccomm:
		RTFSkipGroup ();
		break;
	}
}


/*
 * The reason these use the rtfSC_xxx thingies instead of just writing
 * out ' ', '-', '"', etc., is so that the mapping for these characters
 * can be controlled by the text-map file.
 */

void SpecialChar ()
{

	TRACE("\n");

	switch (rtfMinor)
	{
	case rtfPage:
	case rtfSect:
	case rtfRow:
	case rtfLine:
	case rtfPar:
		PutLitChar ('\n');
		break;
	case rtfCell:
		PutStdChar (rtfSC_space);	/* make sure cells are separated */
		break;
	case rtfNoBrkSpace:
		PutStdChar (rtfSC_nobrkspace);
		break;
	case rtfTab:
		PutLitChar ('\t');
		break;
	case rtfNoBrkHyphen:
		PutStdChar (rtfSC_nobrkhyphen);
		break;
	case rtfBullet:
		PutStdChar (rtfSC_bullet);
		break;
	case rtfEmDash:
		PutStdChar (rtfSC_emdash);
		break;
	case rtfEnDash:
		PutStdChar (rtfSC_endash);
		break;
	case rtfLQuote:
		PutStdChar (rtfSC_quoteleft);
		break;
	case rtfRQuote:
		PutStdChar (rtfSC_quoteright);
		break;
	case rtfLDblQuote:
		PutStdChar (rtfSC_quotedblleft);
		break;
	case rtfRDblQuote:
		PutStdChar (rtfSC_quotedblright);
		break;
	}
}


/*
 * Eventually this should keep track of the destination of the
 * current state and only write text when in the initial state.
 *
 * If the output sequence is unspecified in the output map, write
 * the character's standard name instead.  This makes map deficiencies
 * obvious and provides incentive to fix it. :-)
 */

void PutStdChar (int stdCode)
{

  char	*oStr = (char *) NULL;
  char	buf[rtfBufSiz];

/*	if (stdCode == rtfSC_nothing)
		RTFPanic ("Unknown character code, logic error\n");
*/
	TRACE("\n");

	oStr = outMap[stdCode];
	if (oStr == (char *) NULL)	/* no output sequence in map */
	{
		sprintf (buf, "[[%s]]", RTFStdCharName (stdCode));
		oStr = buf;
	}
	PutLitStr (oStr);
}


void PutLitChar (int c)
{
	CHARLIST_Enqueue(&charlist, (char) c);
        /* fputc (c, ostream); */
}


static void PutLitStr (char	*s)
{
	for(;*s;s++)
	{
	  CHARLIST_Enqueue(&charlist, *s);
	}
	/* fputs (s, ostream); */
}
