/*!
	WorkspaceAccess.h

	CWorkspaceへアクセスするためのクラス、CWorkspaceへの基本的なアクセスはこのクラスを経由する
	このクラスは、CWorkspaceのノードへのアクセスを保持し、そのノード以下へのアクセスを提供する。
	DLLを超える場合は、IWorkspaceAccessやIWorkspaceAccessRefを使用し、ノードパスとIWorkspaceを受け渡す
	設定など、所持するプロパティが決まっている場合は、継承してテンプレートとなるクラスを作成できる。
*/
#pragma once
#include "types/WorkspaceTypes.h"
#include "IStringHelper.h"

/*!
	CWorkspace アクセスクラス
*/
class CWorkspaceAccess :
	protected IWorkspaceAccess, protected IWorkspaceAccessRef
{
public:
	/////////////////////////////////////////////////////////////////////////////
	//	コンストラクタ
	/////////////////////////////////////////////////////////////////////////////
	CWorkspaceAccess(void);
	CWorkspaceAccess(IWorkspaceAccessPtr access);
	CWorkspaceAccess(IWorkspacePtr root, CUTF8String path);

	/////////////////////////////////////////////////////////////////////////////
	//	インタフェース取得
	/////////////////////////////////////////////////////////////////////////////
	//!	インタフェース取得
	virtual IWorkspaceAccessPtr GetIWorkspaceAccess() { return this; };

	//!	インタフェース取得
	virtual IWorkspaceAccessRefPtr GetIWorkspaceAccessRef() { return this; };

	//!	インタフェースへ設定
	virtual void FillIWorkspaceAccessRef(IWorkspaceAccessRefPtr access) { access->SetWorkspaceAccess(GetRoot(), GetPath()); };

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

	/////////////////////////////////////////////////////////////////////////////
	//	IWorkspaceAccessPtr
	/////////////////////////////////////////////////////////////////////////////
	//!	初期化
	virtual void SetWorkspaceAccess(IWorkspacePtr root, LPCU8STR path)
	{
		Init(root, path);
	}

	//!	インターフェース取得
	virtual IWorkspacePtr GetIWorkspacePtr()
	{
		return GetRoot();
	}

	//!	パス取得
	virtual void GetAccessPath(IStringPtr path)
	{
		path->SetString(m_path, -1);
	}

	/////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	/////////////////////////////////////////////////////////////////////////////
	//!	自分の示すノード
	CUTF8String		m_path;

	//!	親Workspace
	IWorkspacePtr	m_root;
};


/******************************************************************************************/
//	テンプレート作成用マクロ
/******************************************************************************************/
//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_STR(PropertyName, PropertyPath, DefaultVal) \
	CUTF8String Get##PropertyName(CUTF8String defVal = DefaultVal)	{ return GetKeyStr(PropertyPath, defVal); }; \
	void Set##PropertyName(CUTF8String val)	{ SetKeyStr(PropertyPath, val); };	\
	void Clear##PropertyName()	{ SetKeyStr(PropertyPath, _U8("")); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, _U8("")).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, _U8("")); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, _U8("")).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, _U8("")); };	\
	int PropertyName##IsSet() { return !GetKeyStr(PropertyPath, _U8("")).IsEmpty(); };

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


//!	アクセスメソッド
#define	DEFINE_PROPERTY_METHOD_ACC_STR(Access, PropertyName, PropertyPath, DefaultVal) \
	CUTF8String Get##PropertyName(CUTF8String defVal = DefaultVal)	{ return Access.GetKeyStr(PropertyPath, defVal); }; \
	void Set##PropertyName(CUTF8String val)	{ Access.SetKeyStr(PropertyPath, val); };	\
	void Clear##PropertyName()	{ Access.SetKeyStr(PropertyPath, _U8("")); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, _U8("")).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, _U8("")); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, _U8("")).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, _U8("")); };	\
	int PropertyName##IsSet() { return !Access.GetKeyStr(PropertyPath, _U8("")).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); };\
	void operator = (CWorkspaceAccess &other)					{ CWorkspaceAccess::operator=(other); };\
	virtual IWorkspaceAccessPtr GetIWorkspaceAccess()			{ return this; };\
	virtual IWorkspaceAccessRefPtr GetIWorkspaceAccessRef()		{ return this; };\
	virtual void FillIWorkspaceAccessRef(IWorkspaceAccessRefPtr access) { access->SetWorkspaceAccess(GetRoot(), GetPath()); };

