#pragma once

#include "FilterAPIWorkspace.h"


class CWorkspaceAccess
{
public:
	CWorkspaceAccess(void);
	CWorkspaceAccess(IWorkspacePtr root, CString path);
	CWorkspaceAccess(const SWorkspaceAccessCoreDataPtr passed);
	virtual ~CWorkspaceAccess(void);


	/////////////////////////////////////////////////////////////////////////////
	//	初期化など
	/////////////////////////////////////////////////////////////////////////////
	//!	全データクリア
	virtual void Clear(void);

	//!	複製する(自分を上書きコピーする、サブノードとキーがコピーされるが、自分のノード名は変更されない)
	virtual void Copy(CWorkspaceAccess &src);

	//!	アクセスクラス取得
	virtual CWorkspaceAccess GetAccess(CString subPath);

	//!	ルートを取得
	virtual IWorkspacePtr GetRoot();

	//!	名前を取得
	virtual CString GetNodeName();

	//!	パスを取得
	virtual CString GetPath();

	//!	DLL間受け渡し用構造体取得
	virtual int GetCoreData(SWorkspaceAccessCoreDataPtr passData);

	/////////////////////////////////////////////////////////////////////////////
	//	Keyに関する処理
	/////////////////////////////////////////////////////////////////////////////
	//!	データの設定
	virtual void SetKeyStr(CString key, CString data,int noCase=FALSE);
	virtual void SetKeyInt(CString key, int data,int noCase=FALSE);
	virtual void SetKeyInt64(CString key, __int64 data,int noCase=FALSE);
	virtual void SetKeyDWORD(CString key, DWORD data,int noCase=FALSE);

	//!	データの取得
	virtual CString GetKeyStr(CString key, CString defaultData,int noCase=FALSE);
	virtual int GetKeyInt(CString key, int defaultData,int noCase=FALSE);
	virtual __int64 GetKeyInt64(CString key, __int64 defaultData,int noCase=FALSE);
	virtual DWORD GetKeyDWORD(CString key, DWORD defaultData,int noCase=FALSE);

	//!	データの削除
	virtual void DeleteKey(CString key);

	//!	キー数を取得
	virtual int GetKeyCount();

	//!	全てのキー名を文字列として取得
	virtual int GetAllKey(CStringArray &list);

	//!	全てのデータを文字列として取得
	virtual int GetAllData(CStringArray &list);


	/////////////////////////////////////////////////////////////////////////////
	//	サブノードに関する処理
	/////////////////////////////////////////////////////////////////////////////
	//!	ノードを削除する
	virtual void DeleteNode(CString name);

	//!	サブノード数を得る
	virtual int GetSubNodeCount();

	//!	全てのサブノード名を文字列として取得
	virtual int GetAllSubNode(CStringArray &list);

protected:
	/////////////////////////////////////////////////////////////////////////////
	//	内部初期化
	/////////////////////////////////////////////////////////////////////////////
	//!	内部初期化
	void Init(IWorkspacePtr root, CString path);

	/////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	/////////////////////////////////////////////////////////////////////////////
	CString			m_path;
	IWorkspacePtr	m_root;
};


/*!
	文字列補助クラス
*/
class CAPIPassString : public IAPIPassString
{
public:
	//!	コンストラクタ
	CAPIPassString(CString str = "") { m_str = str; };

	//!	文字列を設定
	virtual void SetString(LPCSTR str) { m_str = str; };

	//!	取得
	virtual LPCSTR GetString() { return m_str; };

	//!	空？
	int IsEmpty() { return m_str.IsEmpty(); };

protected:
	CString	m_str;
};


/*!
	文字列配列補助クラス
*/
class CISArrayToCSArray : public IAPIPassStringArray
{
public:
	CISArrayToCSArray(CStringArray &arr) :
	  m_array(arr)
	{
	};

	//!	サイズ設定
	virtual void PreSetSize(int size)
	{
		m_array.SetSize(size);
		m_counter = 0;
	};

	//!	保持している文字列を取得
	virtual void AddString(LPCSTR str)
	{
		m_array[m_counter++] = str;
	};

protected:
	CStringArray	&m_array;

	int				m_counter;
};


/*!
	受け渡し補助クラス
*/
class CWorkspaceAccessCoreData
{
public:
	//!	初期化
	CWorkspaceAccessCoreData(CWorkspaceAccess access)
	{
		access.GetCoreData(&m_coreData);
	};

	//!	取得
	operator SWorkspaceAccessCoreDataPtr()
	{
		return(&m_coreData);
	}

protected:
	SWorkspaceAccessCoreData	m_coreData;
};

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_STR(PropertyName, PropertyPath, DefaultVal) \
	CString Get##PropertyName(CString defVal = DefaultVal)	{ return GetKeyStr(PropertyPath, defVal); }; \
	void Set##PropertyName(CString val)	{ SetKeyStr(PropertyPath, val); };	\
	void Clear##PropertyName()	{ SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, "").IsEmpty(); };
//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_INT(PropertyName, PropertyPath, DefaultVal)	\
	int Get##PropertyName(int defVal = DefaultVal)	{ return GetKeyInt(PropertyPath, defVal); }; \
	void Set##PropertyName(int val)	{ SetKeyInt(PropertyPath, val); };	\
	void Clear##PropertyName()	{ SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, "").IsEmpty(); };

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_INT64(PropertyName, PropertyPath, DefaultVal)	\
	__int64 Get##PropertyName(__int64 defVal = DefaultVal)	{ return GetKeyInt64(PropertyPath, defVal); }; \
	void Set##PropertyName(__int64 val)	{ SetKeyInt64(PropertyPath, val); };	\
	void Clear##PropertyName()	{ SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, "").IsEmpty(); };

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_WORKSPACE(PropertyName, PropertyPath)	\
	int Get##PropertyName()	{ return GetAccess(PropertyPath); };


//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_ACC_STR(Access, PropertyName, PropertyPath, DefaultVal) \
	CString Get##PropertyName(CString defVal = DefaultVal)	{ return Access.GetKeyStr(PropertyPath, defVal); }; \
	void Set##PropertyName(CString val)	{ Access.SetKeyStr(PropertyPath, val); };	\
	void Clear##PropertyName()	{ Access.SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, "").IsEmpty(); };

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_ACC_INT(Access, PropertyName, PropertyPath, DefaultVal)	\
	int Get##PropertyName(int defVal = DefaultVal)	{ return Access.GetKeyInt(PropertyPath, defVal); }; \
	void Set##PropertyName(int val)	{ Access.SetKeyInt(PropertyPath, val); };	\
	void Clear##PropertyName()	{ Access.SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, "").IsEmpty(); };

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_ACC_INT64(Access, PropertyName, PropertyPath, DefaultVal)	\
	__int64 Get##PropertyName(__int64 defVal = DefaultVal)	{ return Access.GetKeyInt64(PropertyPath, defVal); }; \
	void Set##PropertyName(__int64 val)	{ Access.SetKeyInt64(PropertyPath, val); };	\
	void Clear##PropertyName()	{ Access.SetKeyStr(PropertyPath, ""); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, "").IsEmpty(); };

//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_ACC_WORKSPACE(PropertyName, PropertyPath)	\
	int Get##PropertyName()	{ return Access.GetAccess(PropertyPath); };


//!	コンストラクタをまとめて定義
#define	DEFINE_COMMON_CONSTRUCTOR(className)	\
	className(void) {};\
	className(CWorkspaceAccess  &other)							{ CWorkspaceAccess::operator=(other); };\
	className(const SWorkspaceAccessCoreDataPtr other)			{ CWorkspaceAccess::operator=(other); };\
	void operator = (CWorkspaceAccess &other)					{ CWorkspaceAccess::operator=(other); };\
	void operator = (const SWorkspaceAccessCoreDataPtr other)	{ CWorkspaceAccess::operator=(other); };

