
#import <Foundation/NSObject.h>

@class MCTableviewController;

@interface MCAMD:NSObject
{
	id		tvc;
	id		(model);
	id		(objectClass);
	id		binder;
	id		window;
	
	id		addButton;
	id		modifyButton;
	id		deleteButton;

	id		delegate;
	id		target;
	SEL		doubleAction;
	
    id		firstKeyView;
    
	BOOL		isMutable;
	
	// Inspector controlled attributes
	
	int			confirmDelete;
	NSString	*alertPanelTitle;
	NSString	*alertPanelBody;
	int			checkMandatory;
	int			keyEnable;
	int			buttonEnable;	// Enable/Disable based on selection
	int			mutableEnable;
	int			bindOnDeselect;
	int			selectOnAdd;
    int			deselectOnModify;
	int			privilege;
	NSString	*objectClassName;

        // Now we hold on to our temp object for BIND_EMPTY
	id			(tempNewObject);
    
    
    SEL			createAndAddSelector;
    SEL			removeSelector;
    SEL			relationshipSelector;
    
    NSString	*relationshipName;
    
    BOOL		isHandlingPList; 	// if a dictionary is passed in a model, it is assumed the whole thing is a plist
}

// delegate not retained
- (void)setDelegate:(id)aDeleg;
- (id)delegate;


// objectClass used to create temporary object
- (void)setObjectClass:aClass model:aModel;
- (void)setObjectClass:aClass;


// sets the relationship name -- this is used to created 
// the various selectors used on the model object. Selectors 
// follow the following pattern:
//
// - (id)createAndAddTo<CapitalizedRelationshipName>
// - (id)createAndAddToTimeblocks
//
// - (NSMutableArray *)<relationshipName>
// - (NSMutableArray *)timeblocks;
//
// - (void)removeFrom<CapitalizedRelationshipName>:(id)anObject
// - (void)removeFromTimeblocks:(id)aBlock
- (void)setRelationshipName:(NSString *)aName;
- (NSString *)relationshipName;

- (NSMutableArray *)relationshipList;
- (id)createNewRelationshipObject;

// should be an object on which we invoke the relationship 
// selector to get the list. Throws an exception if not
- (void)setModel:(id)aModel;
- (id)model;

- (void)update;


- (void)setConfirmDelete:(BOOL)flag;
- (void)enableAdd:(BOOL)canAdd modify:(BOOL)canModify delete:(BOOL)canDelete;
- (void)setMutable:(BOOL)flag;
- (BOOL)isMutable;

- (id)target;
- (void)setTarget:(id)sender;
- (SEL) doubleAction;
- (void)setDoubleAction:(SEL)aSel;
- (void)tvcDidDoubleClick:(id)sender;

- (IBAction)add:(id)sender;
- (IBAction)modify:(id)sender;
- (IBAction)delete:(id)sender;

// does the actual delete work -- asking the delegate etc etc ...
- (BOOL)deleteSelectedObject;

// deletes without asking delegate ...
- (void)forceDeleteObject:(id)anObject;


- (void)setObject:(id)anObject;
- (id)selectedObject;
- (void)selectObject:(id)anObject;
- (void)selectObjectAt:(int)aDisplayPosition;
- (IBAction)deselectAll:(id)sender;

- (void)selectFirstKeyView;
- (BOOL)selectUIForModel:aModel andAttribute:(NSString *)anAttribute;
- (BOOL)allFieldsIncomplete;
- (void)triggerFormatterForUI:errorList;

- (BOOL)isUsingObject:anObject;
- (id)binder;
- (id)tvc;


// Returns the window currently displaying either it's button, tvc -- useful when dealing with switchviews
- (NSWindow *)firstWindow;

	/*** Private ***/
- (void)setFieldEnablingForSelection:anObject;
- (void)setButtonsForSelection:anObject;
- (void)enableButton:aButton priviledgeMask:(int)mask;

- (BOOL)finishEditting;
- (BOOL)finishEdittingAndCheckMandatory:(BOOL)check;

@end


	/*	--------------------------------------------------------
							Delegate Methods
		--------------------------------------------------------  */
		
@interface NSObject (AMDDelegate)

- (BOOL)amd:anAMD willProcessButtonStatesForObject:(id)obj;
    // if the delegate responds and returns NO, button will disabled no matter what, otherwise standard enable/disable behavior applies

- (BOOL)amd:anAMD willEnableBinderFields:(id)aBinder forObject:(id)obj;
    // if the delegate responds and return NO, binder bindings will be disabled no matter what, otherwise standard behavior applies


- amd:anAMD needsNewObjectForRelationshipList:aList;
	// The delegate can utilize this method to provide the new object
	// to be used in the add operation

- (BOOL)amdShouldChangeSelection:anAMD;
    // Asks the delegate if the selection should change

- (void)amd:anAMD willSetSelection:anObject;
    // informs the delegate that the selection will be set

- (void)amd:anAMD didChangeSelection:anObject;
	// Informs the delegate that the selected object is now different
	// Return is ignored

- (BOOL)amd:anAMD shouldDisplayObject:anObject;
	// Asks the delegate if the object should be displayed


- (BOOL)amd:anAMD canDeleteObject:anObject;
    // if the delegate responds, it is consulted before any alert panels are shown



	/****** Add / Modify / Delete *******/

- (BOOL)amd:anAMD willAddObjectUsingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// warns the delegate of an impending add. If the delegate returns NO, the add is cancelled

	
- (void)amd:anAMD didAdd:anObject usingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// Notifies the delegate that an addition has been completed. Disregards
	// the return value.

- amd:anAMD willModify:anObject usingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// Warns the delegate of an impending 'modify'. If the delegate returns nil.
	// the modification is cancelled.
	
- (void)amd:anAMD didModify:anObject usingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// Notifies the delegate that a modification has been done. Disregards the 
	// return value.

- amd:anAMD willDelete:anObject usingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// Warns the delegate of an impending deletion. If the delegate returns nil,
	// the deletion is cancelled.
	
- (void)amd:anAMD didDelete:anObject usingBinder:aBinder inRelationshipList:aList ofModel:(id)aModel;
	// Notifies the delegate that a deletion has just occurred. Disregards the 
	// return value.


    /****** TVC Delegate Forwards *******/
- (void)amd:(MCAMD *)amd tvc:(MCTableviewController *)aTVC initingDataCell:(id)aCell ofTableColumn:(id)aTBC;
- (id)amd:(MCAMD *)anAMD tvc:(MCTableviewController *)aTVC objectValueForAttribute:(id)mcAttribute ofObject:(id)anObject tableColumn:(NSTableColumn *)tableColumn;

@end

