// $Id: IDSet.h 8019 2007-07-14 22:30:11Z trick $

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Deadly Rooms of Death.
 *
 * The Initial Developer of the Original Code is
 * Caravel Software.
 * Portions created by the Initial Developer are Copyright (C) 2004 Caravel
 * Software. All Rights Reserved.
 *
 * Contributor(s):
 * Mike Rimer (mrimer)
 *
 * ***** END LICENSE BLOCK ***** */

//IDSet.h
//Declarations for CIDSet.
//Class for managing a set of ID values.

#ifndef IDSET_H
#define IDSET_H

#include "Types.h"
#include "IDList.h"

#include <set>
using std::set;

class CIDSet
{
public:
	typedef set<DWORD> IDSet;
	typedef IDSet::const_iterator const_iterator;

	CIDSet() {}
	CIDSet(const DWORD dwID) {this->ids.insert(dwID);}

	bool  empty() const {return this->ids.empty();}
	bool  has(const DWORD dwID) const {return this->ids.count(dwID) != 0;}
	UINT  size() const {return this->ids.size();}

	void  clear() {this->ids.clear();}
	void  erase(const DWORD dwID) {this->ids.erase(dwID);}

	CIDSet& operator = (const CIDSet &Src) {
		clear();
		return operator+=(Src);
	}
	CIDSet& operator += (const DWORD dwID) {
		this->ids.insert(dwID);
		return *this;
	}
	CIDSet& operator += (const CIDSet &Src) {
		for (const_iterator iter = Src.begin(); iter != Src.end(); ++iter)
			this->ids.insert(*iter);
		return *this;
	}
	CIDSet& operator += (const CIDList &Src) {
		IDNODE *pNode = Src.Get(0);
		while (pNode)
		{
			this->ids.insert(pNode->dwID);
			pNode = pNode->pNext;
		}
		return *this;
	}
	CIDSet& operator -= (const DWORD dwID) {
		this->ids.erase(dwID);
		return *this;
	}
	CIDSet& operator -= (const CIDSet &Src) {
		for (const_iterator iter = Src.begin(); iter != Src.end(); ++iter)
			this->ids.erase(*iter);
		return *this;
	}

	//Removes IDs from this set that aren't members of Filter.
	void intersect(const CIDSet &Filter)
	{
		set<DWORD> filteredIDs;
		for (const_iterator iter = Filter.begin(); iter != Filter.end(); ++iter)
			if (has(*iter))
				filteredIDs.insert(*iter);
		this->ids = filteredIDs;
	}

	//Does this set contain all IDs that a second set has.
	bool contains(const CIDSet &against) const
	{
		for (const_iterator iter = against.begin(); iter != against.end(); ++iter)
			if (!has(*iter))
				return false;
		return true;
	}
	//Does this set contain any IDs that a second set has.
	bool containsAny(const CIDSet &against) const
	{
		for (const_iterator iter = against.begin(); iter != against.end(); ++iter)
			if (has(*iter))
				return true;
		return false;
	}

	const_iterator begin() const {return this->ids.begin();}
	const_iterator end() const {return this->ids.end();}

	DWORD getFirst() const {return size() ? *begin() : 0;}
	DWORD getMax() const {return size() ? *(this->ids.rbegin()) : 0;}

private:
	set<DWORD> ids;
};

#endif //...#ifndef IDSET_H
