#pragma once

#include "BasicTypeInterfaces.h"


class CWorkspaceAccess : protected IWorkspaceAccess, protected IWorkspaceAccessRef
{
public:
	CWorkspaceAccess(void);
	CWorkspaceAccess(IWorkspaceAccessPtr access);
	CWorkspaceAccess(IWorkspacePtr root, CString path);
	virtual ~CWorkspaceAccess(void);


	/////////////////////////////////////////////////////////////////////////////
	//	IWorkspaceAccess
	/////////////////////////////////////////////////////////////////////////////
	//!	インタフェース取得
	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(CString subPath);

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

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

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

	/////////////////////////////////////////////////////////////////////////////
	//	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);

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

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

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

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



//!	アクセスメソッド
#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); };\
	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()); };

