/* $Id$ */
/* 
 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#ifndef __PJPP_TREE_HPP__
#define __PJPP_TREE_HPP__

#include <pj/rbtree.h>

//
// Tree.
//
class PJ_Tree
{
public:
    typedef pj_rbtree_comp Comp;
    class iterator;
    class reverse_iterator;

    class Node : private pj_rbtree_node
    {
	friend class PJ_Tree;
	friend class iterator;
	friend class reverse_iterator;

    public:
	Node() {}
	explicit Node(void *data) { user_data = data; }
	void  set_user_data(void *data) { user_data = data; }
	void *get_user_data() const { return user_data; }
    };

    class iterator
    {
    public:
	iterator() {}
	iterator(const iterator &rhs) : tr_(rhs.tr_), nd_(rhs.nd_) {}
	iterator(pj_rbtree *tr, pj_rbtree_node *nd) : tr_(tr), nd_(nd) {}
	Node *operator*() { return (Node*)nd_; }
	bool operator==(const iterator &rhs) const { return tr_==rhs.tr_ && nd_==rhs.nd_; }
	iterator &operator=(const iterator &rhs) { tr_=rhs.tr_; nd_=rhs.nd_; return *this; }
	void operator++() { nd_=pj_rbtree_next(tr_, nd_); }
	void operator--() { nd_=pj_rbtree_prev(tr_, nd_); }
    protected:
	pj_rbtree *tr_;
	pj_rbtree_node *nd_;
    };

    class reverse_iterator : public iterator
    {
    public:
	reverse_iterator() {}
	reverse_iterator(const reverse_iterator &it) : iterator(it) {}
	reverse_iterator(pj_rbtree *t, pj_rbtree_node *n) : iterator(t, n) {}
	reverse_iterator &operator=(const reverse_iterator &rhs) { iterator::operator=(rhs); return *this; }
	Node *operator*() { return (Node*)nd_; }
	bool operator==(const reverse_iterator &rhs) const { return iterator::operator==(rhs); }
	void operator++() { nd_=pj_rbtree_prev(tr_, nd_); }
	void operator--() { nd_=pj_rbtree_next(tr_, nd_); }
    };

    explicit PJ_Tree(Comp *comp) { pj_rbtree_init(&t_, comp); }

    iterator begin()
    {
	return iterator(&t_, pj_rbtree_first(&t_));
    }

    iterator end()
    {
	return iterator(&t_, NULL);
    }

    reverse_iterator rbegin()
    {
	return reverse_iterator(&t_, pj_rbtree_last(&t_));
    }

    reverse_iterator rend()
    {
	return reverse_iterator(&t_, NULL);
    }

    bool insert(Node *node)
    {
	return pj_rbtree_insert(&t_, node)==0 ? true : false;
    }

    Node *find(const void *key)
    {
	return (Node*)pj_rbtree_find(&t_, key);
    }

    Node *erase(Node *node)
    {
	return (Node*)pj_rbtree_erase(&t_, node);
    }

    unsigned max_height(Node *node=NULL)
    {
	return pj_rbtree_max_height(&t_, node);
    }

    unsigned min_height(Node *node=NULL)
    {
	return pj_rbtree_min_height(&t_, node);
    }

private:
    pj_rbtree t_;
};

#endif	/* __PJPP_TREE_HPP__ */

