-- File: ScriptTree.mesa - last edit by
-- Karlton:	20-Aug-82 16:25:24

DIRECTORY
  ScriptNode USING [Object];

ScriptTree: DEFINITIONS =
  BEGIN

  Handle: TYPE = LONG POINTER TO Object;
  Object: TYPE = RECORD [
    leftSibling, rightSibling, parent, child: Handle ← NIL,
    node: ScriptNode.Object ← [placeHolder[]] ];

  TreeHandle: TYPE = LONG POINTER TO TreeObject;
  TreeObject: TYPE;

  Error: ERROR [code: ErrorCode];
  ErrorCode: TYPE = {
    siblingNotChildOfParent, alreadyHasRoot, noRoot, implementationBug,
    outstandingEnumerator};
  
  Create: PROCEDURE [z: UNCOUNTED ZONE] RETURNS [TreeHandle];
  Destroy: PROCEDURE [TreeHandle];

  AddNode: PROCEDURE [tree: TreeHandle, parent, leftSibling: Handle]
    RETURNS [node: Handle];  -- if parent is NIL then leftSibling must be NIL and the root node is being defined.
  MoveNode: PROCEDURE [tree: TreeHandle, node, newParent, newLeftSibling: Handle];
  RemoveNode: PROCEDURE [tree: TreeHandle, node: Handle]; -- frees node and all its children
  RootNode: PROCEDURE [tree: TreeHandle] RETURNS[node: Handle];

  EnumerateOrder: TYPE = {pre, end};
  Enumerator: TYPE = LONG POINTER TO EnumerateState;
  EnumerateState: TYPE;

  CreateEnumerator: PROCEDURE [
    tree: TreeHandle, order: EnumerateOrder, origin: Handle ← NIL]
    RETURNS[state: Enumerator];  -- IF origin is NIL then the root of the tree is taken to be the origin of the enumeration
  DestroyEnumerator: PROCEDURE [state: Enumerator];
  Enumerate: PROCEDURE [state: Enumerator] RETURNS [node: Handle];  -- returns NIL if the enumeration is done
  SetEnumerator: PROCEDURE [
    state: Enumerator, order: EnumerateOrder, origin: Handle ← NIL];  -- this is equivalent to doing a DestroyEnumerator followed by a CreateEnumerator except that if handles have been given out to the original Enumerator, the storage will not have been deallocated. It is the client's responsibility to ensure that the same enumerator is not being used by two different processes at the same time.

  Direction: TYPE = {left, right, up, down};
  Walk: PROCEDURE [node: Handle, direction: Direction] RETURNS [newNode: Handle];

  END. -- of ScriptTree