/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file fugenDocManager.cpp
 * @brief fugenDocManager クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "fugenDocManager.h"
#include "IO/GLFileManager.h"
#include "IO/GLFileImporter.h"
#include "IO/GLFileExporter.h"
#include "GLFileDialog.h"
#include "Misc/UserPreference.h"

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


fugenDocManager::fugenDocManager(){
}

fugenDocManager::~fugenDocManager(){
}

void fugenDocManager::OnFileOpen(){
	std::vector<CString> newFile;
	if(!PromptFileNameMulti(newFile)){
		return;
	}
	std::vector<CString>::iterator cur = newFile.begin(), last = newFile.end();
	for(; cur != last; ++cur){
		AfxGetApp()->OpenDocumentFile(*cur);
	}
}

namespace
{
	int SearchFilterIndex(
		const CString& strExt,
		LPCTSTR lpstrFilter,
		int nMaxCustFilter)
	{
		if(!lpstrFilter){
			return -1;
		}

		LPCTSTR pszWork = lpstrFilter;
		LPCTSTR pszExt = 0;

		for(int i = 0; i < nMaxCustFilter; ++i){
			size_t nWhere = _tcslen(pszWork) + 1;
			pszExt = pszWork + nWhere; // *.igs;*.iges

			CString strTarg(pszExt);
			strTarg.MakeLower();
			// 部分文字列の検索で実装する。
			if(strTarg.Find(strExt) != -1){
				return i + 1; // インデックスは 1 から始まる
			}

			pszWork = pszExt + _tcslen(pszExt) + 1;
		}
		return -1;
	}
}

// See VC98/MFC/SRC/DOCMGR.CPP
BOOL fugenDocManager::DoPromptFileName(
	CString& fileName,
	UINT nIDSTitle,
	DWORD lFlags,
	BOOL bOpenFileDialog,
	CDocTemplate* pTemplate
){
	CGLFileDialog dlgFile(bOpenFileDialog);

	CString title;
	VERIFY(title.LoadString(nIDSTitle));

	dlgFile.m_ofn.Flags |= lFlags;

	CString strFilter;
	CGLFileManager& fm = CGLFileManager::GetInstance();

	if(bOpenFileDialog){
		// Import
		CGLFileManager::IMap::const_iterator 
			i = fm.ibegin(),
			last = fm.iend();
		for(; i != last; ++i){
			strFilter += i->second->GetTypeString();
			strFilter += (TCHAR)'\0';
			strFilter += i->first;
			strFilter += (TCHAR)'\0';
			dlgFile.m_ofn.nMaxCustFilter++;
		}
	}else{
		// Export
		CGLFileManager::OMap::const_iterator 
			i = fm.obegin(),
			last = fm.oend();
		for(; i != last; ++i){
			strFilter += i->second->GetTypeString();
			strFilter += (TCHAR)'\0';

			const CString& strExt = i->first;
			strFilter += strExt;
			strFilter += (TCHAR)'\0';
			dlgFile.m_ofn.nMaxCustFilter++;
		}
	}

	if(bOpenFileDialog){
		// append the "*.*" all files filter
		CString allFilter;
		VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));

		strFilter += allFilter;
		strFilter += (TCHAR)'\0';   // next string please

		strFilter += _T("*.*");
		strFilter += (TCHAR)'\0';   // last string
		dlgFile.m_ofn.nMaxCustFilter++;

		dlgFile.m_ofn.nFilterIndex = dlgFile.m_ofn.nMaxCustFilter;
	}

	dlgFile.m_ofn.lpstrFilter = strFilter;
	if(!bOpenFileDialog){
		// これで mgl 形式をデフォルトで選択させられるはず。
		const UserPreference& pref = UserPreference::getInstance();
		const int nSaveAsFilterIndexLast = pref.GetIntValue(upv_File_DocManager_SaveFilter);
		
		if(nSaveAsFilterIndexLast != -1){
			dlgFile.m_ofn.nFilterIndex = nSaveAsFilterIndexLast;
		}
		else{
			dlgFile.m_ofn.nFilterIndex = SearchFilterIndex(
				_T(".mgl"),
				dlgFile.m_ofn.lpstrFilter,
				dlgFile.m_ofn.nMaxCustFilter);
		}
	}

	dlgFile.m_ofn.lpstrTitle = title;

	// fileName の拡張子以外の部分を欲しい

	::PathRemoveExtension(fileName.GetBuffer(MAX_PATH));
	fileName.ReleaseBuffer();

	dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(MAX_PATH);
	//dlgFile.m_ofn.lpstrDefExt = xxx;

	INT_PTR nResult = dlgFile.DoModal();
	fileName.ReleaseBuffer();

	// fileName に拡張子が付いていることを担保する
	if(!*::PathFindExtension(fileName)){
		// 以下の二点を行う。
		// * コンボボックスのフィルターからファイルタイプを判断する。
		// * 拡張子を自動で与える。

		CString strExt = dlgFile.GetDesiredExt();
		ASSERT(!strExt.IsEmpty());

		::PathAddExtension(fileName.GetBuffer(MAX_PATH), strExt);

		// 前回選択番号として記録
		UserPreference& pref = UserPreference::getInstance();
		if(dlgFile.m_ofn.nFilterIndex != dlgFile.m_ofn.nMaxCustFilter){
			pref.SetIntValue(upv_File_DocManager_SaveFilter, dlgFile.m_ofn.nFilterIndex);
		}
		else{
			pref.SetIntValue(upv_File_DocManager_SaveFilter, SearchFilterIndex(
				_T(".mgl"),
				dlgFile.m_ofn.lpstrFilter,
				dlgFile.m_ofn.nMaxCustFilter));
		}
		fileName.ReleaseBuffer();
	}

	return nResult == IDOK;
}

// 複数ファイル版
BOOL fugenDocManager::PromptFileNameMulti(
	std::vector<CString>& newFile
){
	CGLFileDialog dlgFile(TRUE);

	CString title;
	VERIFY(title.LoadString(AFX_IDS_OPENFILE));

	dlgFile.m_ofn.Flags |= OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;

	CString strFilter;
	CGLFileManager& fm = CGLFileManager::GetInstance();
	{
		CGLFileManager::IMap::const_iterator 
			i = fm.ibegin(),
			last = fm.iend();
		for(; i != last; ++i){
			strFilter += i->second->GetTypeString();
			strFilter += (TCHAR)'\0';
			strFilter += i->first;
			strFilter += (TCHAR)'\0';
			dlgFile.m_ofn.nMaxCustFilter++;
		}
	}

	// append the "*.*" all files filter
	CString allFilter;
	VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));

	strFilter += allFilter;
	strFilter += (TCHAR)'\0';   // next string please

	strFilter += _T("*.*");
	strFilter += (TCHAR)'\0';   // last string
	dlgFile.m_ofn.nMaxCustFilter++;

	dlgFile.m_ofn.lpstrFilter = strFilter;
	dlgFile.m_ofn.lpstrTitle = title;

	CString fileName;
	dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(2048);

	// 初期フィルターを「すべて (*.*)」にセットする

	UserPreference& pref = UserPreference::getInstance();
	int nFilterIndexLast = pref.GetIntValue(upv_File_DocManager_OpenFilter);

	dlgFile.m_ofn.nFilterIndex =
		(nFilterIndexLast != -1) ? nFilterIndexLast : dlgFile.m_ofn.nMaxCustFilter;

	INT_PTR nResult = dlgFile.DoModal();
	if(nResult == IDOK){

		POSITION p = dlgFile.GetStartPosition();
		while(p){
			CString path = dlgFile.GetNextPathName(p);

			// 拡張子の存在を担保する。
			if(!*::PathFindExtension(path)){
				// 拡張子がない場合、ファイルタイプが不明でロード不可能。
				// 本来ならばエラーメッセージを出すべきだが、
				// とりあえず黙って次のファイルを調べることにしよう。
				continue;
			}

			newFile.push_back(path);
		}

		// 前回選択番号として記録
		if(dlgFile.m_ofn.nFilterIndex != dlgFile.m_ofn.nMaxCustFilter){
			pref.SetIntValue(upv_File_DocManager_OpenFilter, dlgFile.m_ofn.nFilterIndex);
		}
		else if(!newFile.empty()){
			const CString& strPath = newFile.back();

			pref.SetIntValue(upv_File_DocManager_OpenFilter, SearchFilterIndex(
				::PathFindExtension(strPath),
				dlgFile.m_ofn.lpstrFilter,
				dlgFile.m_ofn.nMaxCustFilter));
		}
	}
	fileName.ReleaseBuffer();

	return nResult == IDOK;
}
