//
//  MatchExpression.m
//  SFS2X
//
//  Original development by Infosfer Game Technologies Ltd. | http://www.infosfer.com.
//
//  Maintained and developed by A51 Integrated.
//  Copyright 2012 A51 Integrated | http://a51integrated.com. All rights reserved.
//

#import "MatchExpression.h"
#import "LogicOperator.h"
#import "ISFSArray.h"
#import "SFSArray.h"




@implementation MatchExpression

@synthesize varName = _varName;
@synthesize condition = _condition;
@synthesize value = _value;
@synthesize logicOp = _logicOp;
@synthesize parent = _parent;
@synthesize next = _next;


-(MatchExpression *)chainedMatchExpression:(NSString *)varName condition:(id <IMatcher>)condition value:(id)value logicOp:(LogicOperator *)logicOp parent:(MatchExpression *)parent {
	
	MatchExpression *matchingExpression = [[MatchExpression alloc] initWithVarName:varName condition:condition value:value];
	matchingExpression.logicOp = logicOp;
	matchingExpression.parent = parent;
	
	
	return matchingExpression;
}


-(id)initWithVarName:(NSString *)varName condition:(id <IMatcher>)condition value:(id)value {
	
	if ((self = [super init])) {
		self.varName = varName;
		self.condition = condition;
		self.value = value;
	}
	
	return self;
}

+(id)expressionWithVarName:(NSString *)varName condition:(id <IMatcher>)condition value:(id)value {
	MatchExpression *expr = [[MatchExpression alloc] initWithVarName:varName condition:condition value:value];
	return expr;
}

-(MatchExpression *)and:(NSString *)varName condition:(id <IMatcher>)condition value:(id)value {
	self.next = [self chainedMatchExpression:varName condition:condition value:value logicOp:[LogicOperator logicOperatorAnd] parent:self];
	return _next;
}

-(MatchExpression *)or:(NSString *)varName condition:(id <IMatcher>)condition value:(id)value {
	self.next = [self chainedMatchExpression:varName condition:condition value:value logicOp:[LogicOperator logicOperatorOr] parent:self];
	return _next;
}

-(BOOL)hasNext {
	return _next != nil;
}

-(MatchExpression *)rewind {
	MatchExpression *currNode = self;
	
	while (YES) {
		if (currNode.parent != nil) {
			currNode = currNode.parent;
		}
		else {
			break;
		}

	}
	
	return currNode;
}


-(NSString *)asString {
	NSString *sb = [NSString string];
	
	if (_logicOp != nil) {
		sb = [NSString stringWithFormat:@"%@ %@ ", sb, _logicOp.id];
	}
	
	sb = [NSString stringWithFormat:@"%@(%@ %@ %@)", sb, _varName, [_condition symbol], ([_value isKindOfClass:[NSString class]] ? [NSString stringWithFormat:@"'%@'", _value] : _value)];
	
	return sb;
}

-(NSString *)description {
	
	MatchExpression *expr = [self rewind];
	NSString *sb = [expr asString];
	
	while ([expr hasNext]) {
		expr = expr.next;
		
		sb = [NSString stringWithFormat:@"%@%@", sb, [expr asString]];
	}
	
	return sb;
}


-(id<ISFSArray>)toSFSArray {
	MatchExpression *expr = [self rewind];
	id <ISFSArray> sfsa = [SFSArray newInstance];
	
	[sfsa addSFSArray:[expr expressionAsSFSArray]];
	
	while ([expr hasNext]) {
		expr = expr.next;
		
		[sfsa addSFSArray:[expr expressionAsSFSArray]];
	}
	
	return sfsa;
	
}

-(id <ISFSArray>)expressionAsSFSArray {
	
	id <ISFSArray> expr = [SFSArray newInstance];
	
	if (_logicOp != nil) {
		[expr addUtfString:_logicOp.id];
	}
	else {
		[expr addNull];
	}
	
	[expr addUtfString:_varName];
	
	[expr addByte:[_condition type]];
	
	[expr addUtfString:[_condition symbol]];
	
	if ([_condition type] == 0) {
		[expr addBool:[(NSNumber *)_value boolValue]];
	}
	else if ([_condition type] == 1){
		[expr addDouble:(NSNumber *)_value];
	}
	else {
		[expr addUtfString:(NSString *)_value];
	}

	return expr;

}

@end
