//
//  MCPObject.h
//  MCPKit
//
//  Created by Serge Cohen on Wed May 19 2004.
//  Copyright (c) 2004 Serge Cohen. All rights reserved.
//

#import <Foundation/Foundation.h>

/*" Possible return code on some operations of the database interaction. "*/
typedef enum {
   MCPDBReturnUnknown         = 0,     /*"Unknown state, should not happen."*/
   MCPDBReturnDeleted         = 1,     /*"The entry have been successfuly deleted from DB."*/
   MCPDBReturnUsed            = 2,     /*"The entry can not be removed, because some entries are still connected to it (some delete restrict/inhibit delete)."*/
   MCPDBReturnNone            = 3,     /*"No entry exist with this Id."*/
   MCPDBReturnNew             = 4,     /*"The entry was indeed new and inserted in the database."*/
   MCPDBReturnUpdated         = 5,     /*"The entry was updated in the DB."*/
   MCPDBReturnIncompleteKey   = 6,     /*"Part of the primary key is missing, action not taken."*/
   MCPDBReturnMultiple        = 7,     /*"Multiple rows are found with a query supposed to return at most one row."*/
   MCPDBReturnNoIdentity      = 8,     /*"The object does not have attributes that defines identity."*/
   MCPDBReturnNoKey           = 9,     /*"There is no primary key defined for this entity."*/
   MCPDBReturnNoConnection    = 10,    /*"The MCPObject is not having a connection."*/
	MCPDBReturnWrongRelationOrigin = 11,		/*"Looking for a relation not which origin is not of the specified class."*/
	MCPDBReturnWrongRelationCardinality = 12,	/*"Using a method assuming a cardinality of the relation while the relation as the other one."*/
	MCPDBReturnNoSuchRelation	= 13,		/*"There is no relation with such a name starting from this class."*/
	MCPDBReturnNotTarget			= 14,		/*"Tried to remove an object from a relation, while the objects does NOT belong to the relation."*/
   MCPDBReturnOK              = 100    /*"Everything went OK."*/
} MCPDBReturnCode;

@class MCPConnection;
@class MCPClassDescription;
@class MCPRelation;

@interface MCPObject : NSObject {
   MCPClassDescription     *classDescription;
   MCPConnection           *connection;
}

#pragma mark Life of the Object
/*" Life of the object "*/
- (id) init;
- (id) initWithDictionary:(NSDictionary *) dictionary;

- (void) dealloc;

- (void) setAttributesToDefault;

#pragma mark Accessors
/*" Accessor(s) "*/
- (MCPClassDescription *) classDescription;
- (MCPConnection *) connection;

- (void) setConnection:(MCPConnection *) iConnection;

#pragma mark Database interface
/*" Database interface "*/
- (id) readFromDBRow:(NSDictionary *) iDictionary withTableName:(NSString *) iTableName;
- (MCPDBReturnCode) setPrimaryKey:(id) iDictionary andFetchFromDB:(MCPConnection *) iConnection;
//- (MCPDBReturnCode) setPrimaryKey:(NSDictionary *) iDictionary andFetchFromDB:(MCPConnection *) iConnection;
- (NSDictionary *) checkDBId;			// the returned dictionary contains a MCPDBReturnCode key with the return code.
- (NSDictionary *) saveInDB;			// the returned dictionary contains a MCPDBReturnCode key with the return code.
- (MCPDBReturnCode) getAutoGenerated;
- (MCPDBReturnCode) updateInDB;
- (MCPDBReturnCode) deleteInDB;
+ (MCPDBReturnCode) deleteInDBUsingConnection:(MCPConnection *) iConnection withId:(id) iId;

#pragma mark Handling relations
/*" Handling realtions "*/
- (id) getTargetOfRelation:(MCPRelation *) iRelation;
- (id) getTargetOfRelationNamed:(NSString *) iRelationName;
- (MCPDBReturnCode) setTarget:(id) iTarget forRelation:(MCPRelation *) iRelation;
- (MCPDBReturnCode) setTarget:(id) iTarget forRelationNamed:(NSString *) iRelationName;
- (unsigned int) countTargetForRelation:(MCPRelation *) iRelation;
- (unsigned int) countTargetForRelationNamed:(NSString *) iRelationName;
- (MCPObject *) getTargetOfRelation:(MCPRelation *) iRelation atIndex:(unsigned int) iIndex;
- (MCPObject *) getTargetOfRelationNamed:(NSString *) iRelationName atIndex:(unsigned int) iIndex;
- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation;
- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName;
- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation;
- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName;
- (MCPDBReturnCode) removeTargetToRelation:(MCPRelation *) iRelation atIndex:(unsigned int) iIndex;
- (MCPDBReturnCode) removeTargetToRelationNamed:(NSString *) iRelationName atIndex:(unsigned int) iIndex;
- (unsigned int) indexOfTarget:(MCPObject *) iTarget inRelation:(MCPRelation *) iRelation;
- (unsigned int) indexOfTarget:(MCPObject *) iTarget inRelationNamed:(NSString *) iRelationName;

#pragma mark Utilities
/*" Utility methods "*/
- (id) defaultValueForKey:(NSString *) iKey;
- (NSDictionary *) primaryKey;

/*" Testing equality (VERY important for relation management)"*/
- (BOOL) isEqual:(id) iObject;

#pragma mark Output
/*" Output : "*/
- (NSString *) description;
- (NSString *) descriptionWithLocale:(NSDictionary *) locale;

#pragma mark Ordering the array for relations
- (NSString *) orderSQLForClassDescription:(MCPClassDescription *) iClassDescription;

/*" Anti-crash method... "*/
- (void) setNilValueForKey:(NSString *) iKey;

@end
