/*
	\file	CWorkspace.h
	\brief	階層化変数管理クラス

	2006/04/05	XML保存形式の変更
	2006/11/14	XML入出力方法変更
*/

#pragma once

#include ".\workspacenode.h"
#include ".\Buffer.h"
#include ".\workspaceaccess.h"




class CWorkspaceLock;
class CWorkspaceAccess;
class CWorkspace
{
	friend class CWorkspaceAccess;
	friend class CWorkspaceLock;
	friend class CWorkspaceStringList;

public:
	CWorkspace(CString className = _T(""));
	virtual ~CWorkspace(void);

	/////////////////////////////////////////////////////////////////////////////////////
	//	アクセス可能な関数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	アクセスクラスを取得する
	CWorkspaceAccess GetAccess(CString path);

	//!	アクセスクラスを取得し、中身をクリア
	CWorkspaceAccess GetCleanAccess(CString path);

	/////////////////////////////////////////////////////////////////////////////////////
	//	入出力に関する処理
	/////////////////////////////////////////////////////////////////////////////////////
	//!	XMLファイルへ出力
	int SaveToXMLFile(CString filePath, CString savePath = _T(""));

	//!	XMLファイルよりロード
	int LoadFromXMLFile(CString filePath);


	//!	XML文字列へ出力
	CStringA ToXMLStringUTF8(CString savePath = _T(""));

	//!	XML文字列から生成
	int FromXMLStringUTF8(CStringA xml);

	//!	XML文字列へ出力
	CStringA ToXMLString(CString savePath = _T(""));

	//!	XML文字列から生成
	int FromXMLString(CStringA xml);

	/////////////////////////////////////////////////////////////////////////////////////
	//	設定
	/////////////////////////////////////////////////////////////////////////////////////
	//!	リードオンリー
	void SetReadOnly(int readOnly);

	//!	自動置き換え(古い順に置き換え実行)
	void AddAutoSwap(IWorkspaceAutoSwapPtr autoSwap);

	//!	自動置き換え解除
	void DelAutoSwap(IWorkspaceAutoSwapPtr autoSwap);

protected:
	/////////////////////////////////////////////////////////////////////////////////////
	//	初期化など
	/////////////////////////////////////////////////////////////////////////////////////
	//!	全データクリア
	void Clear(CString path);

	//!	コピー
	void Copy(CString destPath, CString srcPath, CWorkspace* srCWorkspace=NULL);

	/////////////////////////////////////////////////////////////////////////////////////
	//	Keyに関する処理
	/////////////////////////////////////////////////////////////////////////////////////
	//!	データの設定
	void SetKeyData(CString path, CString data,int noCase=FALSE);

	//!	データの取得
	CString GetKeyData(CString path, CString defaultData,int noCase=FALSE);

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

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

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

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

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

	/////////////////////////////////////////////////////////////////////////////////////
	//	Keyに関する処理 - WorkspaceStringList
	/////////////////////////////////////////////////////////////////////////////////////
	//!	キーを検索
	int FindKeyData(CString path, CString sData, int noCase = FALSE);

	//!	キーを検索
	int FindKeyDataPath(CString path, CString fPath, int eqPath = FALSE);

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

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

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


	
protected:
	/////////////////////////////////////////////////////////////////////////////////////
	//	その他の処理
	/////////////////////////////////////////////////////////////////////////////////////
	//!	ノードパスに変更
	CString ToNodePath(CString path);

	//!	サブノードのポインタを取得
	CWorkspaceNode	*GetSubNode(CString &path,CString &key);

	//!	コピー内部処理
	void _Copy(CWorkspaceNode *dest, CString srcPath);

	/////////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	作業領域のルート
	CWorkspaceNode		m_root;

	//!	ロックオブジェクト
	CCriticalSection	m_scopeLock;

	//!	クラス名
	CString				m_className;

	//!	リードオンリー
	int						m_readOnly;

	//!	自動置き換え
	CTypedPtrArray<CPtrArray, IWorkspaceAutoSwapPtr>	m_autoSwap;

private:
	//!	コピー禁止
	CWorkspace(const CWorkspace &other);
	void operator=(const CWorkspace &other);
};


class CWorkspaceLock
{
public:
	CWorkspaceLock(CWorkspaceAccess wa)
	{
		m_ws = wa.GetRoot();
		m_ws->m_scopeLock.Lock();
	};

	virtual ~CWorkspaceLock()
	{
		m_ws->m_scopeLock.Unlock();
	};


	CWorkspace	*m_ws;
};


#define	WORKSPACE_LOCK(x) CWorkspaceLock __lock(x);

