/*
	Copyright (C) 1994 Sean Luke

	COWSStringNode.m
	Version 1.4
	Sean Luke
	
*/




#import "COWSStringNode.h"
#import "COWSInterpreter.h"
#import <string.h>
#import <stdlib.h>


@implementation COWSStringNode

- init
	{
	id returnval=[super init];
	string=	string=newstr("");
	error=NO;
	value_state=COWSSTRINGNODE_STATE_STRING;
	return returnval;
	}
	
- (const char*) string
	{
	switch(value_state)
		{
		case COWSSTRINGNODE_STATE_STRING: 
			return (const char*) string; 
			break;
		case COWSSTRINGNODE_STATE_FLOAT:
			sprintf(transfer_string,"%f",double_value);
			return (const char*) transfer_string;
			break;
		case COWSSTRINGNODE_STATE_INT:
			sprintf(transfer_string,"%d",(int) double_value);
			return (const char*) transfer_string;
			break;
		default:		// double
			sprintf(transfer_string,"%g", double_value);
			return (const char*) transfer_string;
		}
	}
	
- setString:(const char*) this
	{
	value_state=COWSSTRINGNODE_STATE_STRING;
	if (this==NULL)
		{
		if (string!=NULL) free(string);
		string=NULL;
		return self;
		}
		
	if (string!=NULL)
		{
		if (strlen(this)<=strlen(string))	// needn't allocate more space
			{
			strcpy(string,this);
			return self;
			}
		// otherwise...
		free(string);
		}
	string=newstr(this);
	return self;
	}
	
- setString:(const char*) this size:(int)this_size
	{
	value_state=COWSSTRINGNODE_STATE_STRING;
	if (this==NULL)
		{
		if (string!=NULL) free(string);
		string=NULL;
		return self;
		}
		
	if (string!=NULL)
		{
		if (this_size+1<=strlen(string))	// needn't allocate more space
			{
			strncpy(string,this,this_size);
			string[this_size]='\0';			// terminates it.
			return self;
			}
		// otherwise...
		free(string);
		}
	string=newstrn(this,this_size);
	return self;
	}
	
- free
	{
	if (string!=NULL)
		{
		free(string);
		}
	return [super free];
	}

- printContents
	{
	printf ("\t#%s#\n",string);
	return self;
	}

- setError:(BOOL)true_or_false
	{
	error=true_or_false;
	return self;
	}
	
	
- (BOOL) error
	{
	return error;
	}
	

- setDoubleVal:(double) this
	{
	double_value=this;
	value_state=COWSSTRINGNODE_STATE_DOUBLE;
	return self;
	}

- (double) doubleVal
	{
	if (value_state==COWSSTRINGNODE_STATE_STRING)
		{
		return strtod((const char*)string,(const char**)NULL);
		}
	else
		{
		return double_value;
		}
	}	
	
- setFloatVal:(float) this
	{
	double_value=(double) this;
	value_state=COWSSTRINGNODE_STATE_FLOAT;
	return self;
	}

- (float) floatVal
	{
	if (value_state==COWSSTRINGNODE_STATE_STRING)
		{
		return strtod((const char*)string,(const char**)NULL);
		}
	else
		{
		return double_value;
		}
	}	
	
- setIntVal:(int) this
	{
	double_value=(double) this;
	value_state=COWSSTRINGNODE_STATE_INT;
	return self;
	}

- (int) intVal
	{
	if (value_state==COWSSTRINGNODE_STATE_STRING)
		{
		return atoi(string);
		}
	else
		{
		return (int) double_value;
		}
	}	
	
- copyValue:(COWSStringNode*) from_this
	{
	if ([from_this value_state]==COWSSTRINGNODE_STATE_STRING)
		{
		[self setString:[from_this string]];
		}
	else
		{
		double_value=[from_this doubleVal];
		}
	value_state=[from_this value_state];
	return self;
	}
	
- (int) value_state
	{
	return value_state;
	}
	
- setBooleanVal:(BOOL) this
	{
	if (this) [self setString:"t"];
	else [self setString:""];
	return self;
	}
	
- (BOOL) booleanVal
	{
	return [self string][0];		// i.e., if first item is \0, it's false.
	}	

- (BOOL) isCanonicallyTrue
	{
	return !strcmp([self string],"t");
	}
	
- (BOOL) isCanonicallyFalse
	{
	return (![self booleanVal]);
	}

@end