// NameManager.H
// JR 9/25/95
#ifndef NAMEMANAGER_H
#define NAMEMANAGER_H

//#include <iostream.h>
#include <iostream>
using namespace std;
#include "Set.H"
//#include "Name.H"
#include "DE.H"
//#include "Homeo.H"

class Homeo;

class NameManager
{

   private:
	Set<Name> edgs;
	Set<Name> perip;
	Set<Name> puncs;

   public:
	NameManager() : edgs(),perip(),puncs() {}
	~NameManager() {}	
	DE newInteriorEdge()
	{	// Uses fact that Name is implemented as int.

		// New name will be the lowest natural number not
		// already in edgs or puncs.

		int i=1;
		while( edgs.has(Name(i)) || puncs.has(Name(i)) ) ++i;
		edgs.add(Name(i));
		return DE(Name(i),0);
	}
	DE newPeripheralEdge()
	{	// Uses fact that Name is implemented as int.

		// New name will be the lowest natural number not
		// already in edgs or puncs.

		int i=1;
		while( edgs.has(Name(i)) || puncs.has(Name(i)) ) ++i;
		edgs.add(Name(i));
		perip.add(Name(i));
		return DE(Name(i),0);
	}
	DE newPuncture()
	{	// Uses fact that Name is implemented as int.

		// New name will be the lowest natural number not
		// already in the set.

		int i=1;
		while( edgs.has(Name(i)) || puncs.has(Name(i)) ) ++i;
		puncs.add(Name(i));
		return DE(Name(i),0);
	}
	const Set<Name>& edges() const
	{	return edgs;	
	}
	const Set<Name>& periphery() const
	{	return perip;	
	}
	const Set<Name>& punctures() const
	{	return puncs;	
	}
	Boolean removeEdge(Name n)
	{
		perip.remove(n);
		return edgs.remove(n);
	}

   friend ostream& operator << (ostream& out, const NameManager& s);
//   friend Homeo::Homeo(istream&); Doesn't let this func access edgs or perip
   friend class Homeo; // This is too broad! How to let only above dunc get access?

};


      ostream& operator << (ostream& out, const NameManager& s)
      {   out << "edges: ";
	  out << "{ ";
	{
	  SetBrowser<Name> i(s.edgs);
	  for(i.init();i.ok();i.advance()) out << i.current() << " ";
          out << "}\n";
	  out << "periphery: ";
	  out << "{ ";
	}
	{
	  SetBrowser<Name> i(s.perip);
	  for(i.init();i.ok();i.advance()) out << i.current() << " ";
          out << "}\n";
          out << "punctures: ";
	  out << "{ ";
	}
	  SetBrowser<Name> j(s.puncs);
	  for(j.init();j.ok();j.advance()) out << j.current() << " ";
          out << "}\n";
	  return out;
      }
	
			
#endif
