/*
 * Copyright (c) 1999 Johnny C. Lam.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  The author makes no representations
 * about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 */

// -*- C++ -*-

#ifndef STL_GRAPH_H
#define STL_GRAPH_H

#ifndef GTL_GRAPH_H
#include <GTL/graph.h>
#endif

#ifndef STL_UTILITY_INCLUDED
#include <utility>
#endif

template <typename T, typename W>
class stl_graph {
public:
    typedef T		value_type;
    typedef W		weight_type;
    typedef stl_graph	graph_type;
    typedef class node	node;
    typedef class edge	edge;

    typedef graph::node_iterator	const_node_iterator;
    typedef graph::node_iterator	node_iterator;

    typedef graph::edge_iterator	const_edge_iterator;
    typedef graph::edge_iterator	edge_iterator;

public:
    node_iterator	n_begin() { return _topology.nodes_begin(); }
    const_node_iterator	n_begin() const { return _topology.nodes_begin(); }
    node_iterator	n_end() { return _topology.nodes_end(); }
    const_node_iterator	n_end() const { return _topology.nodes_end(); }

    edge_iterator	e_begin() { return _topology.edges_begin(); }
    const_edge_iterator	e_begin() const { return _topology.edges_begin(); }
    edge_iterator	e_end() { return _topology.edges_end(); }
    const_edge_iterator	e_end() const { return _topology.edges_end(); }

public:
    value_type		value(node const &n) const { return _node_data[n]; }
    weight_type		weight(edge const &e) const { return _edge_data[e]; }

    int			n_size() const { return _topology.number_of_nodes(); }
    int			e_size() const { return _topology.number_of_edges(); }
    int			size() const { return n_size(); }

    node		find_node(value_type const &) const;

    graph const &	topology() const { return _topology; }
    graph &		topology() { return _topology; }

public:
    node	add_node(value_type const &);
    edge	add_edge(node const &, node const &, weight_type const &);

    template <class InputIterator>
    void	add_node_range(graph_type const &, InputIterator, InputIterator,
			       node_map<node>*);
    template <class InputIterator>
    void	add_edge_range(graph_type const &, InputIterator, InputIterator,
			       node_map<node>*);

    template <class InputIterator>
    void	add_node_range(graph_type const &, InputIterator, InputIterator);
    template <class InputIterator>
    void	add_edge_range(graph_type const &, InputIterator, InputIterator);

    void	erase(node const &);
    void	erase(edge const &);

    void	e_clear();
    void	n_clear();
    void	clear();

private:
    graph			_topology;
    node_map<value_type>	_node_data;
    edge_map<weight_type>	_edge_data;
};

#include <stl_graph_inline.h>
#include <stl_graph.cc>

#endif // STL_GRAPH_H
