//
//  EXPSymbolReference.m
//  XMLTest
//
//  Created by Ashley on 12/05/2007.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "EXPDataElement.h"
#import "EXPAssignmentOp.h"
#import "EXPSymbolReference.h"
#import "EXPElement.h"
#import "EXPDimensionElement.h"
#import "EXPDimensionItemElement.h"
#import "EXPIndexElement.h"
#import "EXPConstant.h"
#import "EXPIndexElement.h"
#import "EXPStateElement.h"
//#import "EXPAssemblerConstants.h"
#import "EXPVirtualMachine.h"
#import "EXPSymbolTable.h"
#import "EXPParser.h"
#import "EXPError.h"

/* BOOL compileIndexOffset(EXPVirtualMachine *machine, NSArray *dimensions, int baseAddress, int *variableAddress, EXPError *err)
{
	BOOL knowAddress = YES;
	*variableAddress = 0;
	
	*variableAddress = baseAddress;
	if ([dimensions count]>0) {
		EXPElement *item = [dimensions objectAtIndex:0];
		EXPDimensionElement *dimension = [dimensions objectAtIndex:0];
		int index;
		NSString *itemType = [item elementType];
		EXPExpression *indexExp = nil;
	
		if ([itemType isEqualToString:@"dimension"]) {
			index = [item address];
			indexExp = [[EXPIndexElement alloc] init];
			[indexExp setAddress:index];
			knowAddress = NO;
		} else {
			index = [dimension indexOfItem:item];
			indexExp = [[EXPConstant alloc] initWithName:@""];
			[indexExp setValue:index];
		}

		int i;
		for(i=1; i<[dimensions count]; i++) {
			item = [dimensions objectAtIndex:i];
			dimension = [dimensions objectAtIndex:i];
			index = [dimension indexOfItem:item];
//			NSLog(@"%@", index);
		}
	
		if (knowAddress) {
			*variableAddress += [(EXPConstant *)indexExp value];
		} else {
			[indexExp compile:machine error:err];
		}

		[indexExp release];
	}
	
	return knowAddress;
} */

@implementation EXPSymbolReference

- (id) init
{
	self = [super init];	
	_element = nil;
	_arguments = [[NSMutableArray alloc] init];
	_dimensions = [[NSMutableArray alloc] init];

	return self;
}

/*- (id) retain
{
	printf("EXPSymbolReference - retaining reference to %s\n", [[_element name] UTF8String]);
	return [super retain];
}

- (void) release
{
	printf("EXPSymbolReference - releasing reference to %s\n", [[_element name] UTF8String]);
	[super release];
} */

- (void) setElement:(id)element
{
	[element retain];
	[_element release];
	_element = element;
}

- (id) element
{
	return _element;
}

- (void) setArguments:(id)arguments
{
	[arguments retain];
	[_arguments release];
	_arguments = arguments;
}

- (id) arguments
{
	return _arguments;
}

- (void) addArgument:(id)argument
{
	[[self arguments] addObject:argument];
}

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

- (id) dimensions
{
	return _dimensions;
}

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

/*- (void) setIsSimple:(BOOL)isSimple
{
	_isSimple = isSimple;
} */

/*- (BOOL) isArray
{
	return [[self dimensions] count]>0;
}*/

- (void) setSimple:(BOOL) simple
{
	_simple = simple;
}

- (void) setPrimes:(int)primes
{
	_primes = primes;
}

- (int) primes
{
	return _primes;
}

- (BOOL) isSimple
{
	return _simple;
}

- (BOOL) isConstant
{
	EXPElement *element = [self element];
	BOOL constant = [element isKindOfClass:[EXPConstant class]];
	
	return constant;
}

- (NSString *)elementType
{
	return [[self element] elementType];
}

- (NSString *) description
{
	NSMutableString *desc = [NSMutableString string/*WithString:@"EXPSymbolReference: "*/];
	[desc appendString:[[self element] name]];
	
	int i;
	for(i=0; i<[self primes]; i++) {
		[desc appendString:@"'"];
	}
	
	NSArray *dimensions = [self dimensions];
	int d = [dimensions count];
	if (d>0) {
		[desc appendString:@"["];
		for(i=0; i<d; i++) {
			if (i>0) {
				[desc appendString:@","];
			}
			NSString *name = [[dimensions objectAtIndex:i] description];
			if (name!=nil) {
				[desc appendString:name];
			} else {
				[desc appendString:@"???"];
			}
		}
		[desc appendString:@"]"];
	}
	
	NSArray *arguments = [self arguments];
	d = [arguments count];
	if (d>0) {
		[desc appendString:@"("];
		for(i=0; i<d; i++) {
			if (i>0) {
				[desc appendString:@","];
			}
			EXPElement *argument = [arguments objectAtIndex:i];
			[desc appendString:[argument description]];
		}
		[desc appendString:@")"];
	}
	
	return desc;
}

- (void) dealloc
{
	[_element release];
	[_arguments release];
	[_dimensions release];
	[super dealloc];
}

@end