/* -------------------------------------------------------------------- */
/*	This is the table used to index LOG.DAT.							*/
/* -------------------------------------------------------------------- */
class LTable : public LogFlags
	{
	int 	PasswordHash;		/* hash of password 					*/
	int 	InitialsHash;		/* hash of initials 					*/
	label	Name;				/* name of user 						*/
	char	Alias[4];			/* alias of user						*/
	char	LocID[5];			/* locID of user						*/
	l_index LogIndex;			/* location in LOG.DAT					*/
	ulong	CallNumber; 		/* Which caller # they were 			*/

public:
	int GetPasswordHash(void) const 	{ return (PasswordHash); }
	void SetPasswordHash(int New)		{ PasswordHash = New; }
	int GetInitialsHash(void) const 	{ return (InitialsHash); }
	void SetInitialsHash(int New)		{ InitialsHash = New; }
	const char *GetName(void) const 	{ return (Name); }

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

		CopyStringToBuffer(Name, New, LABELSIZE);
		}

	const char *GetAlias(void) const
		{
		assert(this);
		return (Alias);
		}

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

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

	const char *GetLocID(void) const
		{
		assert(this);
		return (LocID);
		}

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

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

	l_index GetLogIndex(void) const
		{
		assert(this);
		return (LogIndex);
		}

	void SetLogIndex(l_index New)
		{
		assert(this);
		assert(New >= 0);
		assert(New < cfg.MAXLOGTAB);

		LogIndex = New;
		}

	ulong GetCallNumber(void) const
		{
		assert(this);
		return (CallNumber);
		}

	void SetCallNumber(ulong New)
		{
		assert(this);
		CallNumber = New;
		}

	Bool IsMainSysop(void) const
		{
		assert(this);
		return (SameString(Name, cfg.sysop));
		}
	};


class LogTable
	{
	l_slot TableSize;
	LTable *Table;

public:
	void Clear(void);

	LogTable(l_slot SizeOfTable)
		{
		assert(this);
		VerifyHeap();
		assert (SizeOfTable <= (65532u / sizeof(LTable)));

		TableSize = SizeOfTable;

		Table = new LTable[TableSize];
		Clear();
		VerifyHeap();
		}

	~LogTable(void)
		{
		assert(this);
		VerifyHeap();
		delete [] Table;
		VerifyHeap();
		}

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

	LTable *GetEntry(l_slot LogSlot) const
		{
		assert(this);
		assert(LogSlot >= 0);
		assert(LogSlot < TableSize);

		if (IsValid())
			{
			return (&Table[LogSlot]);
			}
		else
			{
			return (NULL);
			}
		}

	Bool Load(void);
	void Save(void) const;

	void SlideTableDown(l_slot HowFar);
	void UpdateTable(const LogEntry1 *Entry, l_index Index);

	static cdecl LogSorter(LTable *s1, LTable *s2)
		{
		if (!s1->IsInuse() && !s2->IsInuse())
			{
			return 0;
			}

		if (!s1->IsInuse() && s2->IsInuse())
			{
			return 1;
			}

		if (s1->IsInuse() && !s2->IsInuse())
			{
			return -1;
			}

		if (s1->GetCallNumber() < s2->GetCallNumber())
			{
			return 1;
			}

		if (s1->GetCallNumber() > s2->GetCallNumber())
			{
			return -1;
			}

		return 0;
		}

	void Sort(void)
		{
		assert(this);
		if (IsValid())
			{
			qsort(Table, TableSize, sizeof(*Table), (QSORT_CMP_FNP) LogSorter);
			}
		}

	void *GetPointer(void)
		{
		assert(this);
		return (Table);
		}
	};
