//
//  MCPModel.h
//  MCPersistence
//
//  Created by aj on Fri Dec 21 2001.
//  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

extern NSString *MCModelUserInfoKey;

extern NSString*  MCModelSettingsSourceTemplatePathKey;
extern NSString*  MCModelSettingsHeaderTemplatePathKey;
extern NSString*  MCModelSettingsSubSourceTemplatePathKey;
extern NSString*  MCModelSettingsSubHeaderTemplatePathKey;
extern NSString*  MCModelSettingsOutputPathKey;


typedef enum _MCPDatabaseEngineType {
	MCPDatabaseOpenBaseEngineType = 1,
	MCPDatabaseSQLiteEngineType,
	MCPDatabasePostgresEngineType
} MCPDatabaseEngineType;

#define MCPDatabaseSchemaTables     0x01
#define MCPDatabaseSchemaIndices    0x02
#define MCPDatabaseSchemaSequences  0x04
#define MCPDatabaseSchemaProcedures 0x08
#define MCPDatabaseSchemaTriggers   0x10

#define MCPDatabaseSchemaAll (MCPDatabaseSchemaTables | MCPDatabaseSchemaIndices | MCPDatabaseSchemaSequences | MCPDatabaseSchemaProcedures | MCPDatabaseSchemaTriggers)


@class MCPEntity,MCPRelationship, MCPAttribute;

@interface MCPModel : NSObject <NSCoding> {

	NSMutableArray*          _entities;
	
	NSMutableDictionary		*_entitiesByName;
	NSMutableDictionary		*_entitiesByClassname;
	NSMutableDictionary		*_entitiesByTablename;
	NSMutableDictionary     *_entitiesByID;
	id						_index;
	
	NSMutableSet			*_bulkFaultingEntities;

	BOOL                     __usesDerivedLinkedFlags;

	// A dictionary keyed by entity which contains a dictionary keyed by relationship destination name
	// So for instance if you passed a contact
	NSMutableDictionary     *_relationshipsByEntityDestinationName;
	NSMutableDictionary     *_toManyRelationshipsByEntityDestinationName;
	NSMutableDictionary     *_toOneRelationshipsByEntityDestinationName;
	
	NSMutableDictionary*     _settings;
}

/* Going forward, please use this method instead of defaultModel, as that will be removed at a later date.
 This method internally uses a cache for all models loaded based on the path. */
+ (MCPModel *)modelForPath:(NSString *)aPath;

/* 
 The concept of a "default model" will be removed in Daylite 4.
 For most common uses, you should probably get it from the database connection, 
 object context or document.
 */
+ (id)defaultModel DEPRECATED_ATTRIBUTE;
+ (void)setDefaultModel:(MCPModel *)aMod;

// Used to manage the table aliases for SQL generation Application wide!
+ (NSString *)tableAliasForEntity: (MCPEntity *)entity;
+ (NSMutableDictionary *)tableAliasCache;
+ (NSString *)tableAliasString;
    // FIXME: this is a hack for the 1.2 release (which went to the wire)
+ (void)resetTableAliasCache;

- (id)initWithSerializedWrapperData:(NSData *)dt;
- (id)initWithModelFile:(NSString *)path;

- (void)appendModelFromSerializedWrapperData:(NSData *)data;
- (void)appendModelFile:(NSString *)path;

- (NSNumber*)highestEntityUniqueIdentifier;

- (id)entityForClassname:(NSString *)classname;
- (id)entityForClass:(Class)aClass;

- (id)entityForTableName:(NSString *)aName;
- (id)entityForName:(NSString *)aName;

- (id)entityForEntityID:(NSNumber *)anID;
- (NSString *)tableNameForEntityID:(NSNumber *)anID;
- (NSArray *)entityIDs;

// All the relationships in the model that have this entity as the destination
- (NSArray *)relationshipsForDestinationEntityNamed:(NSString *)entName;

// Goes through each entity and adds an attribute $relName$Count to each to-many relationship. (i.e. relationship "tasks" gets "tasksCount" attribute)
- (void)dynamicallyAddLinkedFlagAttributes;

- (NSArray *)entities;
- (NSDictionary *)userInfo;

- (void)encodeWithKeyedCoder:(NSCoder *)coder;
- (void)encodeWithCoder:(NSCoder *)coder;

- (id)initWithKeyedCoder:(NSCoder *)coder;
- (id)initWithCoder:(NSCoder *)decoder;

- (void)addToBulkFaultingEntities:(MCPEntity *)ent;
- (NSArray *)bulkFaultingEntities;
- (BOOL)isBulkFaultingEntity:(MCPEntity *)ent;

- (BOOL)usesDerivedLinkedFlags;

- (void)addRelationship:(MCPRelationship *)aRel forDestinationName:(NSString *)aDest;
- (NSArray *)relationshipsForDestinationEntityNamed:(NSString *)aDest;
- (NSArray *)toManyRelationshipsForDestinationEntityNamed:(NSString *)aDest;
- (NSArray *)toOneRelationshipsForDestinationEntityNamed:(NSString *)aDest;

- (MCPEntity *)createAndAddEntity;
- (void)removeEntity: (MCPEntity*) entity;

- (BOOL)writeToFile: (NSString*)path;

- (NSMutableDictionary*)settings;

- (NSMutableArray*)products;
- (void)setProducts: (NSMutableArray*)aProducts;


- (NSArray*)schemaSQLCreationCommandsForDatabaseEngineType: (MCPDatabaseEngineType)aType schemaGenerationMask: (int)mask;

@end
