/*-----------------------------------------------------------------------------
[名称]	SettingPath.h
[概要]	設定ファイルパスクラスの実装
[備考]	なし
[履歴]	2003-02-08	NC		コメント付加(moralog)
		2004-02-19	b031228 (3367)Grep検索(dincom)
		2004-05-10	b031228 (3204)へぼぺとの連携(moralog)
		2004-05-10	b031228 (3751)文書名がショートファイルネームで表示される(moralog)
-----------------------------------------------------------------------------*/

//-----------------------------------------------------------------------------
// インクルード
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include <stdio.h>
#include <io.h>
#include <direct.h>
#include "shitarabian.h"
#include "SettingPath.h"
#include "Common.h"
#include "ExeCommon.h"
#include "CustomSetting.h"
#include "MainFrm.h"


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


//-----------------------------------------------------------------------------
// 定数
//-----------------------------------------------------------------------------
static const CString		strPrefix = "setting";


/*-----------------------------------------------------------------------------
[名称]	コンストラクタ
[機能]	インスタンスの生成。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CSettingPath::CSettingPath()
{
	Initialize();
	ResetGeneralFolder();
}

/*-----------------------------------------------------------------------------
[名称]	デストラクタ
[機能]	インスタンスの破棄。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CSettingPath::~CSettingPath()
{

}

/*-----------------------------------------------------------------------------
[名称]	インスタンス取得
[機能]	唯一インスタンスの取得。
[戻値]	CSettingPat*	唯一インスタンス [-] (-)
[備考]	Singletonパターン。
-----------------------------------------------------------------------------*/
CSettingPath* CSettingPath::GetInstance()
{
	static CSettingPath Instance;
	return( &Instance );
}

/*-----------------------------------------------------------------------------
[名称]	初期化ファイルパス取得
[機能]	初期設定フォルダを取得する。
[戻値]	CString		初期化ファイルパス [-] (-)
[備考]	したらびあんフォルダ。
-----------------------------------------------------------------------------*/
CString		CSettingPath::GetShitarabianFolderPath()
{
	static CString		strInifilePath;
	if ( strInifilePath.IsEmpty() )
	{
		CString		strFilename = __argv[0];
		int	idxLastSlash = strFilename.ReverseFind( '\\' );
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
		strInifilePath = ::GetLongFilePath( strFilename.Left( idxLastSlash ) );
// ▽ original BGN
//		strInifilePath = strFilename.Left( idxLastSlash+1 );
// △ original END
// ▲ (3204) END
	}

	return( strInifilePath );
}

/*-----------------------------------------------------------------------------
[名称]	属性初期化
[機能]	設定フォルダを列挙し、属性に格納する。
[戻値]	なし
[備考]	コンストラクタで一度だけコールされる。
-----------------------------------------------------------------------------*/
void CSettingPath::Initialize()
{
	CString		strRootPath = GetShitarabianFolderPath();

	// フォルダ名称を列挙する
	m_astrFolderNamez.RemoveAll();
    struct _finddata_t c_file;
    long hFile;
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
    if( (hFile = _findfirst( strRootPath + "\\" + strPrefix + "*", &c_file )) == -1L )
// ▽ original BGN
//    if( (hFile = _findfirst( strRootPath + strPrefix + "*", &c_file )) == -1L )
// △ original END
// ▲ (3204) END
	{
		return;
	}
	else
	{
		BOOL	bEnd = FALSE;
		while( !bEnd )
		{
			if ( c_file.attrib == _A_SUBDIR )
			{
				CString		strTmp = c_file.name;
				strTmp = strTmp.Mid( strPrefix.GetLength() );
				m_astrFolderNamez.Add( strTmp );
			}

			// 次の要素を調べる
			if ( _findnext( hFile, &c_file ) != 0)
			{
				bEnd = TRUE;
			}
		}
	}
}

/*-----------------------------------------------------------------------------
[名称]	設定フォルダ取得
[機能]	指定の設定をカレントとする。
[戻値]	CString		設定フォルダパス [-] (-)
[備考]	基本的に設定フォルダはしたらびあんフォルダを使うが
		設定のみ込み・書き出しをおこなうときは一時的に変更されている。
-----------------------------------------------------------------------------*/
CString	CSettingPath::GetFolderPath()
{
	return( m_strIniFolderPath );
}

/*-----------------------------------------------------------------------------
[名称]	設定フォルダ初期パス移動
[機能]	設定フォルダを初期の（標準）パスに戻す。
[戻値]	なし
[備考]	標準パスにしたらびあんフォルダを使用する。
-----------------------------------------------------------------------------*/
void	CSettingPath::ResetGeneralFolder()
{
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
	m_strIniFolderPath = GetShitarabianFolderPath() + "\\";
// ▽ original BGN
//	m_strIniFolderPath = GetShitarabianFolderPath();
// △ original END
// ▲ (3204) END
}

/*-----------------------------------------------------------------------------
[名称]	カレント設定設定
[機能]	指定の設定をカレントとする。
[戻値]	なし
[備考]	一時的に設定フォルダを変更し、読み込み・書き出しをおこなうときに使用する。
		（基本的に設定フォルダはしたらびあんフォルダを使う。）
-----------------------------------------------------------------------------*/
void	CSettingPath::SetFolderIndex(
	int idxFolder					// i  :設定[インデクス] (-) :-
)
{
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
	m_strIniFolderPath = GetShitarabianFolderPath() + "\\" + strPrefix + m_astrFolderNamez[idxFolder] + "\\";
// ▽ original BGN
//	m_strIniFolderPath = GetShitarabianFolderPath() + strPrefix + m_astrFolderNamez[idxFolder] + "\\";
// △ original END
// ▲ (3204) END
}

/*-----------------------------------------------------------------------------
[名称]	設定フォルダ用意
[機能]	設定フォルダがなければ作成する。
[戻値]	BOOL	処理結果 [-] (TRUE:成功、FALSE:失敗)
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CSettingPath::PrepareFolder(
	CString& strFolderName			// I  :フォルダ名称 [-] (-) :-
)
{
	if( strFolderName.IsEmpty() )
	{
		return( FALSE );
	}

	CFileStatus		tStatus;
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
	CString str = GetShitarabianFolderPath() + "\\" + strPrefix + strFolderName;
// ▽ original BGN
//	CString str = GetShitarabianFolderPath() + strPrefix + strFolderName;
// △ original END
// ▲ (3204) END

	BOOL	bExists = CFile::GetStatus(
		str,
		tStatus
	);
	if ( bExists )
	{
		if ( (tStatus.m_attribute | 0x10) == 0 )
		{
			return FALSE;
		}
	}
	else
	{
		if ( _mkdir( str ) != 0 )
		{
			// エラー	
			::ErrorLog(
				"フォルダ作成に失敗",
				"CSettingPath::PrepareFolder()"
			);
			return( FALSE );
		}
		m_astrFolderNamez.InsertAt( 0, strFolderName );
	}
	m_strIniFolderPath = str + "\\";

	return( TRUE );
}

/*-----------------------------------------------------------------------------
[名称]	拡張子取得
[機能]	指定に対応する拡張子を取得する。
[戻値]	BOOL	処理結果 [-] (TRUE:成功、FALSE:失敗)
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CSettingPath::GetExtz(
	int				idxFolder,		// I  :設定 [インデクス] (-) :-
	CStringArray*	pastrExtz		//   O:拡張子群 [-] (-) :-
)
{
	pastrExtz->RemoveAll();

	// 設定フォルダの存在確認
	BOOL	bExists;
	CString	strFolderName = GetFolderName( idxFolder );
	CFileStatus		tStatus;
	{
// ▼ (3204) BGN 2004.05.10 moralog GetShitarabianFolderPath()は末尾に\\をつけない
		CString strPath = GetShitarabianFolderPath() + "\\" + strPrefix + strFolderName;
// ▽ original BGN
//		CString strPath = GetShitarabianFolderPath() + strPrefix + strFolderName;
// △ original END
// ▲ (3204) END
		bExists = CFile::GetStatus(
			strPath,
			tStatus
		);
	}

	// 設定から拡張子情報を取得する
	if ( bExists )
	{
		if ( (tStatus.m_attribute | 0x10) != 0 )
		{
			// 一時的にCCustomSettingを利用して設定を読み込む
			CCustomSetting	Setting;

			CSettingPath::GetInstance()->PrepareFolder( strFolderName );
			// ▼ (3367) BGN 2004.02.19 (dincom) すべての設定を読み込まないようにする
			// ▽ Original BGN 
			//BOOL	bSuccess = Setting.Read();
			// △ original END
			BOOL bSuccess = Setting.ReadTypeSetting();
			// ▲ (3367) END
			if( bSuccess )
			{
				// 設定のEXT文字列を分解してアレイに格納する
				CString	str = Setting.GetExt();
				int		idxFound = 0;
				while( idxFound > -1 )
				{
					idxFound = str.FindOneOf( ",.:; " );
					if ( idxFound < 0 )
					{
						continue;
					}

					CString		strExt = str.Left( idxFound );
					// セパレータで分割してアレイに格納する
					strExt.TrimRight();
					strExt.TrimLeft();
					pastrExtz->Add( strExt );
					strExt = str.Mid( idxFound+1 );
					str = strExt;
				}
				str.TrimRight();
				str.TrimLeft();
				if(!str.IsEmpty())
				{
					pastrExtz->Add( str );
				}
			}
			CSettingPath::GetInstance()->ResetGeneralFolder();
		}
	}
	else
	{
		// Folderが存在しない？読み飛ばす
	}
	return( TRUE );
}

/*-----------------------------------------------------------------------------
[名称]	拡張子による設定反映
[機能]	指定した拡張子に対応する設定を読み込んで反映する。
[戻値]	BOOL	処理結果 [-] (TRUE:成功、FALSE:失敗)
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CSettingPath::PrepareExtFolder(
	CString& strExt			// I  :拡張子 [-] (-) :-
)
{
	// 設定全てについて検査する
	int	idxFolder;
	for( idxFolder=0 ; idxFolder<Count() ; idxFolder++ )
	{
		// 設定に対応する拡張子群の取得
		CStringArray	astrExtz;

		GetExtz(
			idxFolder,
			&astrExtz
		);

		// 拡張子が合致すれば設定を反映する			
		for( int idxExt=0 ; idxExt<astrExtz.GetSize() ; idxExt++ )
// ▼ (3751) BGN 2004.05.10 (moralog) 拡張子の大文字小文字区別無視
		if ( strExt.CompareNoCase( astrExtz[idxExt] ) == 0 )
// ▽ original BGN
//		if( astrExtz[idxExt] == strExt )
// △ original END
// ▲ (3751) END
		{
			// 指定と合致する設定を読み込む
			CString	strFolderName = GetFolderName( idxFolder );
			CSettingPath::GetInstance()->PrepareFolder( strFolderName );
			CGeneralSetting::GetInstance()->Read();

			// コンボボックスに設定名称を表示
			CMainFrame*		pFrame = (CMainFrame*)::AfxGetMainWnd();
			CComboBox*	pCombo = pFrame->GetSettingCombo();
			if ( ::IsWindow( pCombo->m_hWnd ) )
			{
				pCombo->SelectString( -1, strFolderName );
			}
// please! 起動直後にコンボボックスの選択を正しくするには？

			CSettingPath::GetInstance()->ResetGeneralFolder();
			return( TRUE );
		}
	}

	// 合致する設定が存在しない
	return( FALSE );
}

/*-----------------------------------------------------------------------------
[名称]	ファイルフィルタ取得
[機能]	編集中のファイルに対応したファイルフィルタを取得する。
[戻値]	BOOL	処理結果 [-] (TRUE:取得成功、FALSE:取得失敗)
[備考]	ドキュメントファイルの「開く」、「名前を付けて保存」に使用する。
-----------------------------------------------------------------------------*/
BOOL CSettingPath::GetFilter(
	CString*		pstrFilter,			//   O:フィルタ文字列 [-] (-) :-
	CString*		pstrDefaultExt		//   O:デフォルト拡張子 [-] (-) :-
)
{
	pstrFilter->Empty();
	pstrDefaultExt->Empty();

	// 現在の設定がどのフォルダかを取得
	int	iCurrentFolder = -1;
	int idxFolder;
	for( idxFolder=0 ; idxFolder<Count() ; idxFolder++ )
	{
		CString		a = CGeneralSetting::GetInstance()->GetSettingName();
		CString		b = GetFolderName(idxFolder);
		if( a == b )
		{
			iCurrentFolder = idxFolder;
			break;
		}
	}

	// フィルタ文字列の作成
	{
		// 現在の設定の拡張子を最初に登録
		if ( iCurrentFolder >= 0 )
		{
			CStringArray	astrExtz;
			GetExtz(
				iCurrentFolder,
				&astrExtz
			);

			// ついでにデフォルト拡張子を設定
			if( astrExtz.GetSize() > 0 )
			{
				*pstrDefaultExt = astrExtz[ 0 ];
			}

			CString		strExtz;
			for( int idxExt=0 ; idxExt<astrExtz.GetSize() ; idxExt++ )
			{
				strExtz += "*.";
				strExtz += astrExtz[idxExt];
				if( idxExt<astrExtz.GetSize()-1 )
				{
					strExtz += ";";
				}
			}
			CString	strFolder;
			strFolder.Format(
				"%s (%s)|%s|",
				GetFolderName( iCurrentFolder ),
				strExtz,
				strExtz
			);

			*pstrFilter += strFolder;
		}

		// 残りの拡張子を登録
		for( idxFolder=0 ; idxFolder<Count() ; idxFolder++ )
		if ( iCurrentFolder != idxFolder )
		{
			CStringArray	astrExtz;
			GetExtz(
				idxFolder,
				&astrExtz
			);

			CString		strExtz;
			for( int idxExt=0 ; idxExt<astrExtz.GetSize() ; idxExt++ )
			{
				strExtz += "*.";
				strExtz += astrExtz[idxExt];
				if( idxExt<astrExtz.GetSize()-1 )
				{
					strExtz += ";";
				}
			}
			CString	strFolder;
			strFolder.Format(
				"%s (%s)|%s|",
				GetFolderName( idxFolder ),
				strExtz,
				strExtz
			);
			if ( !strExtz.IsEmpty() )
			{
				*pstrFilter += strFolder;
			}
		}
		*pstrFilter += "All Files (*.*)|*.*||";
	}

	return( TRUE );
}

