|##########|
|#MAGIC   #|CLABLLAP
|#PROJECT #|"ImportHelp"
|#PATHS   #|"StdProject"
|#FLAGS   #|xx---x-xx---x-x-----------------
|#USERSW  #|--------------------------------
|#USERMASK#|--------------------------------
|#SWITCHES#|xx---xxxxx------
|##########|
DEFINITION MODULE Trees;

FROM Lists      IMPORT FileTypeMismatch;
FROM FileSystem IMPORT File;

IMPORT Lists;

EXCEPTION
  NoFather   : "Leaf has no father";

  DEFINITION MODULE StdTrees(Tree : POINTER TO Leaf);

    DEFINITION MODULE LeafList = Lists.BiLists(Tree);

    TYPE
      Leaf       = RECORD OF LeafList.BiNode
		     father : Tree;
		     sons   : LeafList.BiList
		   END;

      Check      = PROCEDURE(t : Tree):BOOLEAN;
      Destructor = PROCEDURE(t : Tree);
      ApplyProc  = PROCEDURE(t : Tree);
      SaveProc   = PROCEDURE(f : File;leaf : Tree);
      LoadProc   = PROCEDURE(f : File):Tree;

    PROCEDURE Init(t : Tree);


    PROCEDURE AddFirstSon(father,son : Tree);

    PROCEDURE AddLastSon(father,son : Tree);

    PROCEDURE AddNextBrother(tree,brother : Tree);

    PROCEDURE AddPrevBrother(tree,brother : Tree);


    PROCEDURE Remove(tree : Tree);

    PROCEDURE RemoveSons(father : Tree);

    PROCEDURE RemoveSons_IF(tree : Tree;if : Check);

    PROCEDURE Remove_IF(tree : Tree;if : Check);


    PROCEDURE Delete(VAR tree : Tree);

    PROCEDURE DeleteSons(father : Tree);

    PROCEDURE DeleteSons_IF(tree : Tree;if : Check);

    PROCEDURE Delete_IF(VAR tree : Tree;if : Check);


    PROCEDURE Destruct(VAR tree : Tree;des : Destructor);

    PROCEDURE DestructSons(father : Tree;des : Destructor);

    PROCEDURE DestructSons_IF(tree : Tree;
			      if   : Check;
			      des : Destructor);

    PROCEDURE Destruct_IF(VAR tree : Tree;
			      if   : Check;
			      des  : Destructor);


    PROCEDURE ApplyDepthFirst(tree : Tree;
			      work : ApplyProc);

    PROCEDURE ApplyBreadthFirst(tree : Tree;
				work : ApplyProc);

    PROCEDURE ApplyDepthFirstBig(tree     : Tree;
				 pre,
				 between,
				 post     : ApplyProc);


    PROCEDURE FindDepthFirst(tree   : Tree;
			     equal  : Check):Tree;

    PROCEDURE FindBreadthFirst(tree  : Tree;
			       equal : Check):Tree;


    PROCEDURE FindSon(father : Tree;
		       equal : Check):Tree;

    PROCEDURE FindNextSon(father : Tree;
			   equal : Check;
			   son   : Tree):Tree;


    PROCEDURE Save(tree : Tree;
		   f    : File;
		   part : SaveProc);

    PROCEDURE Load(VAR tree : Tree;
		       f    : File;
		       part : LoadProc);

  END StdTrees;


  DEFINITION MODULE CursorTree(type : ANYPTR);

    EXCEPTION
      NoCursor : "No cursor set";

    TYPE
      LeafPtr = POINTER TO Leaf;

    DEFINITION MODULE CTree = StdTrees(LeafPtr);

    TYPE
      Leaf    = RECORD OF CTree.Leaf
		  data : type;
		END;
      Tree    = RECORD
		  root,
		  mark,
		  cursor : LeafPtr;
		END;

      Check      = PROCEDURE(t : type):BOOLEAN;
      Destructor = PROCEDURE(t : type);
      ApplyProc  = PROCEDURE(t : type);
      SaveProc  = PROCEDURE(f : File;leaf : type);
      LoadProc   = PROCEDURE(f : File):type;


    PROCEDURE Init(VAR tree : Tree);


    PROCEDURE Get(VAR tree : Tree):type;

    PROCEDURE GetSubtree(VAR dest,arg : Tree);


    PROCEDURE AddFirstSon(VAR tree : Tree;son : type);

    PROCEDURE AddLastSon(VAR tree : Tree;son : type);

    PROCEDURE AddNextBrother(VAR tree : Tree;brother : type);

    PROCEDURE AddPrevBrother(VAR tree : Tree;brother : type);


    PROCEDURE AddFirstSonSubtree(VAR tree,son : Tree);

    PROCEDURE AddLastSonSubtree(VAR tree,son : Tree);

    PROCEDURE AddNextBrotherSubtree(VAR tree,brother : Tree);

    PROCEDURE AddPrevBrotherSubtree(VAR tree,brother : Tree);


    PROCEDURE Remove(VAR tree : Tree);

    PROCEDURE RemoveSons(VAR tree : Tree);

    PROCEDURE RemoveSons_IF(VAR tree : Tree;if : Check);

    PROCEDURE Remove_IF(VAR tree : Tree;if : Check);


    PROCEDURE Delete(VAR tree : Tree);

    PROCEDURE DeleteSons(VAR tree : Tree);

    PROCEDURE DeleteSons_IF(VAR tree : Tree;if : Check);

    PROCEDURE Delete_IF(VAR tree : Tree;if : Check);


    PROCEDURE Destruct(VAR tree : Tree;des : Destructor);

    PROCEDURE DestructSons(VAR tree : Tree;des : Destructor);

    PROCEDURE DestructSons_IF(VAR tree : Tree;
				  if   : Check;
				  des  : Destructor);

    PROCEDURE Destruct_IF(VAR tree : Tree;
			      if   : Check;
			      des  : Destructor);


    PROCEDURE ApplyDepthFirst(VAR tree : Tree;
				  work : ApplyProc);

    PROCEDURE ApplyBreadthFirst(VAR tree : Tree;
				    work : ApplyProc);

    PROCEDURE ApplyDepthFirstBig(VAR tree     : Tree;
				     pre,
				     between,
				     post     : ApplyProc);


    PROCEDURE Dup(VAR dest,arg : Tree);

    PROCEDURE DupSubtree(VAR dest,arg : Tree);


    PROCEDURE Mark(VAR tree : Tree);

    PROCEDURE GoMark(VAR tree : Tree);


    PROCEDURE FindDepthFirst(VAR tree  : Tree;
				 equal : Check);

    PROCEDURE FindBreadthFirst(VAR tree   : Tree;
				   equal  : Check);


    PROCEDURE FindSon(VAR tree  : Tree;
			  equal : Check);

    PROCEDURE FindNextSon(VAR tree  : Tree;
			      equal : Check);


    PROCEDURE Father(VAR tree : Tree);

    PROCEDURE FirstSon(VAR tree : Tree);

    PROCEDURE LastSon(VAR tree : Tree);

    PROCEDURE NextBrother(VAR tree : Tree);

    PROCEDURE PrevBrother(VAR tree : Tree);

    PROCEDURE Root(VAR tree : Tree);


    PROCEDURE HasCursor(VAR tree : Tree):BOOLEAN;


    PROCEDURE Save(VAR tree : Tree;
		       f    : File;
		       part : SaveProc);

    PROCEDURE Load(VAR tree : Tree;
		       f    : File;
		       part : LoadProc);

  END CursorTree;

END Trees.

