//********************************************************************************************
/**
 * @file		swriter.cpp
 * @brief		要約説明
 *
 *	他ツールでソースを自動書き換えするので極力余計な物を外へ逃がしてある
 *	
 *		AddFunc ツールで機能を追加するので▲マークは消さない事
 *
 * @author		N.Takeda
 */
//********************************************************************************************
#include "main.h"

#include <commctrl.h>
#include <mbstring.h>
#include <process.h>

#include "params.h"		///<	引数管理クラス


/// 範囲限定制御クラス.
CRANGE_CTRL	cRange;


#define		NO_SUCCEMESS				///< 有効にすると内臓マクロで逐一成功メッセージの表示をしない

#define		QUIT(class)				if( class != NULL)	class->Quit( _bExit )
#define		CHECK_LOOPOVER(max)		if(ii==s_stGl.old_i){if(++s_stGl.iLimitCnt>max){Message_error(TEXT("ERROR : loop over"));s_stGl.err=1;break;}}s_stGl.old_i=ii


///	変換モジュール　includeをコメントアウトするだけで実装解除される.
	///	内蔵	ワンタッチ機能からも呼べる物、パラメータなしで使える事が必須(パメータ固定でも可).
	#include "module\_common.cpp"
	///	標準	基本マニュアルに載るべき機能.
	#include "module\replace.cpp"
	#include "module\listupparam.cpp"
	#include "module\listupscr.cpp"
	#include "module\checktxt.cpp"
	#include "module\togeGrep.cpp"		///< まとめてGREP.

	///	固有	用途が限定されるが割と使える機能.
	#include "module\bmp_resize.cpp"
	#include "module\fitparts.cpp"
	#include "module\checkscr.cpp"
//	#include "module\kinsoku.cpp"			//★作成中
//	#include "module\renewfiles.cpp"	///< ２つのフォルダを比較し、更新されているファイルを抽出. バージョン管理ソフトの登場以来あまり用途はない.

///	おそらく２度は使わないような機能、または作成、テスト中など.
//▲1
#include "module\SongDataConvert.cpp"	///< 歌詞大データコンバータ
#include "module\smpl_chain.cpp"	///< ファイル連結
#include "module\rlsPress.cpp"	///< RLS圧縮
#include "module\smpl_d2pack.cpp"	///< D2Cパックデータ作成
#include "module\smpl_d2atex.cpp"	///< 幕末用 d2aテクスチャ名変更
#include "module\smpl_d2arc.cpp"	///< D2アーカイバ
#include "module\makemask.cpp"	///< BMPをchaosで使用するマスクデータにコンバートする
#include "module\xls2csv.cpp"			///< エクセルファイルをcsvに展開
#include "module\initSample.cpp"		///< 初期化順確認用
#include "module\checkExcel.cpp"		///< エクセルシートを誤植検索
//#include "module\utter_scr.cpp"				//★テスト中
#include "module\utter.cpp"					//★テスト中
#include "module\function_base.cpp"		///< 基本モジュール.



//********************************************************************************************
/**
 * @brief		変換終了　開放時に呼ばれるのではないので注意.
 *				開放はwindowsアプリ終了に任せている.
 * @author		N.Takeda
 *
 * @param[in]	BOOL	_bExit	まだ次のスクリプトがある場合 FALSEがセットされてくる
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	swriter_exit( BOOL _bExit )
{
	
	//▲2
#ifdef	SW_MODULE_SONGDATACONVERT
	QUIT( pC_SongDataConvert );
#endif
#ifdef	SW_MODULE_SMPL_CHAIN
	QUIT( pC_smpl_chain );
#endif
#ifdef	SW_MODULE_RLSPRESS
	QUIT( pC_rlsPress );
#endif
#ifdef	SW_MODULE_SMPL_D2PACK
	QUIT( pC_smpl_d2pack );
#endif
#ifdef	SW_MODULE_SMPL_D2ATEX
	QUIT( pC_smpl_d2atex );
#endif
#ifdef	SW_MODULE_SMPL_D2ARC
	QUIT( pC_smpl_d2arc );
#endif
#ifdef	SW_MODULE_MAKEMASK
	QUIT( pC_makemask );
#endif
#ifdef	SW_MODULE_XLS2CSV
	QUIT( pC_xls2csv );
#endif
#ifdef	SW_MODULE_INITSAMPLE
	QUIT( pC_initSample );
#endif
#ifdef	SW_MODULE_CHECKEXCEL
	QUIT( pC_checkExcel );
#endif
#ifdef	SW_MODULE_UTTER_SCR
	QUIT( pC_utter_scr );
#endif
#ifdef	SW_MODULE_UTTER
	QUIT( pC_utter );
#endif
#ifdef	SW_MODULE_KINSOKU
	QUIT( pC_kinsoku );
#endif
#ifdef	SW_MODULE_FUNCTION_BASE
	QUIT( pC_function_base );		///< 基本関数.
#endif
	
	///標準
#ifdef	SW_MODULE_LISTUPSCR
	QUIT( pC_listupscr );
#endif
#ifdef	SW_MODULE_LISTUPPARAM
	QUIT( pC_listupparam );
#endif
#ifdef	SW_MODULE_CHECKTXT
	QUIT( pC_checktxt );			///< テキストチェック.
#endif
#ifdef	SW_MODULE_REPLACE
	QUIT( pC_Rep );					///< 置換
#endif
#ifdef	SW_MODULE_TOGEGREP
	QUIT( pC_togeGrep );
#endif


	///固有
#ifdef	SW_MODULE_FITPARTS
	QUIT( pC_fparts );
#endif
#ifdef	SW_MODULE_CHECKSCR
	QUIT( pC_checkscr );
#endif
#ifdef	SW_MODULE_RENEWFILES
	QUIT( pC_renewfiles );			///< 更新ファイル比較.
#endif


#ifdef	SW_MODULE_COMMON
	///	内蔵機能
	common_quit( _bExit );
#endif
}


//********************************************************************************************
/**
* @brief		変換メインルーチン.
*				タイマーから呼ばれる
* @author		N.Takeda
*
* @param[in]	SCRIPT_STAT	_stSStat	.
* @param[in]	LPCTSTR		_pPath		.
*
* @return		なし (none)
*/
//********************************************************************************************
void	swriter_cmd( SCRIPT_STAT _stSStat, LPCTSTR _pPath )
{
	#define		COMMAND_LENGTH	(32)
	#define		PARAM_LENGTH	(1024)
	#define		CREATE(classname,funcname)	if( funcname == NULL ){	funcname = new classname; }\
											if( funcname == NULL ){	Message_error(TEXT("スクリプトの実行に失敗しました"));break;}
	#define		ADD_PARAM(_Param)			{STRING_cat( sParamString, TEXT(" ") );STRING_cat( sParamString, _Param );}
	
	/// sCmd文字列 と 下のenum 順は対応している必要がある
	TCHAR	sCmd[][ COMMAND_LENGTH ] =	///< コマンド文字列(大文字のみ)
	{
		TEXT("COPY"),
		TEXT("DEL"),
		TEXT("DELREM"),
		TEXT("KANJI_CHECK"),
		TEXT("ZEN2HAN"),
		TEXT("REPLACE"),
		TEXT("REPLACE_REM"),
		TEXT("REPLACE_REGEX"),
		TEXT("TOGEGREP"),
		TEXT("LISTUPPARAM"),
		TEXT("LISTSORT"),
		TEXT("FILECHECK"),
		TEXT("BMP_RESIZE"),
		TEXT("FITPARTS"),
		TEXT("FITPARTS_REV"),
		TEXT("DUMP"),
		TEXT("LISTUPSCR"),
		TEXT("CHECKSCR"),
		TEXT("CHECKTXT"),
		TEXT("KINSOKU"),
		TEXT("SAMESIZE"),
		TEXT("RENEWFILES"),
		TEXT("CHGRW"),
		//▲3
		TEXT("SONGDATACONVERT"),
		TEXT("CHAIN"),
		TEXT("RLSPRESS"),
		TEXT("D2PACK"),
		TEXT("D2ATEX"),
		TEXT("D2ARC"),
		TEXT("MAKEMASK"),
		TEXT("XLS2CSV"),
		TEXT("INITSAMPLE"),
		TEXT("CHECKEXCEL"),
		TEXT("UTTER_SCR"),
		TEXT("UTTER"),
		TEXT("FUNCTION_BASE"),
	};
	enum{
		enCom_filecopy,
		enCom_filedel,
		enCom_delrem,
		enCom_kanji_check,
		enCom_zen2han,
		enCom_replace,
		enCom_replace_rem,
		enCom_replace_regex,
		enCom_togeGrep,
		enCom_listupparam,
		enCom_list_sort,
		enCom_filecheck,
		enCom_bmp_resize,
		enCom_fitparts,
		enCom_fitparts_rev,
		enCom_dump,
		enCom_listupscr,
		enCom_checkscr,
		enCom_checktxt,
		enCom_kinsoku,
		enCom_samesize,
		enCom_renewfiles,
		enCom_chgrw,
		//▲4
		enCom_SongDataConvert,
		enCom_smpl_chain,
		enCom_rlsPress,
		enCom_smpl_d2pack,
		enCom_smpl_d2atex,
		enCom_smpl_d2arc,
		enCom_makemask,
		enCom_xls2csv,
		enCom_initSample,
		enCom_checkExcel,
		enCom_utter_scr,
		enCom_utter,
		enCom_function_base,
		enCom_Max
	};
	
	/// 共用変数.
	int		iIdx;
	BOOL	bSuccess = FALSE;														///< 成功か.
	TCHAR	sParamString[ PARAM_LENGTH ] = TEXT("");
	
	
	s_stGl.old_i = -1;
	s_stGl.iLimitCnt = 0;
	
	///	スクリプトコマンドインデックス取得.
	for( iIdx=0 ; iIdx < enCom_Max ; iIdx++ )
	{
		if( STRING_cmp( sCmd[ iIdx ], _stSStat.sCommand.c_str() ) == 0 )	break;
	}
	
	if( PARAM_LENGTH <= (STRING_len( _pPath ) + STRING_len( _stSStat.sParam.c_str() ) + 1) )
	{
		Message_error( TEXT("パラメータが長すぎます. \"%s\""), _stSStat.sParam.c_str() );	///< エラー.
		return;
	}
#if 1
	STRING_printf( sParamString, PARAM_LENGTH, TEXT("\"%s\""), _pPath );
#else
	STRING_cpy( sParamString, _pPath );
#endif
	ADD_PARAM( _stSStat.sParam.c_str() );
	
	
	switch( iIdx )
	{
		//追加モジュール
		//▲5
#ifdef	SW_MODULE_SONGDATACONVERT
		case enCom_SongDataConvert:	///< 歌詞大データコンバータ
			CREATE( SONGDATACONVERT, pC_SongDataConvert );
			pC_SongDataConvert->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_SMPL_CHAIN
		case enCom_smpl_chain:	///< ファイル連結
			CREATE( SMPL_CHAIN, pC_smpl_chain );
			pC_smpl_chain->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_RLSPRESS
		case enCom_rlsPress:	///< RLS圧縮
			CREATE( RLSPRESS, pC_rlsPress );
			pC_rlsPress->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_SMPL_D2PACK
		case enCom_smpl_d2pack:	///< D2Cパックデータ作成
			CREATE( SMPL_D2PACK, pC_smpl_d2pack );
			pC_smpl_d2pack->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_SMPL_D2ATEX
		case enCom_smpl_d2atex:	///< 幕末用 d2aテクスチャ名変更
			CREATE( SMPL_D2ATEX, pC_smpl_d2atex );
			pC_smpl_d2atex->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_SMPL_D2ARC
		case enCom_smpl_d2arc:	///< D2アーカイバ
			CREATE( SMPL_D2ARC, pC_smpl_d2arc );
			pC_smpl_d2arc->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_MAKEMASK
		case enCom_makemask:	///< BMPをchaosで使用するマスクデータにコンバートする
			CREATE( MAKEMASK, pC_makemask );
			pC_makemask->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_XLS2CSV
		case enCom_xls2csv:	///< エクセルファイルをcsvに展開
			CREATE( XLS2CSV, pC_xls2csv );
			pC_xls2csv->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_INITSAMPLE
		case enCom_initSample:	///< 初期化順確認用
			CREATE( INITSAMPLE, pC_initSample );
			pC_initSample->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_CHECKEXCEL
		case enCom_checkExcel:	///< エクセルシートを誤植検索
			CREATE( CHECKEXCEL, pC_checkExcel );
			pC_checkExcel->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_UTTER_SCR
		case enCom_utter_scr:														///< WAVデータの音量レベルをデータ化しSCR組み込み
			CREATE( UTTER_SCR, pC_utter_scr );
			bSuccess = pC_utter_scr->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_UTTER
		case enCom_utter:															///< WAVデータの音量レベルをデータ化
			CREATE( UTTER, pC_utter );
			bSuccess = pC_utter->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_FUNCTION_BASE
		case enCom_function_base:													///< ベースサンプル
			CREATE( FUNCTION_BASE, pC_function_base )
			bSuccess = pC_function_base->Func( sParamString );
			break;
#endif

#ifdef	SW_MODULE_COMMON
		/// 内蔵機能
		case enCom_filecopy:														///< ファイル／フォルダのコピー
			CREATE( FILECOPY, pC_filecopy );
			bSuccess = pC_filecopy->Func( sParamString );
			break;
		case enCom_filedel:															///< ファイルの削除
			if(msged_copy == 0){msged_copy=1;Message_win( TEXT("deleting") );}		///< 一回のみ表示
			bSuccess = file_del(_pPath);
			if( bSuccess == 0 )	Message_printf( TEXT("del failed. %s"), pickup_name(_pPath) );
		#ifndef	NO_SUCCEMESS
			else				Message_printf( TEXT("del %s"), pickup_name(_pPath));
		#endif
			break;
		
		case enCom_delrem:															///< 注釈削除
			if(msged_defrem == 0){msged_defrem=1;Message_win( TEXT("delrem") );}	///< 一回のみ表示
			bSuccess = delete_rem( sParamString );
			if( bSuccess == 0)	Message_printf( TEXT("delrem failed. %s"), pickup_name(_pPath) );
		#ifndef	NO_SUCCEMESS
			else				Message_printf( TEXT("delrem %s"), pickup_name(_pPath) );
		#endif
			break;
		
		case enCom_kanji_check:
			CREATE( KANJI_CHECK, pC_kchk )
			bSuccess = pC_kchk->Func( sParamString );
			break;
		case enCom_zen2han:
			bSuccess = filt_zen2han( sParamString );
			break;
		case enCom_list_sort:
			CREATE( LIST_SORT, pC_listsort )
			bSuccess = pC_listsort->Func( sParamString );
			break;
		case enCom_filecheck:
			CREATE( FILECHECK, pC_filecheck );
			bSuccess = pC_filecheck->Func( sParamString );
			break;
		case enCom_dump:
			CREATE( DUMP, pC_dump );
			bSuccess = pC_dump->Func( sParamString );
			break;
		case enCom_samesize:														///< ファイルサイズを最大の物に揃える
			CREATE( SAMESIZE, pC_samesize );
			bSuccess = pC_samesize->Func( sParamString );
			break;
		case enCom_chgrw:															///< ファイル書き込み属性操作
			CREATE( CHGRW, pC_chgrw );
			bSuccess = pC_chgrw->Func( sParamString );
			break;
#endif
		/// 標準固有機能.
#ifdef	SW_MODULE_REPLACE
		case enCom_replace:
			ADD_PARAM( TEXT("-m0") );
			
			CREATE( REPLASE, pC_Rep );
			bSuccess = pC_Rep->Func( sParamString );
			break;
		case enCom_replace_rem:
			ADD_PARAM( TEXT("-m1") );
			
			CREATE( REPLASE, pC_Rep );
			bSuccess = pC_Rep->Func( sParamString );
			break;
		
		case enCom_replace_regex:
			ADD_PARAM( TEXT("-m2") );
			
			CREATE( REPLASE, pC_Rep );
			bSuccess = pC_Rep->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_TOGEGREP
		case enCom_togeGrep:														///< まとめてGREP
			CREATE( TOGEGREP, pC_togeGrep );
			bSuccess = pC_togeGrep->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_LISTUPPARAM
		case enCom_listupparam:
			CREATE( LISTUP_PARAM, pC_listupparam );
			bSuccess = pC_listupparam->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_RESIZE
		case enCom_bmp_resize:
			bSuccess = bmprs.Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_FITPARTS
		case enCom_fitparts:
			CREATE( FITPARTS, pC_fparts );
			bSuccess = pC_fparts->Func( sParamString );
			break;
		
		case enCom_fitparts_rev:
			CREATE( FITPARTS, pC_fparts );
			bSuccess = pC_fparts->func_rev( sParamString );
			break;
#endif
#ifdef	SW_MODULE_LISTUPSCR
		case enCom_listupscr:														///< スクリプトリストアップ
			CREATE( LISTUPSCR, pC_listupscr );
			bSuccess = pC_listupscr->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_CHECKSCR
		case enCom_checkscr:														///< スクリプトチェック
			CREATE( CHECKSCR, pC_checkscr );
			bSuccess = pC_checkscr->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_CHECKTXT
		case enCom_checktxt:														///< 誤植検索
			CREATE( CHECKTXT, pC_checktxt );
			bSuccess = pC_checktxt->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_KINSOKU
		case enCom_kinsoku:															///< 禁則処理
			CREATE( KINSOKU, pC_kinsoku );
			bSuccess = pC_kinsoku->Func( sParamString );
			break;
#endif
#ifdef	SW_MODULE_RENEWFILES
		case enCom_renewfiles:														///< renewfiles
			CREATE( RENEWFILES, pC_renewfiles );
			bSuccess = pC_renewfiles->Func( sParamString );
			break;
#endif
		
		default:																	///< 外部モジュール
			if( iIdx < enCom_Max )
			{
				Message_printf( TEXT("%s この機能は組み込まれていません"), sCmd[ iIdx ] );
				break;
			}
			string::size_type	ii = _stSStat.sParam.find( TEXT("%1") );
			if( ii == string::npos )
			{
				bSuccess = swriter_ExecModule( _stSStat.sCommand.c_str(), sParamString );
			}else{
				//! %1 識別子が含まれる.
				xstring	String2 = TEXT("%1");
				
				std::string::size_type  Pos( _stSStat.sParam.find( String2 ) );
				while( Pos != std::string::npos )
				{
					_stSStat.sParam.replace( Pos, String2.length(), _pPath );
					Pos = _stSStat.sParam.find( String2, Pos + STRING_len(_pPath) );
				}
				
				bSuccess = swriter_ExecModule( _stSStat.sCommand.c_str(), _stSStat.sParam.c_str() );
			}
			break;
	}
	
	
	if( !bSuccess )
	{
		;///< 現在特に失敗時の処理は無し.
	}
	
}

