/* 
   EOController.h

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
   Date: November 1996

   This file is part of the GNUstep Database Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; see the file COPYING.LIB.
   If not, write to the Free Software Foundation,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifndef __EOController_H__
#define __EOController_H__

#include <eoaccess/eoaccess.h>

@class EOAssociation;

/*
 * EOController
 */

@interface EOController : NSObject
{
    id <EODataSources> dataSource;					
	// its data source or nil (nil -> performs ok its operations)
    NSMutableArray*	associations;
	// association list
    NSMutableArray*	objects;
	// its objects (from its data source copied in this array)
	// even if objects change the array remains the same 
	// this is returned by objects
    NSMutableArray*	selection;
	// contains NSNumbers of indexes of selected objects sorted ascending
	// this is the same array in controller's lifetime
	// this is retuned by getSelectionIndexes
    id delegate;
	// its delegate; null is a "nice" delegate that approved everything
    id nextController;
	// its next controller notified on some operations
    BOOL autoSaveToObjects;
	// if controller saves to objects automatically
    BOOL autoSaveToDataSource;
	// if controller saves to data source automatically
    BOOL autoSelectFirst;
	// if controller selects first object after each fetch it performs
    BOOL fetchInProgress;
	// true if a fetch is in progress
    int	associationNotificationLock;
	// 0  notify; >0 do not
    NSMutableArray* sortOrdering;
	// keeps the sort ordering; it is the same in the controllers lifetime
	// this is returned by sortOrdering
    NSMutableArray*	editStack;
	// array of edit operations (the last is the most recent)
    NSMutableArray*	operationsStack;
	// array of ins/del/upd operations (the last is the most recent)
    NSMutableArray*	operationsPosponedStack;
	// array of ins/del/upd operations (the last is the most recent)
	// in saveToDataSource
    NSMutableArray*	undoStack;
	// array of edit/ins/del (the last is the motst recent) for undo
	// it copies editStack and operationsStack in part and is emptied
	// in releaseUndos
    NSMutableArray*	undoMarkers;
	// array of indexes in undoStack that specifies the undo marks
    id undoGroup;
	// controller's undo group (see undo in EOController.m:)
    int	undoMaxMarks;
	// maximum undo marks; if more marks are requested undo info is lost
    int	undoUsedMarks;
	// used marks (undefined if undoMaxMarks=0 -> no undo marks limit)
    BOOL undoEnabled;
	// if undo is enabled
    BOOL undoMarkEveryOperation;
	// if every operation that modifies objects is marked separately
    BOOL undoFirstOp;
	// YES if next operation (edit/ins/del) is to be marked
}

/* Initializing an EOController	*/
- initWithDataSource:(id <EODataSources>)dataSource;

/* Managing associations */	
- (void)addAssociation:(EOAssociation*)anAssociation;
- (void)removeAssociation:(EOAssociation*)anAssociation;
- (NSArray*)associations;
- (NSArray*)keys;
- (void)disableAssociationNotification;
- (void)reenableAssociationNotification;

/* Getting the objects */
- (NSArray*)allObjects;

/* Fetching objects */
- (BOOL)fetch;
- (BOOL)fetchInProgress;

/* Managing the selection */
- (BOOL)setSelectionIndexes:(NSArray*)selection;
- (NSArray*)selectionIndexes;
- (NSArray*)selectedObjects;
- (BOOL)clearSelection;
- (BOOL)selectNext;
- (BOOL)selectPrevious;
- (void)setSelectsFirstObjectAfterFetch:(BOOL)yn;
- (BOOL)selectsFirstObjectAfterFetch;

/* Editing objects */
- (void)associationDidEdit:(EOAssociation*)association;
- (void)setValues:(NSDictionary*)newValues forObject:anObject;
- (void)endEditing;

/* Sorting objects */
- (void)resort;
- (void)setSortOrdering:(NSArray*)keySortOrderArray;
- (NSArray*)sortOrdering;

/* Performing operations on objects */
- (BOOL)deleteObjectAtIndex:(unsigned)anIndex;
- (BOOL)deleteSelection;
- insertObjectAtIndex:(unsigned)anIndex;
- insertObject:newObject atIndex:(unsigned)anIndex;

/* Discarding changes */
- (void)discardEdits;
- (void)discardOperations;
- (BOOL)isDiscardAllowed;

/* Saving edits to objects */
- (BOOL)saveToObjects;
- (BOOL)hasChangesForObjects;
- (BOOL)setSavesToObjectsAutomatically:(BOOL)yn;
- (BOOL)savesToObjectsAutomatically;

/* Saving to the data source */
- (BOOL)saveToDataSource;
- (BOOL)hasChangesForDataSource;
- (BOOL)setSavesToDataSourceAutomatically:(BOOL)yn;
- (BOOL)savesToDataSourceAutomatically;

/* Controlling undo */
- (BOOL)hasUndos;
- (BOOL)isUndoEnabled;
- (void)setUndoEnabled:(BOOL)yn;
- (void)markUndo;
- (void)undo;
- (void)releaseUndos;
- (void)setMarksEveryOperation:(BOOL)yn;
- (BOOL)marksEveryOperation;
- (void)setMaximumUndoMarks:(unsigned int)max;
- (unsigned int)maximumUndoMarks;

/* Redisplaying the user interface */
- (void)redisplay;

/* Chaining controllers */
- (void)setNextController:(EOController*)aController;
- (EOController*)nextController;

/* Setting the data source */
- (void)setDataSource: (id <EODataSources>)dataSource;
- (id <EODataSources>)dataSource;

/* Setting the delegate */
- (void)setDelegate:aDelegate;
- delegate;

/* Action methods */
- delete:sender;
- discardEdits:sender;
- discardOperations:sender;
- fetch:sender;
- insert:sender;
- markUndo:sender;
- saveToDataSource:sender;
- saveToObjects:sender;
- selectNext:sender;
- selectPrevious:sender;
- undo:sender;

@end /* EOController */

/*
 * EOControllerUndoExtensions
 */

@interface EOController(EOControllerUndoExtensions)
- (id)undoGroup;
- (void)setUndoGroup:grp;
+ (void)setUndoGroupForController:(EOController*)ctrl;
@end

/*
 * EOControllerDelegate informal protocol
 */

@interface NSObject (EOControllerDelegate)

/* General */

- (void)controllerDidChangeSelection:(EOController*)controller;
- (void)controller:(EOController*)controller 
  sortObjects:(NSMutableArray*)objects;
- (BOOL)controllerWillFetch:(EOController*)controller;
- (void)controller:(EOController*)controller 
  didFetchObjects:(NSArray*)objects;
- (BOOL)controller:(EOController*)controller 
  willInsertObject:object 
  atIndex:(unsigned)newIndex;
- (void)controller:(EOController*)controller 
  didInsertObject:object;
- (BOOL)controller:(EOController*)controller 
  willDeleteObject:object;
- (void)controller:(EOController*)controller 
  didDeleteObject:object;
- (NSDictionary*)controller:(EOController*)controller 
  willSaveEdits:(NSDictionary*)edits 
  toObject:object;
- (void)controller:(EOController*)controller 
  didSaveToObject:object;
- (BOOL)controllerWillDiscardEdits:(EOController*)controller;
- (BOOL)controllerWillDiscardOperations:(EOController*)controller;
- (BOOL)controllerWillSaveToDataSource:(EOController*)controller;
- (void)controllerDidSaveToDataSource:(EOController*)controller;
- (void)controllerDidFetchObjects:(EOController*)controller;

/* Data Source related */

typedef enum {
    EONoDataSourceFailure = 0,
    EOContinueDataSourceFailureResponse,
    EORollbackDataSourceFailureResponse
} EODataSourceFailureResponse;

typedef enum {
    EODiscardDataSourceOperation = 0,
    EOPerformDataSourceOperation,
    EOContinueDataSourceOperation,
    EORollbackDataSourceOperation, 	
} EODataSourceOperationDelegateResponse;

- (EODataSourceFailureResponse)controller:(EOController*)controller
  object:object
  failedToPrepareForDataSource:dataSource;

- (EODataSourceOperationDelegateResponse)controller:(EOController*)controller
  willInsertObject:object
  inDataSource:dataSource;

- (EODataSourceFailureResponse)controller:(EOController*)controller
  failedToInsertObject:object
  inDataSource:dataSource;

- (void)controller:(EOController*)controller
  didInsertObject:object
  inDataSource:dataSource;

- (EODataSourceOperationDelegateResponse)controller:(EOController*)controller
  willDeleteObject:object
  inDataSource:dataSource;

- (EODataSourceFailureResponse)controller:(EOController*)controller
  failedToDeleteObject:object
  inDataSource:dataSource;

- (void)controller:(EOController*)controller
  didDeleteObject:object
  inDataSource:dataSource;

- (EODataSourceOperationDelegateResponse)controller:(EOController*)controller
  willUpdateObject:object
  inDataSource:dataSource;

- (EODataSourceFailureResponse)
  controller:(EOController*)controller
  failedToUpdateObject:object
  inDataSource:dataSource;

- (void)controller:(EOController*)controller
  didUpdateObject:object
  inDataSource:dataSource;

- (void) controller:(EOController*)controller
  saveObjectsFailedForDataSource:dataSource;

- (void) controller:(EOController*)controller
  createObjectFailedForDataSource:dataSource;

- (void)controller:(EOController*)controller 
  willRollbackDataSource:(id <EODataSources>)dataSource;

- (void)controller:(EOController*)controller 
  didRollbackDataSource:(id <EODataSources>)dataSource;

- (void)controller:(EOController*)controller
  didChangeDataSource: (id <EODataSources>)dataSource;

/* Association related */

- (void)controller:(EOController*)controller 
  association:(EOAssociation*)association 
  didEditObject:anObject 
  key:(NSString*)key 
  value:aValue;

/* Undo related */

- (BOOL)controller:(EOController*)controller willUndoObject:anObject;
- (void)controller:(EOController*)controller didUndoObject:anObject;
- (BOOL)controllerWillUndo:(EOController*)controller;
- (void)controllerDidUndo:(EOController*)controller;

@end

/*
 * EOObjectValidation
 */

@protocol EOObjectValidation
- (BOOL)prepareForDataSource;
@end

/*
 * EOAssociationNotification
 * methods sent by EOController to EOAssociations
 */

@protocol EOAssociationNotification
- (void)contentsDidChange;
- (void)selectionDidChange;
- (void)endEditing;
- (void)discardEdits;
@end

#endif		/* __EOController_H__ */

