//
//  MCPSQLGenerator.h
//  SQLGenerationTest
//
//  Created by Michael Clark on 19/03/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "MCQueryProcessor.h"

#define GEN_FIX

@class BDQualifier, MCPEntity, MCPTableAliases;



typedef enum _MCPQualifierNodeType {
	MCPQualifierContainerNodeType   = 1,
    MCPQualifierKeyValueComparisonNodeType,
    MCPQualifierKeyComparisonNodeType,
	MCPQualifierGroupNodeType
} MCPQualifierNodeType;

typedef enum _MCPQualifierComparisonType {
	MCPQualifierKeyValueComparisonType = 1,
	MCPQualifierKeyComparisonType
} MCPQualifierComparisonType;




// This is the payload for a KeyComparison comparison node - tells the comparison operation and the root entity key, the destination key comes from the owning group node
// The KeyComparisonQualifier LHS is assumed to be the rootEntityKey, and the RHS is assumed to be the destination key
typedef struct _MCPQualifierTreeKeyComparisonPayload*   MCPQualifierTreeKeyComparisonPayloadPtr;

typedef struct _MCPQualifierTreeKeyComparisonPayload {
	SEL           comparisonOperation;
	NSString*     rootEntityKey;
} MCPQualifierTreeKeyComparisonPayload;


// This is the payload for a KeyValue comparison node - tells the comparison operation and the value, the key comes from the owning group node
typedef struct _MCPQualifierTreeKeyValueComparisonPayload*   MCPQualifierTreeKeyValueComparisonPayloadPtr;

typedef struct _MCPQualifierTreeKeyValueComparisonPayload {
	SEL           comparisonOperation;
	id            value;
} MCPQualifierTreeKeyValueComparisonPayload;


// The GroupPayload contains the information about a grouped set (or individual) of ComparisonPayloads - the group is used by the container node to keep track of sub qualifiers with the same destination entity and key
typedef struct _MCPQualifierTreeGroupPayload*   MCPQualifierTreeGroupPayloadPtr;

typedef struct _MCPQualifierTreeGroupPayload {
	MCPQualifierComparisonType           comparisonType;
	MCPEntity*                           destinationEntity;
	NSString*                            destinationKey;
	NSString*                            fullKeyPath;
} MCPQualifierTreeGroupPayload;	


// The ContainerPayload stores the Boolean operation type for the container, currently only AND, OR and NOT
typedef struct _MCPQualifierTreeContainerPayload*   MCPQualifierTreeContainerPayloadPtr;

typedef struct _MCPQualifierTreeContainerPayload {
	MCQueryBooleanType      booleanType;
} MCPQualifierTreeContainerPayload;


typedef struct _MCPQualifierTreeNode*   MCPQualifierTreeNodePtr;

typedef struct _MCPQualifierTreeNode {
	MCPQualifierNodeType             nodeType;
	union {
		MCPQualifierTreeKeyValueComparisonPayloadPtr  keyValueComparison;
		MCPQualifierTreeKeyComparisonPayloadPtr       keyComparison;
		MCPQualifierTreeGroupPayloadPtr               group;
		MCPQualifierTreeContainerPayloadPtr           container;
	} payload;
	int                              numberOfEntries;
	MCPQualifierTreeNodePtr*         nodes;
} MCPQualifierTreeNode;


#define keyValueComparisonPayload    payload.keyValueComparison
#define keyComparisonPayload         payload.keyComparison
#define groupPayload                 payload.group
#define containerPayload             payload.container





@interface MCPSQLGenerator : NSObject {
	MCPEntity*             __entity;
	BDQualifier*           __qualifier;
	NSStringEncoding       __encoding;
	
	NSData*                __sqlWhereClause;
	
	MCPQualifierTreeNodePtr    __treeRoot;
	
	MCPTableAliases*       __tableAliases;
	BOOL                   __needsTableAliases;
	
	int                    __bindingsKeyNumber;
	NSMutableDictionary*   __bindings;
}

+ (void)setSQLGeneratorClass: (Class)aClass;

+ (NSData*)generateSQLForQualifier: (BDQualifier*)qualifier rootEntity: (MCPEntity*)entity databaseEncoding: (NSStringEncoding)encoding tableAliases: (MCPTableAliases**)tableAliases bindings: (NSDictionary**)bindings;
+ (NSData*)generateSQLForQualifier: (BDQualifier*)qualifier rootEntity: (MCPEntity*)entity databaseEncoding: (NSStringEncoding)encoding tableAliases: (MCPTableAliases**)tableAliases;
+ (NSData*)generateSQLForQualifier: (BDQualifier*)qualifier rootEntity: (MCPEntity*)entity tableAliases: (MCPTableAliases**)tableAliases; 
	// Uses MCOSRoman encoding by default



- (id)initWithQualifier: (BDQualifier*)qualifier rootEntity: (MCPEntity*)entity databaseEncoding: (NSStringEncoding)encoding useBindings: (BOOL)flag;

- (NSString*)swapWildcardsForSQLValue: (NSString*)val forComparisonSelector: (SEL)aSelector;
// Subclassers can override this method to swap out the * wildcard characters to something else - this method simply returns the input without modification
- (NSString *)sqlComparisonForSelector: (SEL)selector value: (id)value;
// Subclassers can override this method to change the SQL comparison operators used


- (NSData*)sqlWhereClauseData;

- (void)printQualifierTree;
- (NSString*)qualifierTreeDescription;

- (BOOL)usedTableAliases;
- (MCPTableAliases *)tableAliases;
- (void)setTableAliases:(MCPTableAliases *)aTableAliases;

- (NSMutableDictionary *)bindings;
- (void)setBindings:(NSMutableDictionary *)aBindings;

@end
