
#ifndef DKUTIL_DETAIL_LUNALIBDEF_HPP
#define DKUTIL_DETAIL_LUNALIBDEF_HPP

#include <helper/windows_header.h>

namespace dkutil{

///SOCKETのログ一行を保持する為の最大数
#define SOCKET_LOG_LINE_MAX				(256)

typedef bool (*PCALLBACKSOCKETPROC)( HWND hWnd, long Id );			///< ソケット処理用コールバック関数
/**
	@brief	ホスト情報

	ソケット使用時にホスト情報を格納するために使う構造体。
*/
struct HOSTINFO
{
	char Name[256];						///< ホスト名
	char Alias[16][256];				///< ホスト別名テーブル
	char Address[16][64];				///< IPアドレステーブル
	long Type;							///< データタイプ
	long Length;						///< データサイズ
	long AliasCount;					///< エイリアス数
	long AddressCount;					///< IPアドレス数
};

/**
	@brief	ソケット用送信データ定義

	ソケット使用時にデータを送信する際に使用されるデータ構造体。
*/
struct SOCKETSENDDATA
{
	unsigned long Send;					///< 送信済みデータサイズ
	unsigned long Size;					///< 送信合計サイズ
	unsigned char *pData;				///< 送信データ
};
/**
	@brief	ソケット接続情報

	ソケットでの接続時の接続情報を<BR>
	格納しておくための構造体です
*/
struct CONNECTCLIENTDATA
{
	SOCKET Socket;							///< ソケットデータ
	SOCKADDR_IN SockAddr;					///< ソケットアドレス
	HOSTINFO HostInfo;						///< ホスト情報
	char IPAddress[64];						///< ＩＰアドレス
	char Buffer[1024];						///< バッファ
	long Length;							///< バッファ長さ

	bool IsWriteEnable;						///< 書き込みＯＫフラグ
	bool IsReadEnable;						///< 読み込みＯＫフラグ

	SOCKETSENDDATA SendData;				///< 送信データ

	CONNECTCLIENTDATA *pNext;				///< 次の接続情報へのポインタ
};

/**
	@brief	ソケットクライアント情報

	ソケットでの接続時の接続情報を<BR>
	格納しておくための構造体です
*/
struct SOCKETMTCLIENTDATA
{
	SOCKET Socket;							///< ソケットデータ
	SOCKADDR_IN SocketAddr;					///< ソケットアドレス
	HOSTINFO HostInfo;						///< ホスト情報

	SOCKETMTCLIENTDATA *pNext;				///< 次の接続情報へのポインタ
};


/**
	@brief	ソケット用データ

	WinSockを管理するために必要な情報を<BR>
	格納している構造体です
*/
struct WORK_LUNASOCKETASYNCIO
{
	char LastError[1024];							///< エラー格納用文字列
	bool IsInitialize;								///< 初期化完了フラグ
	HOSTINFO HostInfo;								///< ホスト情報
	HOSTENT HostEntry;								///< ホストエントリー
	SOCKET Socket;									///< 自分のソケット
	bool IsConnect;									///< 接続中か否か
	bool IsRequest;									///< 送受信リクエスト中か否か
	long RequestCode;								///< リクエスト結果コード
	WSAOVERLAPPED Overlap;							///< 送受信リクエスト用データ
	WSABUF SendBuff;								///< 送信バッファ
	WSABUF RecvBuff;								///< 受信バッファ
};

/**
	@brief	ソケット用データ

	WinSockを管理するために必要な情報を<BR>
	格納している構造体です
*/
struct WORK_LUNASOCKETSERVERASYNC
{
	char LastError[1024];							///< エラー格納用文字列
	bool IsInitialize;								///< 初期化完了フラグ
	HOSTINFO HostInfo;								///< ホスト情報
	HOSTENT HostEntry;								///< ホストエントリー
	SOCKET Socket;									///< 自分のソケット
	bool IsConnect;									///< 接続中か否か
	long ClientCount;								///< クライアント数
	CONNECTCLIENTDATA *pConnectionList;				///< 接続ユーザーリスト
	CONNECTCLIENTDATA ConnectClient;				///< 最終接続クライアント
	CONNECTCLIENTDATA CloseClient;					///< 最終切断クライアント
	HWND hWindow;									///< 処理するウィンドウのウィンドウハンドル
	unsigned long Message;							///< 処理するメッセージ

	PCALLBACKSOCKETPROC pCallBackAccept;			///< 受信受付時用コールバック関数のポインタ
	PCALLBACKSOCKETPROC pCallBackClose;				///< 接続切断時用コールバック関数のポインタ
	PCALLBACKSOCKETPROC pCallBackRead;				///< データ受信時用コールバック関数のポインタ
	PCALLBACKSOCKETPROC pCallBackWrite;				///< データ送信時用コールバック関数のポインタ
};

/**
	@brief	マルチスレッド型ソケット用データ

	WinSockを管理するために必要な情報を<BR>
	格納している構造体です
*/
struct WORK_LUNASOCKETSERVERMT
{
	char LastError[1024];							///< エラー格納用文字列
	bool IsInitialize;								///< 初期化完了フラグ
	HOSTINFO HostInfo;								///< ホスト情報
	HOSTENT HostEntry;								///< ホストエントリー
	SOCKET Socket;									///< 自分のソケット
	bool IsConnect;									///< 接続中か否か
	HANDLE hListenThread;							///< サーバー待機用スレッドハンドル
	unsigned long ListenThreadId;					///< サーバー待機用スレッドID
	unsigned long ClientCount;						///< 接続クライアント数
	HANDLE hEventExit;								///< 終了用イベントハンドル
	HANDLE hEventClient;							///< クライアント用イベントハンドル
	CRITICAL_SECTION ClientCriticalSection;			///< クライアント用クリティカルセクション
	char SocketLog[SOCKET_LOG_LINE_MAX][1024];		///< ソケット用ログ
	long SocketLogLine;								///< ソケット用ログ数
	CRITICAL_SECTION LogCriticalSection;			///< クライアント用クリティカルセクション
	void (*pCallbackProc)( long Id );				///< コールバック関数
	SOCKETMTCLIENTDATA *pList;						///< クライアントリスト
};


#define MemoryClear(PD,S)		::FillMemory((PD),(S),0x00)													///< メモリクリア
#define MemoryFill(PD,PS,S)		::FillMemory((PD),(S),(PS))													///< メモリ塗りつぶし
#define MemoryMove(PD,PS,S)		::MoveMemory((PD),(PS),(S))													///< メモリ移動
#define MemoryCopy(PD,PS,S)		::CopyMemory((PD),(PS),(S))													///< メモリコピー


inline void *malloc_memset(size_t size){
	void *p=malloc(size);
	if(p){
		memset(p,0,size);
	}
	return 0;
}
///< メモリ確保
#define MemoryAlloc(S)					malloc(S)						
///< メモリ初期化確保
#define MemoryClearAlloc(S)			malloc_memset(S)
///< メモリ再確保
#define MemoryReAlloc(P,S)			realloc(P,S)

///< メモリ解放
#define MemoryFree(P)					{ free((P)); (P) = NULL; }


/*
#define MemoryAlloc(S)					LunaMemory::Alloc((S),0xFFFF,__FILE__,__LINE__)						///< メモリ確保
//#define MemoryAllocLog(S)				LunaMemory::AllocLog((S),0xFFFF,__FILE__,__LINE__)					///< メモリ確保（ログ付き）
#define MemoryClearAlloc(S)				LunaMemory::ClearAlloc((S),0xFFFF,__FILE__,__LINE__)				///< メモリ初期化確保
//#define MemoryClearAllocLog(S)			LunaMemory::ClearAllocLog((S),0xFFFF,__FILE__,__LINE__)				///< メモリ初期化確保（ログ付き）
#define MemoryReAlloc(P,S)				LunaMemory::ReAlloc((P),(S),__FILE__,__LINE__)						///< メモリ再確保
//#define MemoryReAllocLog(P,S)			LunaMemory::ReAllocLog((P),(S),__FILE__,__LINE__)					///< メモリ再確保（ログ付き）
#define MemoryAllocGruop(S,G)			LunaMemory::Alloc((S),(G),__FILE__,__LINE__)						///< グループメモリ確保
//#define MemoryAllocGruopLog(S,G)		LunaMemory::AllocLog((S),(G),__FILE__,__LINE__)						///< グループメモリ確保（ログ付き）
#define MemoryClearAllocGruop(S,G)		LunaMemory::ClearAlloc((S),(G),__FILE__,__LINE__)					///< グループメモリ初期化確保
//#define MemoryClearAllocGruopLog(S,G)	LunaMemory::ClearAllocLog((S),(G),__FILE__,__LINE__)				///< グループメモリ初期化確保（ログ付き）
#define MemoryFree(P)					{ LunaMemory::Free((P)); (P) = NULL; }								///< メモリ解放
//#define MemoryFreeLog(P)				{ LunaMemory::FreeLog((P)); (P) = NULL; }							///< メモリ解放（ログ付き）
#define MemoryFreeGruop(gruop)			{ LunaMemory::FreeGruop((G)); (P) = NULL; }							///< グループメモリ解放
//#define MemoryFreeGruopLog(gruop)		{ LunaMemory::FreeGruopLog((G)); (P) = NULL; }						///< グループメモリ解放（ログ付き）
*/

}//end of dkutil namespace



#endif