/* $Id$ */
/* 
 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 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_LIST_HPP__
#define __PJPP_LIST_HPP__

#include <pj/list.h>
#include <pj++/pool.hpp>


//
// Linked-list.
//
// Note:
//  List_Node must have public member next and prev. Normally
//  it will be declared like:
//
//  struct my_node
//  {
//      PJ_DECL_LIST_MEMBER(struct my_node);
//      ..
//  };
//
//
template <class List_Node>
class Pj_List : public Pj_Object
{
public:
    //
    // List const_iterator.
    //
    class const_iterator
    {
    public:
	const_iterator() 
            : node_(NULL) 
        {}
	const_iterator(const List_Node *nd) 
            : node_((List_Node*)nd) 
        {}
	const List_Node * operator *() 
        { 
            return node_; 
        }
	const List_Node * operator -> () 
        { 
            return node_; 
        }
	const_iterator operator++() 
        { 
            return const_iterator((const List_Node *)node_->next); 
        }
	bool operator==(const const_iterator &rhs) 
        { 
            return node_ == rhs.node_; 
        }
	bool operator!=(const const_iterator &rhs) 
        { 
            return node_ != rhs.node_; 
        }

    protected:
	List_Node *node_;
    };

    //
    // List iterator.
    //
    class iterator : public const_iterator
    {
    public:
	iterator() 
        {}
	iterator(List_Node *nd) 
            : const_iterator(nd) 
        {}
	List_Node * operator *() 
        { 
            return node_; 
        }
	List_Node * operator -> () 
        { 
            return node_; 
        }
	iterator operator++() 
        { 
            return iterator((List_Node*)node_->next); 
        }
	bool operator==(const iterator &rhs) 
        { 
            return node_ == rhs.node_; 
        }
	bool operator!=(const iterator &rhs) 
        { 
            return node_ != rhs.node_; 
        }
    };

    //
    // Default constructor.
    //
    Pj_List() 
    { 
        pj_list_init(&root_); 
        if (0) compiletest(); 
    }

    //
    // You can cast Pj_List to pj_list
    //
    operator pj_list&()
    {
	return (pj_list&)root_;
    }
    operator const pj_list&()
    {
	return (const pj_list&)root_;
    }

    //
    // You can cast Pj_List to pj_list* too
    //
    operator pj_list*()
    {
	return (pj_list*)&root_;
    }
    operator const pj_list*()
    {
	return (const pj_list*)&root_;
    }

    //
    // Check if list is empty.
    // 
    bool empty() const
    {
	return pj_list_empty(&root_);
    }

    //
    // Get first element.
    //
    iterator begin()
    {
	return iterator(root_.next);
    }

    //
    // Get first element.
    //
    const_iterator begin() const
    {
	return const_iterator(root_.next);
    }

    //
    // Get end-of-element
    //
    const_iterator end() const
    {
	return const_iterator((List_Node*)&root_);
    }

    //
    // Get end-of-element
    //
    iterator end()
    {
	return iterator((List_Node*)&root_);
    }

    //
    // Insert node.
    //
    void insert_before (iterator &pos, List_Node *node)
    {
	pj_list_insert_before( *pos, node );
    }

    //
    // Insert node.
    //
    void insert_after(iterator &pos, List_Node *node)
    {
	pj_list_insert_after(*pos, node);
    }

    //
    // Merge list.
    //
    void merge_first(List_Node *list2)
    {
	pj_list_merge_first(&root_, list2);
    }

    //
    // Merge list.
    //
    void merge_last(Pj_List *list)
    {
	pj_list_merge_last(&root_, &list->root_);
    }

    //
    // Insert list.
    //
    void insert_nodes_before(iterator &pos, Pj_List *list2)
    {
	pj_list_insert_nodes_before(*pos, &list2->root_);
    }

    //
    // Insert list.
    //
    void insert_nodes_after(iterator &pos, Pj_List *list2)
    {
	pj_list_insert_nodes_after(*pos, &list2->root_);
    }

    //
    // Erase an element.
    //
    void erase(iterator &it)
    {
	pj_list_erase(*it);
    }

    //
    // Get first element.
    //
    List_Node *front()
    {
	return root_.next;
    }

    //
    // Get first element.
    //
    const List_Node *front() const
    {
	return root_.next;
    }

    //
    // Remove first element.
    //
    void pop_front()
    {
	pj_list_erase(root_.next);
    }

    //
    // Get last element.
    //
    List_Node *back()
    {
	return root_.prev;
    }

    //
    // Get last element.
    //
    const List_Node *back() const
    {
	return root_.prev;
    }

    //
    // Remove last element.
    //
    void pop_back()
    {
	pj_list_erase(root_.prev);
    }

    //
    // Find a node.
    //
    iterator find(List_Node *node)
    {
	List_Node *n = pj_list_find_node(&root_, node);
	return n ? iterator(n) : end();
    }

    //
    // Find a node.
    //
    const_iterator find(List_Node *node) const
    {
	List_Node *n = pj_list_find_node(&root_, node);
	return n ? const_iterator(n) : end();
    }

    //
    // Insert a node in the back.
    //
    void push_back(List_Node *node)
    {
	pj_list_insert_after(root_.prev, node);
    }

    //
    // Insert a node in the front.
    //
    void push_front(List_Node *node)
    {
	pj_list_insert_before(root_.next, node);
    }

    //
    // Remove all elements.
    //
    void clear()
    {
	root_.next = &root_;
	root_.prev = &root_;
    }

private:
    struct RootNode
    {
	PJ_DECL_LIST_MEMBER(List_Node);
    } root_;

    void compiletest()
    {
	// If you see error in this line, 
	// it's because List_Node is not derived from Pj_List_Node.
	List_Node *n = (List_Node*)0;
	n = (List_Node *)n->next; n = (List_Node *)n->prev;
    }
};


#endif	/* __PJPP_LIST_HPP__ */

