//
//  EXPBlockElement.m
//  dde
//
//  Created by ashley on 04/05/2008.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "EXPBlockElement.h"
#import "EXPParameterElement.h"
#import "EXPAuxiliaryElement.h"
#import "EXPStateElement.h"
#import "EXPAssignmentOp.h"
#import "EXPSymbolTable.h"
#import "EXPFunctionElement.h"
#import "EXPError.h"

@implementation EXPBlockElement

- (id) initWithEnclosingBlock:(id)enclosingBlock
{
	self = [super init];
	if (self!=nil) {
		_enclosingBlock = enclosingBlock;
		_symbolTable = [[EXPSymbolTable alloc] init];
		[_symbolTable setParentTable:[enclosingBlock symbolTable]];
/*		if (enclosingBlock==nil) {
			[EXPFunctionElement registerDefaultFunctions:_symbolTable];
			[self declareBuiltinVariables];
		} */
		
		_hasStatements = NO;

		_statements = [[NSMutableArray alloc] init];
		_statements = [[NSMutableArray alloc] init];
		_initialisers = [[NSMutableArray alloc] init];
		
		_dimensions = [[NSMutableArray alloc] init];
		_functions = [[NSMutableArray alloc] init];
		_variables = [[NSMutableArray alloc] init];
		_parameters = [[NSMutableArray alloc] init];
		_auxiliaries = [[NSMutableArray alloc] init];
		_tables = [[NSMutableArray alloc] init];
		_switches = [[NSMutableArray alloc] init];
		_outputters = [[NSMutableArray alloc] init];
		
		_options = [[NSMutableDictionary alloc] initWithObjectsAndKeys: 
					@"0.0", @"tstart",
					@"10.0", @"tstop",
					@"1.0e-2", @"tstep",
					@"1.0e-08", @"epsilon",
					@"1.0e-1", @"outstep",
					@"2000", @"histsize", 
					@"aqt", @"device",
					@"", @"plotfile", 
					@"No", @"printheader", 
				    nil];
	
		_names = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					@"tstart", @"tstart",
					@"tstop", @"tstop",
					@"t", @"t",
					nil];
	}

	return self;
}

- (void) setSymbolTable:(id)symbolTable
{
	[symbolTable retain];
	[_symbolTable release];
	_symbolTable = symbolTable;
}

- (id) symbolTable
{
	return _symbolTable;
}

- (id) enclosingBlock
{
	return _enclosingBlock;
}

- (void) setHasStatements:(BOOL)hasStatements
{
	_hasStatements = hasStatements;
}

- (BOOL) hasStatements
{
	return _hasStatements;
}

- (void) setStatements:(id)statements
{
	[statements retain];
	[_statements release];
	_statements = statements;
}

- (void) addStatement:(id)statement error:(id)error
{
	if (statement!=nil) {
		[[self statements] addObject:statement];
	}
}

- (id) statements
{
	return _statements;
}

- (void) setInitialisers:(id)initialisers
{
	[initialisers retain];
	[_initialisers release];
	_initialisers = _initialisers;
}

- (void) addInitialiser:(id)initialiser error:(id)error
{
	[[self initialisers] addObject:initialiser];
}

- (id) initialisers
{
	return _initialisers;
}

- (void) setVariables:(id)variables
{
	[variables retain];
	[_variables release];
	_variables = variables;
}

- (void) addVariable:(id)variable error:(id)error
{
	[variable setExpressions:nil];
	[[self variables] addObject:variable];
}

- (id) variables
{
	return _variables;
}

- (void) setParameters:(id)parameters
{
	[parameters retain];
	[_parameters release];
	_parameters = parameters;
}

- (void) addParameter:(id)parameter error:(id)error
{
	[parameter setExpressions:nil];
	[[self parameters] addObject:parameter];
}

- (id) parameters
{
	return _parameters;
}

- (void) setAuxiliaries:(id)auxiliaries
{
	[auxiliaries retain];
	[_auxiliaries release];
	_auxiliaries = auxiliaries;
}

- (void) addAuxiliary:(id)auxiliary error:(id)error
{
	[[self auxiliaries] addObject:auxiliary];
}

- (id) auxiliaries
{
	return _auxiliaries;
}

- (void) setTables:(id)tables
{
	[tables retain];
	[_tables release];
	_tables = tables;
}

- (void) addTable:(id)table error:(id)error
{
	[[self tables] addObject:table];
}

- (id) tables
{
	return _tables;
}

- (void) setSwitches:(id)switches
{
	[switches retain];
	[_switches release];
	_switches = switches;
}

- (void) addSwitch:(id)swtch error:(id)error
{
	[[self switches] addObject:swtch];
}

- (id) switches
{
	return _switches;
}

- (int) nSwitches
{
	NSArray *switches = [self switches];
	return [switches count];
}

- (void) setOutputters:(id)outputters
{
	[outputters retain];
	[_outputters release];
	_outputters = outputters;
}

- (void) addOutputter:(id)outputter error:(id)error
{
	[[self outputters] addObject:outputter];
}

- (id) outputters
{
	return _outputters;
}

- (void) setFunctions:(id)functions
{
	[functions retain];
	[_functions release];
	_functions = functions;
}

- (void) addFunction:(id)function error:(id)error
{
	if (function!=nil) {
		[[self functions] addObject:function];
	}
}

- (id) functions
{
	return _functions;
}

- (void) setDimensions:(id)dimensions
{
	[dimensions retain];
	[_dimensions release];
	_dimensions = dimensions;
}

- (void) addDimension:(id)dimension error:(id)error
{
	[[self dimensions] addObject:dimension];
}

- (id) dimensions
{
	return _dimensions;
}

- (void) list
{
	NSArray *initialisers = [self initialisers];
	EXPAssignmentOp *assignment;
	
	printf("\n");
	int i;
	for(i=0; i<[initialisers count]; i++) {
		assignment = [initialisers objectAtIndex:i];
		printf("%s\n", [[assignment description] UTF8String]);
	}
	
	printf("\n");
	NSArray *statements = [self statements];
	for(i=0; i<[statements count]; i++) {
		assignment = [statements objectAtIndex:i];
		printf("%s\n", [[assignment description] UTF8String]);
	}
	
}

- (id) option:(NSString *)name
{
	id option = [_options valueForKey:name];
	return option;
}

- (void) setOption:(id) value forName:(NSString *)name
{
	if ([_options valueForKey:name]!=nil) {
		[_options setValue:value forKey:name];
	}
}

- (id) options
{
	return _options;
}

- (id) names
{
	return _names;
}

- (id) nameForName:(id)name
{
	return [_names objectForKey:name];
}

- (void) dealloc
{
//	NSLog(@"Deallocating block");

	[_statements release];
	[_initialisers release];
	[_symbolTable release];

	[_functions release];
	[_dimensions release];
	[_variables release];
	[_parameters release];
	[_auxiliaries release];
	[_tables release];
	[_switches release];
	[_outputters release];
	
	[_options release];
	[_names release];
	
	[super dealloc];
}


@end