#pragma once

#include "chain.h"

// Classes Defined in this file

class Set;
class SetIterator;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Set ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class Set : public Socket
{

  friend class SetIterator;

public:
	Logical
		TestInstance() const;


	 // Constructor
	Set(Node *node);

	~Set();

protected:
	Set& operator=(const Set &rhs);

	//STUBBED: UNKNOWN RB 1/15/07
	//void
	//	AddImplementation(Plug *plug);

	// Useful Set Operations
	Logical operator==(const Set &rhs);
	Set operator-(const Set &rhs) const;
	Set Union(const Set &rhs) const;
	Set Intersection(const Set &rhs) const;

	// Set membership
	Logical
		Exists(const Plug &element) const;

private:
	Chain *contents;
};


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SetOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

template <class T> class SetOf:
	public Set
{
public:
	SetOf(Node *node);
	~SetOf();

protected:
	SetOf(Set set):
		Set(set)
	{
	}

public:

	// Public interface

	void
		Add(T *plug)
			{AddImplementation(plug);}

	// Useful Set Operations
	SetOf<T>&
		operator=(const SetOf<T> &rhs)
		{
			if (this==&rhs) return *this;
			Set::operator=(rhs);
			return *this;
		}

	Logical
		operator==(const SetOf<T> &rhs)
			{return Set::operator==(rhs);}


	SetOf<T>
		operator-(const SetOf<T> rhs) const
			{return (SetOf<T>) Set::operator-(rhs);}

	SetOf<T>
		Union(const SetOf<T> &rhs) const
			{return  (SetOf<T>) Set::Union(rhs);}

	SetOf<T>
		Intersection(const SetOf<T> &rhs) const
			{return  (SetOf<T>) Set::Intersection(rhs);}


};


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~ SetOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	template <class T>
		SetOf<T>::SetOf(Node *node):
			Set(node)
	{
	}

	template <class T>
		SetOf<T>::~SetOf()
	{
	}



	//~~~~~~~~~~~~~~~~~~~~~~~~~~~ SetIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	class SetIterator:
		public ChainIterator
	{
	public:
		friend class Set;
		//
		//--------------------------------------------------------------------
		//--------------------------------------------------------------------
		// Public interface
		//--------------------------------------------------------------------
		//--------------------------------------------------------------------
		//

		//
		//--------------------------------------------------------------------
		// Constructors, Destructor and testing
		//--------------------------------------------------------------------
		//
		SetIterator(Set *set);
		SetIterator(const SetIterator &iterator);
		~SetIterator();

	protected:
		SetIterator(Chain *chain);   // Used fot Set implementation to iterate on own contents
	};


//~~~~~~~~~~~~~~~~~~~~~~~~~~ SetIteratorOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	template <class T> class SetIteratorOf:
		public SetIterator
	{
	public:
		//
		//--------------------------------------------------------------------
		//--------------------------------------------------------------------
		// Public interface
		//--------------------------------------------------------------------
		//--------------------------------------------------------------------
		//

		//
		//--------------------------------------------------------------------
		// Constructors and Destructor
		//--------------------------------------------------------------------
		//
		SetIteratorOf(SetOf<T> *chain);
		SetIteratorOf(SetOf<T> &chain);
		SetIteratorOf(const SetIteratorOf<T> &iterator);
		~SetIteratorOf();

		//
		//--------------------------------------------------------------------
		// Iterator methods (see Iterator for full listing)
		//--------------------------------------------------------------------
		//
		T*
			ReadAndNext()
				{return (T*)ReadAndNextImplementation();}
		T*
			ReadAndPrevious()
				{return (T*)ReadAndPreviousImplementation();}
		T*
			GetCurrent()
				{return (T*)GetCurrentImplementation();}
		T*
			GetNth(CollectionSize index)
				{return (T*)GetNthImplementation(index);}
		void
			Insert(T *plug)
				{InsertImplementation(plug);}

		SetIteratorOf<T>&
			Begin()
				{return (SetIteratorOf<T>&)BeginImplementation();}
		SetIteratorOf<T>&
			End()
				{return (SetIteratorOf<T>&)EndImplementation();}
		SetIteratorOf<T>&
			Forward()
				{return (SetIteratorOf<T>&)ForwardImplementation();}
		SetIteratorOf<T>&
			Backward()
				{return (SetIteratorOf<T>&)BackwardImplementation();}

		//
		//---------------------------------------------------
		// Operators useful when it is know that the iterator
		// is a SetOf<> Iterator
		//---------------------------------------------------
		//
#if 0
		Logical
			operator!()
				{return currentLink == NULL;}
		operator T*()
				{return GetCurrent();}
		T*
			operator->()
				{return GetCurrent();}
		T&
			operator*()
				{return *GetCurrent();}

		SetIteratorOf<T>&
			operator++()
				{Next(); return *this;}
		SetIteratorOf<T>&
			operator--()
				{Previous(); return *this;}
		T*
			operator++(int)
				{return ReadAndNext();}
		T*
			operator--(int)
				{return ReadAndPrevious();}
#endif
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~ SetIteratorOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	template <class T>
		SetIteratorOf<T>::SetIteratorOf(SetOf<T> *set):
			SetIterator(chain)
	{
	}

	template <class T>
		SetIteratorOf<T>::SetIteratorOf(SetOf<T> &set):
			SetIterator(&chain)
	{
	}

	template <class T>
		SetIteratorOf<T>::SetIteratorOf(const SetIteratorOf<T> &iterator):
			SetIterator(iterator)
	{
	}

	template <class T>
		SetIteratorOf<T>::~SetIteratorOf()
	{
	}
