/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/* ***************************************************** */

/**
 * Common/GLCommandFactory.h の実装。
 */
#include "stdafx.h"

#include "Common/GLCommandFactory.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// デフォルトコンストラクター
CGLCommandFactory::CGLCommandFactory(){
}

// デストラクター
CGLCommandFactory::~CGLCommandFactory(){
}

void CGLCommandFactory::RegisterCommand(UINT nID, CreateCommandFunc pfn){
	m_commandFactoryMap[nID] = pfn;
}

void CGLCommandFactory::RegisterUpdateUI(UINT nID, UpdateUIFunc pfn){
	m_uimap[nID] = pfn;
}

// コマンドオブジェクトを生成できるか否かテスト。
// @note Complexity O(1) で実装したい。
bool CGLCommandFactory::QueryCommand(UINT nCmdID) const{
	// キー nCmdID がマップ内にあれば OK だ。
	return m_commandFactoryMap.count(nCmdID) == 1;
}

// コマンド ID とドキュメントからコマンドを生成（登録済のメソッドを呼ぶ）
MGCommandBase* CGLCommandFactory::CreateCommand(fugenDoc* pDoc, UINT nCmdID)const{
	CommandMap::const_iterator i = m_commandFactoryMap.find(nCmdID);
	if(i == m_commandFactoryMap.end()){
		return nullptr;
	}

	// コマンド生成関数ポインターを得る。
	CreateCommandFunc pfnCreateCommand = i->second;
	ASSERT(pfnCreateCommand);

	// MGCommandBase を new して返す。
	return (*pfnCreateCommand)(pDoc, nCmdID);
}

// コマンドに対応するメニューアイテムの有効無効テストに利用する。
bool CGLCommandFactory::IsEnabled(fugenDoc* pDoc, UINT nCmdID)const{
	UpdateUIMap::const_iterator i = m_uimap.find(nCmdID);
	if(i == m_uimap.end()){
		// true: 無条件に実行可能とする。
		return true;
	}

	// 関数ポインターを得る。
	UpdateUIFunc pfnUpdateUIFunc = i->second;
	// ヌルが格納されている場合は、実行させない。
	return pfnUpdateUIFunc ? (*pfnUpdateUIFunc)(pDoc, nCmdID) : false;
}
