//
//  MCPersistentObject.h
//  MCFoundation
//
//  Created by aj on Sat Sep 08 2001.
//  Copyright (c) 2001 Marketcircle Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
//#import "MCFoundationDefines.h"
//#import "MCPDefines.h"
//#import "MCObserverProtocol.h"

@class MCPEntity;
@class MCPObjectContext;


@protocol MCPersistentObject

- (id)initForEntity:(MCPEntity *)ent;
- (id)initForEntity:(MCPEntity *)ent rawRow:(NSMutableDictionary *)dict 
	objectContext:(MCPObjectContext *)context;
	
- (MCPEntity *)entity;

- (void)setObjectContext:(MCPObjectContext *)aContext;
- (MCPObjectContext *)objectContext;

- (void)refreshIfNeeded;

- (void)takeRawRow:(NSMutableDictionary *)dict;
- (NSDictionary *)rawRow;


- (void)refreshFromRawRow:(NSMutableDictionary *)dict;

- (void)takePrimaryKeyValue:(id)aValue forAttributeName:(NSString *)aName;


/*
If we are persistent, we return yes immediately, otherwise we a more thorough test
*/
- (int)primaryKeyState;
- (id)primaryKeyValue;

//- (id)storedValueForAttribute:(NSString *)key;
//- (void)takeStoredValue:(id)aValue forAttribute:(NSString *)key;
//- (void)removeStoredValue:(id)aValue forAttribute:(NSString *)key;


- (void)willChangeAttributeForName:(NSString *)anAttributeName;
- (NSArray *)changedAttributeNames;
- (BOOL)hasChanges;

/*
validateForSave gets called first, and then forInsert or forUpdate is called depending on whether the object is going to be inserted or updated. If you subclass or override, always call super at the end of your code (if you don't have an error). The default validation behavour is too check for string lengths and non-null values. Don't raise the exception, just return one. If you return null, the system things all is good.
*/
- (NSException *)validateForSave;
- (NSException *)validateForInsert;
- (NSException *)validateForUpdate;
- (NSException *)validateForDelete;


- (BOOL)isPersistent;
- (void)setIsPersistent:(BOOL)flag;

// lock the object for editing ...
- (BOOL)lockForEditing;
- (void)unlockFromEditing;
- (BOOL)isLockedByCurrentConnection;

//- (void)openAndLockInEditor;



/*
If you override didSave, you must call super!! Once an object is saved, it's change state is cleared (changedAttributes, addedToRelationships, removedFromRelationships) and the persistence flag is set to YES

*/
- (void)didSave;
- (void)didInsert;
- (void)didUpdate;
- (void)didDelete;


- (void)addObject:object toRelationshipWithKey:(NSString *)key;
- (void)removeObject:object fromRelationshipWithKey:(NSString *)key;


- (void)addObject:object toBothSidesOfRelationshipWithKey:(NSString *)key;
- (void)removeObject:object fromBothSidesOfRelationshipWithKey:(NSString *)key;


- (void)willAddObject:object toRelationshipWithKey:(NSString *)key;
- (void)willRemoveObject:object fromRelationshipWithKey:(NSString *)key;

- (NSDictionary *)addedToRelationships;
- (NSDictionary *)removedFromRelationships;



// set and get a parent object, this way you can always get to the theoretical owner of an object
// the parentObject is weakly retain to present retain-deadlock
- (id)parentObject;
- (void)setParentObject:(id)anObj;
// if the parent is already set, ignores the passed in value
- (void)takeParentObjectIfNotSet:(id)anObj;
// travels up the parent tree until nil is returned for the parent and returns that object
- (id)rootObject;

// calls [[self rootObject] objectGraphDocument];
- (id)document;

- (void)didInitWithCoder:(NSCoder *)aCoder;
- (void)didEncodeWithCoder:(NSCoder *)aCoder;





@end





