/*-----------------------------------------------------------------------------
[名称]	ExeCommon.cpp
[概要]	したらびあん本体用ユーティリティ関数の実装
[備考]	なし
[履歴]	2003-01-23	NC		コメント付加(moralog)
		2003-12-28  b040111 (3632)キャレット位置の強調(moralog)
		2004-05-10	b031228 (3204)へぼぺとの連携(moralog)
-----------------------------------------------------------------------------*/

//-----------------------------------------------------------------------------
// インクルード
//-----------------------------------------------------------------------------
#include "stdafx.h"
#define	APSTUDIO_INVOKED	// リソースIDの設定をちょっと覗き見たい
#include "resource.h"
#define ExeCommon
#include "ExeCommon.h"
#include "Shlwapi.h"
#include "Common/Common.h"
#include "vbscriptregexp.h"
#include "SettingPath.h"
#include "FinderDefault.h"
#include "FinderBREGEXP.h"
#include "FinderVBScript.h"
#include "BregPool.h"
#include "ClipHistory.h"
#include "EmphasisItem.h"
#include "GeneralSetting.h"
// ▼ (3204) BGN 2004.05.10 (moralog) ランチャツールバー追加
#include "shitarabian.h"
extern CShitarabianApp	theApp;
// ▲ (3204) END

// 参考になるWebページ
// MFC Programming Note（全般）
// http://www.aa.wakwak.com/~dragoon/mfctop.htm


/*-----------------------------------------------------------------------------
[名称]	スクロール単位→文字列取得
[機能]	スクロール単位文字列の取得。
[戻値]	CString		スクロール単位文字列 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CString	EScrollUnitToString(
	EScrollUnit	eValue		// I  :スクロール単位 [-] (-) :-
)
{
	switch( eValue )
	{
	case Scroll1Pixel:
		return( "Scroll1Pixel" );
		break;
	case Scroll1Row:
		return( "Scroll1Row" );
		break;
	case Scroll2Row:
		return( "Scroll2Row" );
		break;
	case Scroll1Char:
		return( "Scroll1Char" );
		break;
	case Scroll2Char:
		return( "Scroll2Char" );
		break;
	default:
		return( "Scroll1Pixel" );
		break;
	}
}


/*-----------------------------------------------------------------------------
[名称]	文字列→スクロール単位取得
[機能]	スクロール単位の取得。
[戻値]	EScrollUnit		スクロール単位 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
EScrollUnit	StringToEScrollUnit(
	CString	strValue		// I  :スクロール単位文字列 [-] (-) :-
)
{
	if ( strValue == "Scroll1Pixel" ) return( Scroll1Pixel );
	if ( strValue == "Scroll1Row" ) return( Scroll1Row );
	if ( strValue == "Scroll2Row" ) return( Scroll2Row );
	if ( strValue == "Scroll1Char" ) return( Scroll1Char );
	if ( strValue == "Scroll2Char" ) return( Scroll2Char );
	if ( strValue == "Scroll1Pixel" ) return( Scroll1Pixel );
	return( Scroll1Pixel );
}


/*-----------------------------------------------------------------------------
[名称]	エラーロギング
[機能]	エラーメッセージの表示。
[戻値]	なし
[備考]	実際にはログを残していない。
-----------------------------------------------------------------------------*/
void ErrorLog(
	const char*		strReason,		// I  :エラー説明文字列 [-] (-) :-
	const char*		strFunction		// I  :エラー発生関数文字列 [-] (-) :-
){
	CString		strMes;
	strMes.Format("%s にて\nerror : %s\nが発生しました。", strFunction, strReason);
	MessageBox(
		NULL,
		strMes,
		"したらびあん　ランタイムエラー",
		MB_OK|MB_ICONSTOP
	);
}

// ▼ (3632) BGN 2003.12.28 (moralog) バージョン管理方法変更
// ▽ original BGN
/*-----------------------------------------------------------------------------
[名称]	文字列→バージョン取得
[機能]	バージョンの取得。
[戻値]	EVersion	バージョン [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
/*
EVersion	StringToVersion(
	CString&	strVersion
)
{
	if( strVersion == "α2_02")
	{
		return( VersionAlpha2_02 );
	}
	if( strVersion == "α3")
	{
		return( VersionAlpha3 );
	}
	return( VersionUnknown );
}
// △ original END
*/
// ▲ (3632) END


#include "MainFrm.h"
static CMainFrame*	f_pMainFrame = NULL;	// メインフレームオブジェクト [-] (-)
/*-----------------------------------------------------------------------------
[名称]	メインフレーム設定
[機能]	メインフレームオブジェクトの設定。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void SetMainFrame( CMainFrame* pMainFrame )
{
	f_pMainFrame = pMainFrame;
}


/*-----------------------------------------------------------------------------
[名称]	メインフレーム取得
[機能]	メインフレームオブジェクトの取得。
[戻値]	CMainFrame*		メインフレーム [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CMainFrame*	GetMainFrame()
{
	return( f_pMainFrame );
}


/*-----------------------------------------------------------------------------
[名称]	ユニークコマンドID生成
[機能]	新しいコマンドIDの生成。
[戻値]	int		コマンドID [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
int		UniqueCommandID()
{
	static int		s_idNextCommand = _APS_NEXT_COMMAND_VALUE;
	return( s_idNextCommand++ );
}


/*-----------------------------------------------------------------------------
[名称]	検索オブジェクト取得
[機能]	検索オブジェクトの取得。
[戻値]	CFinder*	検索オブジェクト [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CFinder*	GetFinder(
	BOOL	bRegExp		// I  :正規表現必要性 [-] (TRUE:正規表現エンジン、FALSE:正規表現エンジンでない) :-
)
{
	static CFinderDefault	FinderDefault;
	static CFinderBREGEXP	FinderBREGEXP;
	static CFinderVBScript	FinderVBScript;

	if( bRegExp )
	{
		CBregPool*	pBRegPool = CBregPool::GetInstance();
		if ( pBRegPool->IsAlive() )
		{
			return( &FinderBREGEXP );
		}
		else
		{
			return( &FinderVBScript );
		}
	}
	else
	{
		return( &FinderDefault );
	}

}


/*-----------------------------------------------------------------------------
[名称]	強調表示背景色取得
[機能]	強調表示の背景色を取得。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
COLORREF GetBackColor(
	int idxColor	// I  :強調表示番号 [-] (-)
)
{
	CEmphasisItem&	Emphasis = CGeneralSetting::GetInstance()->GetEmphasisDefine()->GetItemz()[idxColor];
	return(
		Emphasis.GetBackColor()
	);
}


/*-----------------------------------------------------------------------------
[名称]	強調表示前景色取得
[機能]	強調表示の前景色を取得。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
COLORREF GetForeColor(
	int idxColor	// I  :強調表示番号 [-] (-)
)
{
	CEmphasisItem&	Emphasis = CGeneralSetting::GetInstance()->GetEmphasisDefine()->GetItemz()[idxColor];

	return(
		Emphasis.GetForeColor()
	);
}


/*-----------------------------------------------------------------------------
[名称]	ドキュメント設定
[機能]	アプリケーションで使用するドキュメントを設定する。
[戻値]	なし
[備考]	GetDocument()で取得するため。
-----------------------------------------------------------------------------*/
static CShitarabianDoc*	f_pDocument = NULL;
void SetDocument( CShitarabianDoc* pDocument )
{
	f_pDocument = pDocument;
}


/*-----------------------------------------------------------------------------
[名称]	ドキュメント取得
[機能]	ドキュメントを取得する。
[戻値]	CShitarabianDoc*	ドキュメント [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CShitarabianDoc* GetDocument()
{
	if ( f_pDocument != NULL )
	{
		return( f_pDocument );
	}

	ASSERT( FALSE );
	CShitarabianDoc*	pDoc;
	pDoc = (CShitarabianDoc*)(GetMainFrame()->GetDocument());
	return( pDoc );
}


/*-----------------------------------------------------------------------------
[名称]	文字列のカラム位置→バイト位置
[機能]	文字列の文字列のカラム位置からバイト位置を取得する。
[戻値]	long	バイト位置 [-] (-)
[備考]	ShiftJis。
-----------------------------------------------------------------------------*/
long CaretColumnToByteColumn(
	const char*		pstrSrc,	// I  :文字列 [マルチバイト] (-) :-
	long			idxChar		// I  :カラム位置 [-] (-) :-
)
{
	long	idxByte = 0;

	while( *pstrSrc != NULL )
	{
		if ( idxChar == 0 )
		{
			break;
		}

		// マルチバイト判別
		int	iByteSize;
		if ( _istleadbyte( *pstrSrc ) != 0 )
		{
			iByteSize = 2;
		}
		else
		{
			iByteSize = 1;
		}

		idxByte += iByteSize;
		pstrSrc += iByteSize;
		idxChar--;
	}

	return( idxByte );
}


/*-----------------------------------------------------------------------------
[名称]	文字列のバイト位置→カラム位置
[機能]	文字列の文字列のバイト位置からカラム位置を取得する。
[戻値]	long	カラム位置 [-] (-)
[備考]	ShiftJis。
-----------------------------------------------------------------------------*/
// 文字列のバイト位置→文字位置
long ByteColumnToCaretColumn(
	const char*		pstrSrc,	// I  :文字列 [ShiftJis] (-) :-
	long			idxByte		// I  :バイト位置 [-] (-) :-
)
{
	long	idxChar = 0;

	while( *pstrSrc != NULL )
	{
		if ( idxByte <= 0 )
		{
			break;
		}

		// マルチバイト判別
		int	iByteSize;
		if ( _istleadbyte( *pstrSrc ) != 0 )
		{
			iByteSize = 2;
		}
		else
		{
			iByteSize = 1;
		}

		idxChar ++;
		pstrSrc += iByteSize;
		idxByte -= iByteSize;
	}

	return( idxChar );
}


/*-----------------------------------------------------------------------------
[名称]	カラム数取得
[機能]	文字列の総カラム数を取得する。
[戻値]	long	カラム数 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
long	StringToColumn(
	const char*		pstrSrc		// I  :文字列 [マルチバイト判別] (-) :-
)
{
	long	idxChar = 0;

	while( *pstrSrc != 0x00 )
	{
		int		iByteSize = 0;

		// マルチバイト判別
		if ( iByteSize == 0 )
		if ( _istleadbyte( *pstrSrc ) != 0 )
		{
			iByteSize = 2;
		}
		else
		{
			iByteSize = 1;
		}

		idxChar ++;
		pstrSrc += iByteSize;
	}

	return( idxChar );

}


/*-----------------------------------------------------------------------------
[名称]	クリップボードコピー
[機能]	文字列をクリップボードへ出力する。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
// ▼ (3204) BGN 2004.05.12 (moralog) ExeCommon.cppから移動。汎用関数化。
void EditCopyStringWithHistory(
// ▽ original BGN
//void EditCopyString(
// △ original END
// ▲ (3204) END
	CString&	strCopySrc	// I  :コピー元文字列 [-] (-) :-
) 
{
	if ( !strCopySrc.IsEmpty() )
	if ( ::OpenClipboard( NULL ) )
	{
// ▼ (3204) BGN 2004.05.12 (moralog) ExeCommon.cppから移動。汎用関数化。
		::EditCopyString( strCopySrc );
/*
// ▽ original BGN

		long	nChar = strCopySrc.GetLength();
		HGLOBAL hGMem = NULL;
		hGMem = ::GlobalAlloc(
			GHND,// | GMEM_DDESHARE,
			sizeof(TCHAR)*( nChar+2 )
		);
		if ( hGMem == NULL )
		{
			PrintLastErr("::GlobalAlloc");
		}

		TCHAR* psz = (TCHAR*)::GlobalLock(hGMem);
		void* p = ::lstrcpy( psz, (LPCTSTR)strCopySrc );
		if ( p == NULL )
		{
			PrintLastErr("::lstrcpy");
		}
		BOOL	b = ::GlobalUnlock(hGMem);
		if ( !b )
		{
			PrintLastErr("::GlobalUnlock");
		}

		BOOL	bEmpty = ::EmptyClipboard();
		if ( !bEmpty )
		{
			PrintLastErr("::EmptyClipboard");
		}

		HANDLE	h = ::SetClipboardData(CF_TEXT, hGMem);
		if ( h == NULL )
		{
			PrintLastErr("::SetClipboardData");
		}
		BOOL	bSuccess = ::CloseClipboard();
		if ( !bSuccess )
		{
			PrintLastErr("::SetClipboardData");
		}
// △ original END
*/
// ▲ (3204) END

		// クリップボード履歴へ登録
		CClipHistory::GetInstance()->AddHistory( strCopySrc );
	}
}

// ▼ (3632) BGN 2003.12.28 (moralog) バージョン管理方法変更
/*-----------------------------------------------------------------------------
[名称]	文字列→バージョン取得
[機能]	バージョンの取得。
[戻値]	long	バージョン番号 [-] (0:エラー)
[備考]	バージョン文字列は　ＸＸ_YYMMDDr
		例：β４_031228b
-----------------------------------------------------------------------------*/
long	StringToVersion(
	CString&	strVersion
)
{
	// 特別処理
	{
// ▼ (3632) BGN 2003.12.28 (moralog) バージョン管理方法変更
// ▽ original BGN
//		// b031228のバージョン文字列の記述ミスに対応
//		if ( strVersion == _T("β４_0301228") )
// △ original END
		// b031228以前のバージョン文字列の記述ミスに対応
		if ( ::GetNumeric( strVersion ) > 0200000 )
// ▲ (3632) END
		{
			return( 31228 );
		}
	}

	long	posSeparater = strVersion.Find( _T("_"), 0 );
	if ( posSeparater >= 0 )
	{
		CString		str = (LPCTSTR)strVersion + posSeparater;
		return( ::GetNumeric( str ) );

	}
	return( 0 );
}
// ▲ (3632) END

// ▼ (3204) BGN 2004.05.10 (moralog) ランチャツールバー追加
void DrawIcon(
	CDC*		pDC,
	CRect		rcDst,
	CString		strIconFilePath,
	long		idxIcon
) 
{
	// 実行ファイルからアイコンを読み出す
	HICON	hIconL( NULL );
	UINT ui = 0;

	if ( !strIconFilePath.IsEmpty() )
	{
		ui = ::ExtractIconEx( 
		  strIconFilePath,	// ファイル名 
		  idxIcon,			// アイコンのインデックス番号 
		  &hIconL,			// 大きいアイコンの配列 
		  NULL,				// 小さいアイコンの配列 
		  1					// 抽出対象のアイコンの数 
		);
	}

	if ( ui == 0 )
	{
		switch ( idxIcon )
		{
		case 0:
			hIconL = theApp.LoadIcon( IDI_TYPE01 );	// 昔のしたらばくん
			break;
		case 1:
			hIconL = theApp.LoadIcon( IDI_TYPE02 );	// 昔のしたらばファイル
			break;
		case 2:
			hIconL = theApp.LoadIcon( IDI_TYPE03 );	// プラグイン
			break;
		case 3:
			hIconL = theApp.LoadIcon( IDR_SHITARTYPE );	// 文書
			break;
// ▼ (3204) BGN 2004.06.09 (moralog) アイコン追加
		case 4:
			hIconL = theApp.LoadIcon( IDI_TYPE04 );		// へぼりー
			break;
// ▲ (3204) END
		default:
			hIconL = theApp.LoadIcon( IDR_MAINFRAME );	// したらばくん
			break;
		}
	}

	pDC->SetMapMode( MM_TEXT );

	::DrawIconEx(
		pDC->m_hDC,
		rcDst.left, rcDst.top,
		hIconL,
		rcDst.Width(),
		rcDst.Height(),
		0,
		NULL,
		DI_NORMAL
	);

	if ( ui > 0 )
	{
		// 取得したアイコンの破棄
		::DestroyIcon( hIconL );
	}
}
// ▲ (3204) END