// -*- c++ -*-

#ifndef LEMON_EXTENDABLE_GRAPH_EXTENDER_H
#define LEMON_EXTENDABLE_GRAPH_EXTENDER_H

namespace lemon {

  template <typename _Base> 
  class ExtendableGraphExtender : public _Base {
  public:

    typedef ExtendableGraphExtender Graph;
    typedef _Base Parent;

    typedef typename Parent::Node Node;
    typedef typename Parent::Edge Edge;

    Node addNode() {
      Node node = Parent::addNode();
      Parent::getNotifier(Node()).add(node);
      return node;
    }
    
    Edge addEdge(const Node& from, const Node& to) {
      Edge edge = Parent::addEdge(from, to);
      Parent::getNotifier(Edge()).add(edge);
      return edge;
    }

  };

  template <typename _Base> 
  class ExtendableUndirGraphExtender : public _Base {
  public:

    typedef ExtendableUndirGraphExtender Graph;
    typedef _Base Parent;

    typedef typename Parent::Node Node;
    typedef typename Parent::Edge Edge;
    typedef typename Parent::UndirEdge UndirEdge;

    Node addNode() {
      Node node = Parent::addNode();
      Parent::getNotifier(Node()).add(node);
      return node;
    }

    UndirEdge addEdge(const Node& from, const Node& to) {
      UndirEdge uedge = Parent::addEdge(from, to);
      Parent::getNotifier(UndirEdge()).add(uedge);

      Edge edge_forward(uedge, true);
      Edge edge_backward(uedge, false);
      Parent::getNotifier(Edge()).add(edge_forward);
      Parent::getNotifier(Edge()).add(edge_backward);

      return uedge;
    }

  };

}

#endif
