//
//  $Id$
//
//  MCPObject.h
//  MCPKit
//
//  Created by Serge Cohen (serge.cohen@m4x.org) on 19/05/04.
//  Copyright (c) 2004 Serge Cohen. All rights reserved.
//
//  Forked by the Sequel Pro team (sequelpro.com), April 2009
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  More info at <http://mysql-cocoa.sourceforge.net/>
//  More info at <http://code.google.com/p/sequel-pro/>

#import <Foundation/Foundation.h>

/*" Possible return code on some operations of the database interaction. "*/
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."*/
};
typedef NSUInteger 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;
- (NSUInteger) countTargetForRelation:(MCPRelation *) iRelation;
- (NSUInteger) countTargetForRelationNamed:(NSString *) iRelationName;
- (MCPObject *) getTargetOfRelation:(MCPRelation *) iRelation atIndex:(NSUInteger) iIndex;
- (MCPObject *) getTargetOfRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) 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:(NSUInteger) iIndex;
- (MCPDBReturnCode) removeTargetToRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) iIndex;
- (NSUInteger) indexOfTarget:(MCPObject *) iTarget inRelation:(MCPRelation *) iRelation;
- (NSUInteger) 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