/* -------------------------------------------------------------------- */
/*	GROUP.H						Citadel									*/
/* -------------------------------------------------------------------- */
/*				Data and structures for the group subsystem.			*/
/* -------------------------------------------------------------------- */


/* -------------------------------------------------------------------- */
/*	This is all of the information we know about groups. Like rooms,	*/
/*	this information is stored in GRP.DAT, one entry after another.		*/
/*	Unlike rooms, however, we do not keep a table to index this file.	*/
/*	The file is small enough that we keep the whole thing in memory		*/
/*	always. This is a potential area to look into to save memory, but	*/
/*	not much. (Which is why it hasn't been done yet.) The only member	*/
/*	of this structure that doesn't get much use is the group's			*/
/*	description. A typical number of groups configured for an			*/
/*	installation of Citadel is the default: 16. With the description	*/
/*	of each of these being 80 bytes, the amount of memory that can be	*/
/*	saved is only 1,280 bytes.											*/
/* -------------------------------------------------------------------- */
class GroupEntry
	{
	label	GroupName;			// Name of the group
	uchar	UNUSED1;			// Group generation #.
	char	Description[80];	// Description of group

	Bool	Inuse	: 1;		// Is group inuse?
	Bool	Locked	: 1;		// Sysop access needed for changes
	Bool	Hidden	: 1;		// hidden to all, unless specified by
								// name or in group
	Bool	AutoAdd	: 1;		// Add to new users.
	uint	UNUSED2	: 12;

public:
	GroupEntry(void)
		{
		assert(this);
		Clear();
		}

	void Clear(void)
		{
		assert(this);
		VerifyHeap();
		memset(this, 0, sizeof(*this));
		VerifyHeap();
		}

	void Verify(void)
		{
		// Make sure no strings are too long
		assert(this);
		GroupName[LABELSIZE]	= 0;
		Description[79]		= 0;

		// Fill unused areas with nothingness
		UNUSED1	= 0;
		UNUSED2	= 0;
		}

	const char *GetName(void) const
		{
		assert(this);
		return (GroupName);
		}

	void SetName(const char *New)
		{
		assert(this);
		assert(New);

		CopyStringToBuffer(GroupName, New, LABELSIZE);
		}

	const char *GetDescription(void) const
		{
		assert(this);
		return (Description);
		}

	void SetDescription(const char *New)
		{
		assert(this);
		assert(New);

		CopyStringToBuffer(Description, New, sizeof(Description) - 1);
		}

	Bool IsInuse(void) const
		{
		assert(this);
		return (Inuse);
		}

	void SetInuse(Bool New)
		{
		assert(this);
		Inuse = !!New;
		}

	Bool IsLocked(void) const
		{
		assert(this);
		return (Locked);
		}

	void SetLocked(Bool New)
		{
		assert(this);
		Locked = !!New;
		}

	Bool IsHidden(void) const
		{
		assert(this);
		return (Hidden);
		}

	void SetHidden(Bool New)
		{
		assert(this);
		Hidden = !!New;
		}

	Bool IsAutoAdd(void) const
		{
		assert(this);
		return (AutoAdd);
		}

	void SetAutoAdd(Bool New)
		{
		assert(this);
		AutoAdd = !!New;
		}

	Bool Load(g_slot Slot);
	Bool Save(g_slot Slot);
	Bool Load(g_slot Slot, FILE *File);
	Bool Save(g_slot Slot, FILE *File);
	};

class GroupBuffer
	{
	g_slot NumGroups;
	GroupEntry *Groups;

public:
	void Clear(void)
		{
		assert(this);
		VerifyHeap();

		if (IsValid())
			{
			memset(Groups, 0, sizeof(*Groups) * NumGroups);
			VerifyHeap();
			}
		}

	GroupBuffer(g_slot NumberOfGroups)
		{
		assert(this);
		VerifyHeap();
		assert (NumberOfGroups <= (65532u / sizeof(GroupEntry)));

		NumGroups = NumberOfGroups;

		Groups = new GroupEntry[NumGroups];
		Clear();
		VerifyHeap();
		}

	~GroupBuffer(void)
		{
		assert(this);
		VerifyHeap();
		delete [] Groups;
		VerifyHeap();
		}

	Bool IsValid(void) const
		{
		assert(this);
		return (Groups != NULL);
		}

	void Resize(g_slot NewNumberOfGroups)
		{
		assert(this);
		VerifyHeap();
		assert (NewNumberOfGroups <= (65532u / sizeof(GroupEntry)));

		if (IsValid())
			{
			delete [] Groups;
			}

		NumGroups = NewNumberOfGroups;

		Groups = new GroupEntry[NumGroups];
		Clear();
		VerifyHeap();
		}

	GroupEntry *GetEntry(g_slot GroupSlot) const
		{
		assert(this);
		assert(GroupSlot >= 0);
		assert(GroupSlot < NumGroups);

		if (IsValid())
			{
			return (&Groups[GroupSlot]);
			}
		else
			{
			return (NULL);
			}
		}

	Bool Load(const char *Name = grpDat);
	Bool Save(const char *Name = grpDat) const;

	const GroupEntry *GetPointer(void) const
		{
		assert(this);
		return (Groups);
		}
	};

extern GroupBuffer *GroupData;			// Group data goes here

// group.cpp
g_slot FindGroupByName(const char *TestName);
g_slot FindGroupByPartialName(const char *TestName, Bool IgnoreInGroup);


// grpovl.cpp
void ListGroups(Bool CheckInGroup);
