/*****
 NAME
	pset.h - protocol definitions for data set operation classes
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#if !defined(PSET_H_INCLUDED)
#define PSET_H_INCLUDED

#include <coconut/pobject.h>
#include <coconut/perror.h>

@protocol PSetBase <PObject>
 - (u_int) count ;
 - clear ;
@end

@protocol PDataSetBase <PSetBase>
 - (const void *) foreach: (foreach_func_t) func with: (void *) p1 
     with: (void *) p2 ;
@end

@protocol PIdSetBase <PSetBase, PDebug>
 - foreach: (SEL) msg with: p1 with: p2 ;
 - foreach: (id) obj message: (SEL) msg with: p1 ;
@end

@protocol PDataSet <PDataSetBase>
  - append: (const void *) data ;
@end

@protocol PIdSet <PIdSetBase>
  - append: (id) obj ;
@end

/* similar interface is used in PText in "pstring.h" */
@protocol PDataList <PDataSetBase>
 - append: (const void *) data ;
 - prepend: (const void *) data ;
   /* add new next object and move to it */
 - add: (const void *) data ;
   /* add new previous object. current node is not changed. */
 - insert: (const void *) data ;

 - (const void *) currentItem ;
 - (const void *) item: (u_int) idx ;

   /* change current node to the next, and return the pointer of the 
      new current node */
 - (const void *) moveNext ;
 - (const void *) movePrev ;
 - (const void *) moveToHead ;
 - (const void *) moveToTail ;

   /* the pointer move to the previous element if it exist */
 - (id <PError>) remove ;

@end

@protocol PIdList <PIdSetBase>
 - append: (id) obj ;
 - prepend: (id) obj ;

   /* add new next object and move to it */
 - add: (id) obj ;
   /* add new previous object. current node is not changed. */
 - insert: (id) obj ;

 - (id) currentItem ;
 - (id) item: (u_int) idx ;

   /* change current node to the next, and return the pointer of the 
      new current node */
 - (id) moveNext ;
 - (id) movePrev ;
 - (id) moveToHead ;
 - (id) moveToTail ;

   /* the pointer move to the previous element if it exist */
 - (id <PError>) remove ;
@end

@protocol PNode <PDebug>
 - (id) parent ;
 - (id) child ;
 - (id) next ;
 - (id) prev ;

   /* add the node and it's follower after the node */
 - addSibling: (id <PNode>) node ;
   /* insert the node and it's follower before the node */
 - insertSibling: (id <PNode>) node ;

   /* add the node and it's follower after the last sibling */
 - appendSibling: (id <PNode>) node ;
   /* prepend the node and it's follower after the first sibling */
 - prependSibling: (id <PNode>) node ;

 - appendChild: (id <PNode>) node ;
 - prependChild: (id <PNode>) node ;

 - foreach: (SEL) msg with: p1 with: p2 ;
 - foreach: (id) obj message: (SEL) msg with: p1 ;

   /* execute method "msg" for child and self and next widget.
      the method for the child is executed earlier than it self */
 - foreachFromChildren: (SEL) msg with: p1 with: p2 ;
 - foreachFromChildren: (id) obj message: (SEL) msg with: p1 ;

   /* unlink the node from the nodes which had been connected
        before unlink:		after unlink:
	        parent		       parent
	  prev - self - next	prev - child - next
	        child
    */
 - isolate ;

 - removeAllChildren ;

 /* these are private methods. In usually user does not have the reason
    to these methods. */
 - setParent: (id <PNode>) node ;
 - setChild: (id <PNode>) node ;
 - setNext: (id <PNode>) node ;
 - setPrev: (id <PNode>) node ;
@end

@protocol PNodeFactory
 + (id) lastSibling: (id <PNode>) node ;
 + (id) firstSibling: (id <PNode>) node ;
@end

@protocol PTree <PSetBase, PDebug>
 - (id)	rootNode ;
 - (id) currentNode ;

   /* add the node and it's follower after the node */
 - addSibling: (id <PNode>) node ;
   /* insert the node and it's follower before the node */
 - insertSibling: (id <PNode>) node ;

   /* add the node and it's follower after the last sibling.
      the current node moves to the new node */
 - appendSibling: (id <PNode>) node ;
   /* prepend the node and it's follower after the first sibling.
      the current node moves to the new node */
 - prependSibling: (id <PNode>) node ;

   /* the current node moves to the new last node */
 - appendChild: (id <PNode>) node ;
   /* the current node moves to the new first node */
 - prependChild: (id <PNode>) node ;

 - (id <PNode>) moveToParent ;
 - (id <PNode>) moveToChild ;
 - (id <PNode>) moveToPrev ;
 - (id <PNode>) moveToNext ;
 - (id <PNode>) moveToHead ;
 - (id <PNode>) moveToTail ;
 - (id <PNode>) moveToLastChild ;

   /* remove current node. the child node will be released.
      if the following node will be the new current node:
        [1] next node
	[2] previout node
	[3] parent node
    */
 - removeCurrentNode ;
@end

@protocol PDataArray <PDataSetBase>
 - append: (const void *) data ;
 - prepend: (const void *) data ;

 - (id <PError>) setItem: (const void *) data to: (u_int) idx ;
 - (const void *) item: (u_int) idx ;

   /* return the addresses of first/last item. If the item is not found,
      the null pointer is returned */
 - (const void *) first ;
 - (const void *) last ;

 - (const void *) search: (u_int *) idx compareFunc: (compare_func_t) cmp
     by: (const void *) obj ;

 - (id <PError>) removeItem: (u_int) idx ;
@end

@protocol PIdArray <PIdSetBase>
 - append: (id) obj ;
 - prepend: (id) obj ;

 - (id <PError>) setItem: (id) obj to: (u_int) idx ;
 - (id) item: (u_int) idx ;

   /* return the addresses of first/last item. If the item is not found,
      the null pointer is returned */
 - (id) first ;
 - (id) last ;

 - (id) search: (u_int *) idx by: (id) obj ;

 - (id <PError>) removeItem: (u_int) idx ;
@end

@protocol PDataHash <PDataSetBase>
 - add: (const void *) key data: (const void *) value ;
 - (const void *) search: (const void *) key ;
 - (const void *) foreachHash: (foreach_hash_func_t) func with: (void *) p1 
     with: (void *) p2 ;
@end

@protocol PIdHash <PIdSetBase>
 - add: (const void *) key object: (id) obj ;
 - (id) search: (const void *) key ;
 - foreachHash: (SEL) msg with: p1 ;
 - foreachHash: (id) obj message: (SEL) msg ;
@end

/* this protocol is used for the hash element object */
@protocol PIdHashElm <PObject>
  - (int) compare: (id) src ;
  - (u_int) hashkey ;
@end

@protocol PDataStack <PDataSetBase>
 - push: (const void *) p ;
 - (const void *) pop ;
 - (const void *) peek: (u_int) index ;
 - (const void *) peekTop ;
@end

@protocol PIdStack <PIdSetBase>
 - push: (id) p ;
 - (id) pop ;
 - (id) peek: (u_int) index ;
 - (id) peekTop ;
@end

#endif /* !defined(PSET_H_INCLUDED) */

