//
//  EXPTableElement.m
//  XMLTest
//
//  Created by Ashley on 01/06/2007.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "EXPTableElement.h"

@implementation EXPTableElement

- (id) init
{
	if ([super init]==nil) {
		return nil;
	}
	
	_type = nil;
	
	return self;
}

- (void) setInterpType:(int)interpType
{
	_interpType = interpType;
}

- (int) interpType
{
	return _interpType;
}

- (void) setXPoints:(id)xPoints
{
	[xPoints retain];
	[_xPoints release];
	_xPoints = xPoints;
}

- (id) xPoints
{
	return _xPoints;
}

- (void) setYPoints:(id)yPoints
{
	[yPoints retain];
	[_yPoints release];
	_yPoints = yPoints;
}

- (id) yPoints
{
	return _yPoints;
}

- (BOOL) setElementFromParser:(EXPParser *)parser symbolTable:(EXPSymbolTable *)symbolTable inputs:(id)inputs
{
	NSString *identifier = [[NSString alloc] initWithString:[parser symbol]];
	[parser readSymbol];
	[self setName:identifier];
			
	if (![parser checkSymbol:@"="]) {
		[identifier release];
		return NO;
	}
			
	NSString *tableType = [[NSString alloc] initWithString:[parser symbol]];
	[parser readSymbol];
	
	EXPExpressionList *expressionList = [self expressionList];
//	[expressionList addName:@"bracket" andValue:@"("];

	if (![parser checkSymbol:@"("]) {
		[identifier release];
		[tableType release];
		return NO;
	}
	
	BOOL success = YES;
	int nPoints = 0;
	for(;;) {
		if (![parser checkSymbol:@"{"]) {
			success = NO;
			break;
		}
		
//		EXPExpression *exp1 = [EXPExpression expression:parser];
		[expressionList setExpressionListFromParser:parser symbolTable:symbolTable inputs:inputs];
		[expressionList addName:@"separator" andValue:@"|"];
		
		if (![parser checkSymbol:@","]) {
//			[exp1 release];
			success = NO;
			break;
		}

		[expressionList setExpressionListFromParser:parser symbolTable:symbolTable inputs:inputs];
		[expressionList addName:@"separator" andValue:@"|"];

//		EXPExpression *exp2 = [EXPExpression expression:parser];
//		NSArray *point = [[NSArray alloc] initWithObjects:exp1, exp2, nil];
		
//		[expressionList addName:@"point" andValue:point];
		
//		[point release];
//		[exp2 release];
//		[exp1 release];

		nPoints++;

		if (![parser checkSymbol:@"}"]) {
			success = NO;
			break;
		}
		
		if (![parser testSymbol:@","]) {
			break;
		}

	}
			
	if (![parser checkSymbol:@")"]) {
		[identifier release];
		[tableType release];
		return NO;
	}
	_nItems = nPoints;
//	[expressionList addName:@"bracket" andValue:@")"];
	
//	[self setExpressionList:expressionList];
//	[expressionList release];
			
//	gsl_spline *_spline;
	if ([tableType isEqualToString:@"linear"]) {
		[self setInterpType:LINEAR];
//		spline = gsl_spline_alloc(gsl_interp_linear, nPoints);
	} else if ([tableType isEqualToString:@"polynomial"]) {
		[self setInterpType:POLYNOMIAL];
//		spline = gsl_spline_alloc(gsl_interp_polynomial, nPoints);
	} else if ([tableType isEqualToString:@"cspline"]) {
		[self setInterpType:CSPLINE];
//		spline = gsl_spline_alloc(gsl_interp_cspline, nPoints);
	} else if ([tableType isEqualToString:@"csplineperiodic"]) {
		[self setInterpType:CSPLINEPERIODIC];
//		spline = gsl_spline_alloc(gsl_interp_cspline_periodic, nPoints);
	} else if ([tableType isEqualToString:@"gsl_interp_akima"]) {
		[self setInterpType:AKIMA];
//		spline = gsl_spline_alloc(gsl_interp_linear, nPoints);
	} else if ([tableType isEqualToString:@"akimaperiodic"]) {
		[self setInterpType:AKIMAPERIODIC];
//		spline = gsl_spline_alloc(gsl_interp_akima_periodic, nPoints);
	} else {
		[identifier release];
		[tableType release];
		return NO;
	}

	[identifier release];
	[tableType release];
	
	return success;
}

- (void) generateParseTree
{
	EXPExpressionList *list = [self expressionList];
//	NSArray *list = [[self expressionList] list];
	NSMutableArray *xPoints = [[NSMutableArray alloc] init];
	NSMutableArray *yPoints = [[NSMutableArray alloc] init];
//	int n = [[[self expressionList] list] count];
	int i;
	for(i=0; i<_nItems; i++) {
		EXPExpression *exp1 = [EXPExpression expression:list];
		[list readSymbol];
		EXPExpression *exp2 = [EXPExpression expression:list];
		[list readSymbol];
		[xPoints addObject:exp1];
		[yPoints addObject:exp2];
		[exp2 release];
		[exp1 release];
	}
	
	[self setXPoints:xPoints];
	[self setYPoints:yPoints];
	
	[xPoints release];
	[yPoints release];
	
} 

- (BOOL) compile:(EXPStackMachine *)machine error:(NSError **)err withArguments:(NSArray *)arguments
{
	BOOL success = YES;
	int numArgs = [arguments count];
	if (numArgs!=1) {
		return NO;
	}

	EXPExpression *argument = [arguments objectAtIndex:0];
	success = [argument compile:machine error:err];
	
	if (!success) {
		return NO;
	}
	
	[machine putUInt:INTERP];
	unsigned int address = [self address];
	[machine putUInt:address];

	return success;
}

- (NSString *)elementType
{
	return @"table";
}

- (void) dealloc
{
	[_xPoints release];
	[_yPoints release];
	[_type release];
	[super dealloc];
}

@end
