/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 1, or (at your option)
** any later version.

** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.

** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com> --- August 1998
 */

/*
 * MultiString.h --- remember several unique persistents strings
 */

#ifndef MULTISTRING_H
#define MULTISTRING_H

#include <vector>
#include "Persistent.h"
#include "CPStr.h"

#ifndef NAMESPACE
#	if defined(_MSC_VER) || defined(__MWERKS__) || (__GNUC__ > 2)
#		define NAMESPACE(w) w::
#	else
#		define NAMESPACE(w) ::
#	endif
#endif

///	Persistent array
template<class T>
class TMPersistent : public CPersistent
{
public:
	typedef	NAMESPACE(std) vector<T>	list_t;
	
	TMPersistent(const char *uniqueName, kClassPersistent pclass = kNoClass)
	: CPersistent(uniqueName, pclass) {};

	virtual ~TMPersistent() {};
	
	virtual unsigned int SizeOf(void) const {return sizeof (int) + sizeof (T) * fAllItems.size ();};
	virtual const void *GetData(void) const
		{
			fBuf.AdjustSize(SizeOf());
			char *tmp = fBuf;
			*(int *) tmp = fAllItems.size();
			tmp += sizeof(int) / sizeof(char);
			
			for(typename list_t::const_iterator i = fAllItems.begin(); i != fAllItems.end(); ++i)
			{
				memcpy(tmp, (const char *)(&*i), sizeof (T));
				tmp += sizeof (T);
			}
			
			return (char *)fBuf;
		};

	virtual void SetData(const void *ptr, unsigned int size)
		{
			const char *tmp = (char *)ptr;
			fAllItems.erase(fAllItems.begin(), fAllItems.end());
			unsigned int thesize = *(int *)tmp;
			tmp += sizeof(int) / sizeof(char);
			for(unsigned int i = 0; i < thesize; ++i)
			{
				fAllItems.push_back(*((T*)tmp));
				tmp += sizeof (T);
			}
		};
		// persistent interface
	
	inline const list_t & GetList(void) const { return fAllItems; }
	inline list_t & GetList(void) { return fAllItems; }
	
protected:
	list_t 						fAllItems;
	mutable	CStaticAllocT<char> fBuf;
};

template<class T>
class TMString : public CPersistent
{
public:
	typedef	NAMESPACE(std) vector<T> list_t;
	
	TMString(unsigned int maxstr, const char *uniqueName,
		char * const *defaultStr = 0L, kClassPersistent pclass = kNoClass);
		// defaultStr is a null terminated set of strings

	virtual ~TMString();
	
	virtual unsigned int SizeOf(void) const;
	virtual const void *GetData(void) const;
	virtual void SetData(const void *ptr, unsigned int size);
		// persistent interface
	
	void Insert(const char *newstr);
		// add a new string
	
	bool Remove(const char *newstr);
		// remove a new string, true if it was found
	
	typename list_t::const_iterator Find(const char *instr) const;
		// find a string
	
	inline const list_t & GetList(void) const { return fAllStrs; }
	inline typename list_t::const_iterator begin() const { return GetList ().begin ();};
	inline typename list_t::const_iterator end() const { return GetList ().end ();};
	
protected:
	virtual int Compare(const char *s1, const char *s2) const
	{
		return strcmp(s1, s2);
	}

	list_t fAllStrs;
	mutable	CStaticAllocT<char> fBuf;
	unsigned int fMaxStr;
};

class CMString : public TMString<CStr>
{
	UDECLARE_DYNAMIC(CMString)
public:
	CMString(unsigned int maxstr, const char *uniqueName,
		char * const *defaultStr = 0L, kClassPersistent pclass = kNoClass) :
		TMString<CStr>(maxstr, uniqueName, defaultStr, pclass)
	{
	}

	virtual ~CMString()
	{
	}
};

class CMPString : public TMString<CPStr>
{
	UDECLARE_DYNAMIC(CMPString)
public:
	CMPString(unsigned int maxstr, const char *uniqueName,
		char * const *defaultStr = 0L, kClassPersistent pclass = kNoClass) :
		TMString<CPStr>(maxstr, uniqueName, defaultStr, pclass)
	{
	}

	virtual ~CMPString()
	{
	}
};

/// This is a multi-string for storing map (i.e. dictionary)
class CKeyString : public CMString
{
public:
	CKeyString(unsigned int maxstr, const char *uniqueName,
		char * const *defaultStr = 0L, kClassPersistent pclass = kNoClass) :
		CMString(maxstr, uniqueName, defaultStr, pclass)
	{
	}

	virtual ~CKeyString()
	{
	}

	static void Concatenate(UStr & res, const char *key, const char *value);
	static void Split(const char *str, UStr & key, UStr & value);
protected:
	virtual int Compare(const char *s1, const char *s2) const;
};

#if qUnix
	void DoDataExchange(bool fill, int widid, int cmdid, CMString & mstr);
#endif // qUnix

#endif /* AUTHEN_H */
