#ifndef __DynamicServer_h_954C1D48_846B_4D83_B2_8E_A2_85_F4_CF_F0_91_
#define __DynamicServer_h_954C1D48_846B_4D83_B2_8E_A2_85_F4_CF_F0_91_

#include "DynamicServerErrorCode.h"

#ifdef DYNAMICSERVER_EXPORTS
#define DYNAMICSERVER_API __declspec(dllexport)
#else
#define DYNAMICSERVER_API __declspec(dllimport)
#endif

template<class T> struct DsMemoryAlloc
{
	virtual T*	New () { return new T; }
	virtual T*	NewArray (int i) { return new T[i]; }
	virtual void	Delete (T* p) { delete p; }
	virtual void	DeleteArray (T* p) { delete[] p; }
}; // struct DsMemoryAlloc.

template<class T> class DsArray : public DsMemoryAlloc<T>
{
public:
	DsArray () : m_pArray(NULL), m_szArraySize(0) {}
	DsArray (const DsArray<T>& array) : m_pArray(NULL), m_szArraySize(0) { operator = (array); }
	DsArray (const T* pArray, size_t szSize) : m_pArray(NULL), m_szArraySize(0) { Set(pArray, szSize); }
	virtual ~DsArray () { Clear(); }
	virtual T* Allocate (size_t szSize)
		{
			Clear();
			if (szSize != 0)
			{
				m_pArray = NewArray(szSize);
				m_szArraySize = szSize;
			}
			return m_pArray;
		}
	virtual void Set (const T* pArray, size_t szSize)
		{
			Allocate(szSize);
			memcpy(Get(), pArray, sizeof(T) * szSize);
		}
	virtual void Clear ()
		{
			if (m_pArray != NULL)
			{
				DeleteArray(m_pArray);
			}
			m_pArray = NULL;
			m_szArraySize = 0;
		}
	virtual size_t	GetSize () const { return m_szArraySize; }
	virtual operator const T* () const
		{
			return Get();
		}
	virtual T*		Get () { return m_pArray; }
	virtual const T*	Get () const { return m_pArray; }
	virtual void	operator = (const DsArray<T>& array)
		{
			Allocate(array.GetSize());
			memcpy(Get(), array.Get(), sizeof(T) * GetSize());
		}
	virtual T&	GetAt (size_t n) { return m_pArray[n]; }

protected:
	T*		m_pArray;
	size_t	m_szArraySize;
}; // struct DsArray.

class DsString : public DsArray<wchar_t>
{
public:
	DsString (const wchar_t* wcpString = NULL)
		:	DsArray<wchar_t>()
		{
			operator = (wcpString);
		}
	virtual void	operator = (const wchar_t* wcpString)
		{
			Clear();
			if (wcpString != NULL)
			{
				Set(wcpString, wcslen(wcpString) + 1);
			}
		}
}; // struct DsString.

struct DsTableName
{
	DsTableName () {}
	DsTableName (const wchar_t* wcpTopDirPath, const DWORD aTableIds[], DWORD dwTableIds)
		:	m_hstrTopDirPath(wcpTopDirPath),
			m_vTableIds(aTableIds, dwTableIds) {}
	DsString		m_hstrTopDirPath;
	DsArray<DWORD>	m_vTableIds;
}; // struct DsTableName.

typedef long DsErr;

/*************************************************************************
 * <_xZkqqHx_iDeOiDiJiDfI_xHqqkZx_>	DynamicServer
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfEiBfLiDgPiBfLiCmMiDeDiDjDiDfOiDhEiDeGiBfLiDfIiDeOiDiJiDfIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	06.02.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
class DynamicServer
{
public:
	virtual void	SetLoginUserName (const wchar_t* wcpUserName) = NULL;

	virtual DsErr	CheckTopGroupPath (const wchar_t* wcpTopDirPath) = NULL;

	virtual DsErr	TryReadLock (	GUID& guidTable,
									DWORD& dwDeleteIdentifier,
									DWORD& dwAppendIdentifier,
									const DsTableName& dsTableName) = NULL;

	virtual DsErr	TryWriteLock (const DsTableName& dsTableName) = NULL;

	virtual DsErr	CreateWriteLock (const DsTableName& dsTableName) = NULL;

	virtual BOOL	ReadUnlock (const DsTableName& dsTableName) = NULL;

	virtual BOOL	WriteUnlock (const DsTableName& dsTableName) = NULL;

	virtual BOOL	IsReadLocked (const DsTableName& dsTableName) const = NULL;

	virtual BOOL	IsWriteLocked (const DsTableName& dsTableName) const = NULL;

	virtual void	WhoLockingFile (DsString& dsUserName, const DsTableName& dsTableName) const = NULL;

	virtual void	SendTransaction (	BOOL bMultiUserAccessable,
										BOOL bReturnImmediate,
										const wchar_t* wcpTopDirPath[],
										const BYTE* pTransaction[],
										size_t szTransaction[],
										long lTopDirCount) = NULL;

	virtual DsErr	GetFlushErrorCode () const = NULL;

	virtual void	GetFlushErrorMessage (DsString& dstrErrorMessage) const = NULL;

	virtual DWORD	GetRecordCount (const DsTableName& dsTableName) = NULL;

	virtual void	LoadTableIndex (DsArray<BYTE>& vTableIndex,
									const DsTableName& dsTableName,
									DWORD dwBeginIndex,
									DWORD dwEndIndex) = NULL;

	virtual void	LoadTableRecords (	DsArray<BYTE>& vTableRecord,
										const DsTableName& dsTableName,
										DWORD dwBeginIndex,
										DWORD dwEndIndex) = NULL;

	virtual void	GetUnlockRequestGroup (DsArray<DsTableName>& dsGroupNameArray) = NULL;

	virtual BOOL	IsFlushing () const = NULL;

	virtual BOOL	IsGroupExist (const DsTableName& dsGroupName) const = NULL;

	virtual BOOL	IsTableExist (const DsTableName& dsTableName) const = NULL;

	virtual DsErr	DeleteTopGroup (const wchar_t* wcpTopDirPath) = NULL;

	virtual BOOL	IsRecoveryRequired (const wchar_t* wcpTopDirPath) const = NULL;

	virtual BOOL	IsTopGroupExist (const wchar_t* wcpTopDirPath) const = NULL;

	virtual FDTIME	GetLastModifiedFdtime (const DsTableName& dsTableName) const = NULL;

	virtual DWORD	OnDlgOpenDirectory (DsString& dsDirPath,
										HWND hwndParent,
										const wchar_t* wcpInitPath,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount) const = NULL;

	virtual DWORD	OnDlgSaveTopGroup (	DsString& dstrTopGroupPath,
										HWND hwndParent,
										const wchar_t* wcpDlgTitle,
										const wchar_t* wcpInitPath,
										const wchar_t* wcpDocumentType,
										const wchar_t* wcpExt,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount,
										BOOL bIsJustifyWindow) const = NULL;

	virtual DWORD	OnDlgOpenTopGroup (	DsString& dstrTopGroupPath,
										HWND hwndParent,
										const wchar_t* wcpDlgTitle,
										const wchar_t* wcpFilePath,
										const wchar_t* wcpDocumentType,
										const wchar_t* wcpExt,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount,
										BOOL bIsJustifyWindow) const = NULL;

	virtual void	TerminateFlushThread () = NULL;

	virtual void	MakeUniqTopGroupPath (	DsString& dsTopGroupPath,
											const wchar_t* wcpPath,
											const wchar_t* wcpExt) const = NULL;

// 06.02.22 Fukushiro M. 1_xZkqqHx_iNhDiNoNiPjM_xHqqkZx_ ()
//	virtual void	GetTmpDirectory (DsString& dsDirPath) const = NULL;

	virtual void	SetCurrentDirectory (const wchar_t* wcpDirPath) = NULL;

	virtual void	GetCurrentDirectory (DsString& dsDirPath) const = NULL;

}; // class DynamicServer.

typedef void (*DsErrorThrowCallback)(DWORD dwId, const wchar_t* wcpMessage);

extern DYNAMICSERVER_API DynamicServer* DynamicServerCreate (DsErrorThrowCallback callback);
extern DYNAMICSERVER_API void DynamicServerDelete (DynamicServer* pServer);
extern DYNAMICSERVER_API void DynamicServerSetWnd (HWND hWnd, DWORD dwUnlockRequestMessage);

#endif//__DynamicServer_h_954C1D48_846B_4D83_B2_8E_A2_85_F4_CF_F0_91_
