// -*- c++ -*-

#ifndef LEMON_ERASABLE_GRAPH_EXTENDER_H
#define LEMON_ERASABLE_GRAPH_EXTENDER_H

#include <lemon/invalid.h>


namespace lemon {

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

    typedef ErasableGraphExtender Graph;
    typedef _Base Parent;

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

    void erase(const Node& node) {
      Edge edge;
      Parent::firstOut(edge, node);
      while (edge != INVALID ) {
	erase(edge);
	Parent::firstOut(edge, node);
      } 

      Parent::firstIn(edge, node);
      while (edge != INVALID ) {
	erase(edge);
	Parent::firstIn(edge, node);
      }

      Parent::getNotifier(Node()).erase(node);
      Parent::erase(node);
    }
    
    void erase(const Edge& edge) {
      Parent::getNotifier(Edge()).erase(edge);
      Parent::erase(edge);
    }

  };

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

    typedef ErasableUndirGraphExtender Graph;
    typedef _Base Parent;

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

    void erase(const Node& node) {
      Edge edge;
      Parent::firstOut(edge, node);
      while (edge != INVALID ) {
	erase(edge);
	Parent::firstOut(edge, node);
      } 

      Parent::getNotifier(Node()).erase(node);
      Parent::erase(node);
    }
    
    void erase(const UndirEdge& uedge) {
      Parent::getNotifier(Edge()).erase(Edge(uedge,true));
      Parent::getNotifier(Edge()).erase(Edge(uedge,false));
      Parent::getNotifier(UndirEdge()).erase(uedge);
      Parent::erase(uedge);
    }

  };

}

#endif
