#include "StdAfx.h"
#include "ContextManager.h"
#include "DateUtility.h"

CContextManager::CContextManager(void)
{
	//	初期値
	m_idCounter = 0;
	m_contextLogCount = 0;

	//	スレッド環境領域を取得
	m_context = m_contextRoot.GetAccess("Threads");

	//	スレッド環境領域のログを取得
	m_contextLog = m_contextRoot.GetAccess("ThreadLogs");
}

CContextManager::~CContextManager(void)
{
}


//////////////////////////////////////////////////////////////////////////////////////
//	インタフェース
//////////////////////////////////////////////////////////////////////////////////////
/*!
	初期化
*/
int CContextManager::Start(CWorkspaceAccess setting)
{
	m_contextLogCount = setting.GetKeyInt(_T("Log::MaxThreadLog"), 20);
	return(0);
}


/*!
	新規コンテキスト
*/
CWorkspaceAccess CContextManager::GetNewContext()
{
	//	コンテキスト名生成
	CString	name;
	name.Format(_T("Thread_%04x"), GetNewID());

	//	コンテキスト生成
	CWorkspaceAccess	newContext = m_context.GetAccess(name);
	newContext.SetKeyStr(_T("ThreadName"), name);

	//	作成日時設定
	GetDate(newContext.GetAccess("StartTime"));
	return(newContext);
}

/*!
	コンテキスト利用完了
*/
void CContextManager::DeleteContext(CWorkspaceAccess context)
{
	//	コンテキスト名取得
	CString	name = context.GetConfig("ThreadName", "");

	//	ログは有効か？
	if(m_contextLogCount > 0)
	{
		//	日付の設定
		CWorkspaceAccess	date = context.GetAccess(_T("EndTime"));
		GetDate(date);

		//	ロック
		WORKSPACE_LOCK(m_contextLog);

		//	領域のコピー
		CWorkspaceAccess	log = m_contextLog.GetAccess(name);
		log.Copy(context);

		//	ログ数の調整
		if(m_contextLog.GetSubNodeCount() > m_contextLogCount)
		{
			CStringArray	nodes;
			m_contextLog.GetAllSubNode(nodes);
			m_contextLog.DeleteNode(nodes[0]);
		}
	}

	//	環境の削除
	m_context.DeleteNode(name);
}


/*!
	日付取得
*/
void CContextManager::GetDate(CWorkspaceAccess date, int detail)
{
	//	クリア
	date.Clear();

	//	時刻
	CTime	time = CTime::GetCurrentTime();
	date.SetConfig("Date", time.Format("%Y/%m/%d"));
	date.SetConfig("Time", time.Format("%H:%M:%S"));
	date.SetConfig("GMT", CDateUtility::GetGMTString(time));

	if(detail)
	{
		date.SetConfig("Year", time.Format("%Y"));
		date.SetConfig("Month", time.Format("%m"));
		date.SetConfig("Day", time.Format("%d"));
		date.SetConfig("DayOfWeek", time.Format("%w"));

		date.SetConfig("MonthString", time.Format("%b"));
		date.SetConfig("DayOfWeekString", time.Format("%a"));

		date.SetConfig("Hour", time.Format("%H"));
		date.SetConfig("Minute", time.Format("%M"));
		date.SetConfig("Second", time.Format("%S"));

	}
}

/*!
	コピーを取得
*/
void CContextManager::GetContextCopy(CWorkspaceAccess copyTo)
{
	copyTo.Copy(m_contextRoot.GetAccess(""));
}


/*!
	テキストとして取得
*/
CString CContextManager::GetContextByXMLString()
{
	return m_contextRoot.ToXMLString();
}


//////////////////////////////////////////////////////////////////////////////////////
//	ツール関数
//////////////////////////////////////////////////////////////////////////////////////
/*!
	新規ID
*/
int CContextManager::GetNewID()
{
	return m_idCounter.IncCounter();
}
