MODULE Sequencers;
(**
	project	= "BlackBox"
	organization	= "www.oberon.ch"
	contributors	= "Oberon microsystems"
	version	= "System/Rsrc/About"
	copyright	= "System/Rsrc/About"
	license	= "Docu/BB-License"
	changes	= "
	- YYYYMMDD, nn, ...
	"
	issues	= "
	- ...
	"

**)

	IMPORT Stores;

	CONST
		clean* = 0; 
		notUndoable* = 1; 
		invisible* = 2;

	TYPE
		Message* = ABSTRACT RECORD END;
		
		Notifier* = POINTER TO ABSTRACT RECORD
			next: Notifier
		END;

		Sequencer* = POINTER TO ABSTRACT RECORD
			notifiers: Notifier
		END;

		CloseMsg* = RECORD (Message)
			sticky*: BOOLEAN	(** OUT, preset to FALSE **)
		END;

		RemoveMsg* = RECORD (Message) END;

		Directory* = POINTER TO ABSTRACT RECORD END;

	VAR dir*: Directory;

	(** Directory **)
	PROCEDURE (dir: Directory) New* (): Sequencer, NEW, ABSTRACT;

	PROCEDURE SetDir* (d: Directory);
	BEGIN
		ASSERT(d # NIL, 20); dir := d
	END SetDir;


	(** Notifier **)

	PROCEDURE (f: Notifier) Notify* (VAR msg: Message), NEW, EMPTY;


	(** Sequencer **)

	PROCEDURE (s: Sequencer) Dirty* (): BOOLEAN, NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) SetDirty* (dirty: BOOLEAN), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) BeginScript* (IN name: Stores.OpName;
																VAR script: Stores.Operation), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) Do* (st: Stores.Store; IN name: Stores.OpName;
														op: Stores.Operation), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) LastOp* (st: Stores.Store): Stores.Operation, NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) Bunch* (st: Stores.Store), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) EndScript* (script: Stores.Operation), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) StopBunching* (), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) BeginModification* (type: INTEGER; st: Stores.Store), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) EndModification* (type: INTEGER; st: Stores.Store), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) CanUndo* (): BOOLEAN, NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) CanRedo* (): BOOLEAN, NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) GetUndoName* (VAR name: Stores.OpName), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) GetRedoName* (VAR name: Stores.OpName), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) Undo* (), NEW, ABSTRACT;
	PROCEDURE (s: Sequencer) Redo* (), NEW, ABSTRACT;

	PROCEDURE (s: Sequencer) Handle* (VAR msg: ANYREC), NEW, EMPTY;

	PROCEDURE (s: Sequencer) Notify* (VAR msg: Message), NEW;
		VAR n: Notifier;
	BEGIN
		n := s.notifiers;
		WHILE n # NIL DO
			n.Notify(msg);
			n := n.next
		END
	END Notify;

	PROCEDURE (s: Sequencer) InstallNotifier* (n: Notifier), NEW;
	BEGIN
		n.next := s.notifiers; s.notifiers := n
	END InstallNotifier;

END Sequencers.
