/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
#include "stdafx.h"
#include "resource.h"
#include "IO/GLFileManager.h"
#include "IO/GLFileImporter.h"
#include "IO/GLFileExporter.h"

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

CGLFileManager::CGLFileManager()
{
}

CGLFileManager::~CGLFileManager(){
	{
		IMap::iterator i = m_mapi.begin(), last = m_mapi.end();
		for(; i != last; ++i){
			delete i->second;
		}
	}
	{
		OMap::iterator i = m_mapo.begin(), last = m_mapo.end();
		for(; i != last; ++i){
			delete i->second;
		}
	}
}

CGLFileImporter* CGLFileManager::GetImporter(LPCTSTR lpszFileName) const
{
	// ファイルパスが拡張子を含んでいなかったら何も返せない。
	CString strExt(::PathFindExtension(lpszFileName)); // ドットから始まる
	if(strExt.IsEmpty()){
		return 0;
	}
	strExt.MakeLower();

	// マップの key から部分文字列を検索することになる
	IMap::const_iterator first = m_mapi.begin(), last = m_mapi.end();
	for(; first != last; ++first){
		// "*.stp;*.step" のような文字列なので、
		// 直接 PathMatchSpec することができない。
		CString strWild(first->first);
		strWild.MakeLower();

		if(strWild.Find(strExt) != -1){
			CGLFileImporter* pHandler = first->second;
			pHandler->SetFileName(lpszFileName);
			return pHandler;
		}
	}

	return 0;
}

/// 保存ファイル名からハンドルできるオブジェクトを返す。
/// @param[in] lpszFileName 拡張子を含むファイルパス。
CGLFileExporter* CGLFileManager::GetExporter(LPCTSTR lpszFileName) const
{
	// ファイルパスが拡張子を含んでいなかったら
	// ファイルダイアログのコンボボックスの位置を利用するしかない。
	CString strExt(::PathFindExtension(lpszFileName)); // ドットから始まる
	if(strExt.IsEmpty()){
		return 0;
	}
	strExt.MakeLower();

	// GetImporter と同様の探索処理を行う。
	OMap::const_iterator first = m_mapo.begin(), last = m_mapo.end();
	for(; first != last; ++first){
		CString strWild(first->first);
		strWild.MakeLower();

		if(strWild.Find(strExt) != -1){
			CGLFileExporter* pHandler = first->second;
			pHandler->SetFileName(lpszFileName);
			return pHandler;
		}
	}

	return 0;
}

/// 保存ダイアログのフィルター文字列からハンドルできるオブジェクトを返す。
/// @param[in] lpszFilter "AG Files (*.ag)" のような文字列
CGLFileExporter* CGLFileManager::GetExporterFromFilter(LPCTSTR lpszFilter) const
{
	OMap::const_iterator first = m_mapo.begin(), last = m_mapo.end();
	for(; first != last; ++first){
		CGLFileExporter* pHandler = first->second;

		if(pHandler->GetTypeString().Compare(lpszFilter) == 0){
			return pHandler;
		}
	}
	return 0;
}

CGLFileManager& CGLFileManager::GetInstance(){
	static CGLFileManager factory;
	return factory;
}

/// 拡張子を指定して、インポートハンドラーをマネージャーに追加する。
/// @param[in] nIDSExt 拡張子文字列のリソース ID
/// @param[in] pHandler インポートハンドラー
void CGLFileManager::RegisterHandler(UINT nIDSExt, CGLFileImporter* pHandler)
{
	CString str;
	VERIFY(str.LoadString(nIDSExt));
	RegisterHandler(str, pHandler);
}

/// 拡張子を指定して、インポートハンドラーをマネージャーに追加する。
/// @param[in] nIDSExt 拡張子文字列 (e.g. "*.iges;*.igs")
/// @param[in] pHandler インポートハンドラー
void CGLFileManager::RegisterHandler(const CString& strExt, CGLFileImporter* pHandler)
{
	ASSERT(!strExt.IsEmpty());
	m_mapi.insert(IMap::value_type(strExt, pHandler));
	pHandler->SetExt(strExt);

	ASSERT(!pHandler->GetExt().IsEmpty());
}

/// 拡張子を指定して、エクスポートハンドラーをマネージャーに追加する。
/// @param[in] nIDSExt 拡張子文字列のリソース ID
/// @param[in] pHandler エクスポートハンドラー
void CGLFileManager::RegisterHandler(UINT nIDSExt, CGLFileExporter* pHandler)
{
	CString str;
	VERIFY(str.LoadString(nIDSExt));
	RegisterHandler(str, pHandler);
}

/// 拡張子を指定して、エクスポートハンドラーをマネージャーに追加する。
/// @param[in] nIDSExt 拡張子文字列  (e.g. "*.iges;*.igs")
/// @param[in] pHandler エクスポートハンドラー
void CGLFileManager::RegisterHandler(const CString& strExt, CGLFileExporter* pHandler)
{
	ASSERT(!strExt.IsEmpty());
	m_mapo.insert(OMap::value_type(strExt, pHandler));
	pHandler->SetExt(strExt);

	ASSERT(!pHandler->GetExt().IsEmpty());
}

CGLFileManager::IMap::const_iterator CGLFileManager::ibegin() const
{
	return m_mapi.begin();
}

CGLFileManager::IMap::const_iterator CGLFileManager::iend() const
{
	return m_mapi.end();
}

CGLFileManager::OMap::const_iterator CGLFileManager::obegin() const
{
	return m_mapo.begin();
}

CGLFileManager::OMap::const_iterator CGLFileManager::oend() const
{
	return m_mapo.end();
}

void CGLFileManager::GetAllSaveHandler(OMap& omap) const{
	omap = m_mapo;
}
