#pragma once

#include ".\workspacenode.h"

/*!
	自動置き換え
*/
class IWorkspaceAutoSwap
{
public:
	//!	通常の取得
	virtual CString SwapString(CString orgKey, CString orgData) = 0;

	//!	削除
	virtual void Delete() {};
};
//!	ポインタ型
typedef IWorkspaceAutoSwap* IWorkspaceAutoSwapPtr;


class CWorkspace;
class CWorkspaceAccess
{
public:
	CWorkspaceAccess(void);
	CWorkspaceAccess(CWorkspace *root,CString path);
	virtual ~CWorkspaceAccess(void);


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

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

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

	//!	ルートを取得
	CWorkspace * GetRoot();

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


	/*********************************************************
		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 int KeyIsExist(CString key,int noCase=FALSE);

	//!	データの削除
	virtual void DeleteKey(CString key,int noCase=FALSE);

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

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

	//!	全てのキーをコピーする
	virtual void CopyAllKeys(CKeyDataArray &keyData);

	//!	文字列中のキー名をデータに置き換えた文字列を取得する
	virtual CString GetKeySwapString(CString str,CString noData=_T(""), IWorkspaceAutoSwapPtr tempSwap = NULL);

	/******************************************************
		エイリアス(CConfigクラス互換用)
	*******************************************************/
	void SetConfig(CString key, CString data)	{ SetKeyStr(key, data); };								//	データの設定
	void SetConfig(CString key, int data)		{ SetKeyInt(key, data); };								//	データの設定
	void SetConfig(CString key, UINT data)		{ SetKeyDWORD(key, data); };							//	データの設定
	void SetConfig(CString key, __int64 data)	{ SetKeyInt64(key, data); };							//	データの設定

	CString GetConfig(CString key, CString defaultData,int noCase=FALSE)	{ return GetKeyStr(key, defaultData, noCase); };	//	データの取得
	int GetConfig(CString key, int defaultData,int noCase=FALSE)			{ return GetKeyInt(key, defaultData, noCase); };	//	データの取得
	UINT GetConfig(CString key, UINT defaultData,int noCase=FALSE)			{ return GetKeyDWORD(key, defaultData, noCase); };	//	データの取得
	__int64 GetConfig(CString key, __int64 defaultData,int noCase=FALSE)	{ return GetKeyInt64(key, defaultData, noCase); };	//	データの取得

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

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

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

protected:
	CString			m_path;
	CWorkspace		*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); };

