/***********************************************************************\
rtf token class for Convert RTF which converts between Mac and NeXT rtf formats.
Copyright (C) 1993 David John Burrowes

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

The author, David John Burrowes, can be reached at:
	davidjohn@kira.net.netcom.com
	David John Burrowes
	1926 Ivy #10
	San Mateo, CA 94403-1367
\***********************************************************************/

#import "rtfToken.h"
#import <math.h>
#import <string.h>
#import	<stdio.h>
#import <stdlib.h>

@implementation rtfToken


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		init
//	Parameters:	none
//	Returns:		self
//	Stores:		none
//	Description:
//		Just a simple wrapper call to initTokenOftype.
//	Bugs:
//	history
//		93.01.02	djb	Created
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- init
{
	return [self   initTokenOfType: tokenWord];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		initTokenOfType
//	Parameters:	the type of token to create.
//	Returns:		self
//	Stores:		none
//	Description:
//		Initializes a new RTF token. by setting up it's instance variables.  Two things
//		are worth noting.  (1) name always points to a legal string, even if it is just a null
//		length CString.  (2) There is no way to change the type of a token after it is created.
//		This was deliberate.
//		Given the token in an rtf file:  \margin23  the type is a tokenControlWord, the
//		token's name would be `margin', it has a parameter, and the parameter is 23.
//	Bugs:
//	history
//		93.01.02	djb	Commended and added [super init] (oops)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- initTokenOfType: (TokenType) theType
{
	[super init];
	
	type = theType;
	name = NewCString(0);
	hasParameter = NO;
	parameter = 0;
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		free
//	Parameters:	none
//	Returns:		self
//	Stores:		none
//	Description:
//		Imagine my horror when I realized my rtf controller was, naturally,
//		allocating and destroying many a token, and happily calling free, but that there
//		was no specialized free method here to free the name of the token!!!!!  YI!!!
//		So, this does that.  Now we get to see if this makes the thing any less sluggish.
//		I may even be currently crashing due to excessive stuff (mallocdebug reports
//		alomst 6K nodes on a simple file conversion. may of which this will remove).
//	Bugs:
//	history
//		92.12.25	djb	Created
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- free
{
	FreeCString(name);
	return [super free];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		SetTokenName
//	Parameters:	A Cstring to be stored as the token's name. 
//	Returns:		self
//	Stores:		none
//	Description:
//		Simply store a copy of the specified string as the name of the token.
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- SetTokenName: (CString) theName
{
	FreeCString(name);
	name = NewCString(strlen(theName));
	strcpy(name, theName);
	return self;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		SetTokenValue
//	Parameters:	An integral value to be stored as the token's value 
//	Returns:		self
//	Stores:		none
//	Description:
//		Simply store the specified value in the token.
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- SetTokenValue: (Integer) theValue
{
	hasParameter = YES;
	parameter = theValue;
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetType
//	Parameters:	none 
//	Returns:		the type of this token.
//	Stores:		none
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (TokenType)  GetType
{
	return type;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetName
//	Parameters:	none 
//	Returns:		A copy of the name of the token
//	Stores:		none
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (CString)  GetName
{
	CString	temp = NewCString(strlen(name));
	strcpy(temp, name);
	return temp;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		HasValue
//	Parameters:	none 
//	Returns:		YES if this token has a value, no if not.
//	Stores:		none
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Boolean) HasValue;
{
	return hasParameter;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetValue
//	Parameters:	none 
//	Returns:		The integral parameter of the token.
//	Stores:		none
//	Bugs:
//	history
//		93.01.02	djb	Commented
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer)  GetValue
{
	return parameter;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetLength
//	Parameters:	none
//	Returns:		the length of the token as if it were printed out in ascii
//	Stores:		none
//	Description:
//		This returns the length of this token as if it were represented as an ascii
//		string.  Note that this does not include the escape character or any trailing
//		delimiter.  Thus, in "\fonttbl\f23 \froman" the length of the second token
//		would be 3 (f23.  not the \ or the space).  The length of the first would be 7.
//		Note that the log10 computation below figures out how many digits make up
//		the theoretical string without actually sprinf()-ing the integer into a string.
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (PositiveInteger)  GetLength
{
	PositiveInteger	thelength	= strlen(name);
	//
	//	If the token was \', then it gets it's own special length, otherwise it was
	//	a control symbol with a parameter (always a number) so get it's length.
	//
	if  (hasParameter == YES)
	{
		if ( (type  == tokenControlSymbol) && (strcmp(name, "\'") == 0) )
			thelength += 2;
		else
		{
			if (parameter == 0)
				thelength += 1;
			else
			{
				if (parameter < 0)
					thelength += (2+ floor(log10(parameter*-1))); 
				else
					thelength += (1+ floor(log10(parameter)));
			}
		}
	}

	return thelength;
}



@end
