//********************************************************************************************
/**
 * @file		
 * @brief		
 *
 *	このファイルの詳細説明
 *
 * @date		新規作成.
 */
//********************************************************************************************

#define	SW_MODULE_FUNCTION_BASE						///< この機能を切り離したい時はコメントアウト.
#ifdef	SW_MODULE_FUNCTION_BASE


//********************************************************************************************
/**
 * @class		FUNCTION_BASE
 * @brief		スクリプトコマンドクラス.
 */
//********************************************************************************************
class FUNCTION_BASE
{
	BOOL		m_bInitialized;
	BOOL		m_bImplemented;
	BOOL		m_bFullInit;
	
	void		Initialize();
	
public:
	virtual int		Func( LPCTSTR _sParamString );
	virtual void	Quit( BOOL _bExit );
	
	FUNCTION_BASE();
	virtual ~FUNCTION_BASE();
	
};

//********************************************************************************************
/**
 * @brief		コンストラクタ.
 */
//********************************************************************************************
FUNCTION_BASE::FUNCTION_BASE()
	: m_bFullInit( FALSE )
	, m_bInitialized( FALSE )
	, m_bImplemented( FALSE )
{
	
}

//********************************************************************************************
/**
 * @brief		デストラクタ.
 */
//********************************************************************************************
FUNCTION_BASE::~FUNCTION_BASE()
{
	
}


//==============================================================================================================================================
/**
	初期化と開放.
		1ファイルに1つの処理でコンプリートするような場合は修正する必要ありません
		注釈となっている Message_printf を有効にして sample.swb を実行すると動きがよく分かると思います。
*/
//==============================================================================================================================================

//********************************************************************************************
/**
 * @brief		スクリプトコマンドの初期化.
 *				(特に必要ないなら変更の必要なし)
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	FUNCTION_BASE::Initialize()
{
	if( m_bInitialized == TRUE )	return;
	m_bInitialized = TRUE;	//	初期済みフラグ
	
	if( m_bFullInit == FALSE )
	{
		m_bFullInit = TRUE;
		//	全体を通して一度しか行わない初期化
		
		//Message_printf( TEXT("全体の初期化") );
		
	}
	
	//	初期化処理
	//	１つのバッチに同じスクリプトが２度指定されていたならここには２度来る
	//Message_printf( TEXT("初期化") );
	
}

//********************************************************************************************
/**
 * @brief		スクリプトコマンドの終了.
 *				(特に必要ないなら変更の必要なし)
 *
 * @param[in]	BOOL	_bExit	.
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	FUNCTION_BASE::Quit(BOOL _bExit)
{
	//	ここにはスクリプトを使っていなくても来るので注意
	
	if( m_bImplemented == FALSE )	return;		///<変換処理が実行されていないなら帰還.
	m_bImplemented = FALSE;
	m_bInitialized = FALSE;
	
	///	終了処理.
	//Message_printf( TEXT("終了") );
	
	if( _bExit == TRUE )
	{
		//	次のスクリプトは存在しない、完全な終了
		//	１つのバッチに同じスクリプトに別パラメータを渡しての処理で
		//	逐一結果を出さず、全体で統合して結果を出したい場合などはここで
		
		//Message_printf( TEXT("全体の終了") );
	}
	
}







//==============================================================================================================================================
//	変換処理部分
//==============================================================================================================================================

#define	FUNCTION_BASE_OUTAREA		2	///< 変換後の容量は仮に元の倍取っている　内容によって変更して下さい.
#define	FUNCTION_BASE_RANGE				///< このdefineを有効にすると範囲限定機能が有効になる.

//********************************************************************************************
/**
 * @brief	変換フィルターサンプル　機能:無変換
 *			テキストデータを取り扱うサンプル.
 *			関数内は patol.lib を使用したサンプルになっているが、中身は完全に別物に変えても問題ありません.
 *
 *			
 *
 * @param[in]	LPCTSTR	_sParamString	引数文字列  ターゲットファイル名 + スクリプトで指定する引数.
 *
 * @return		int	TRUE:成 / FALSE:否(デフォルト)
 */
//********************************************************************************************
int		FUNCTION_BASE::Func( LPCTSTR _sParamString )
{
	CSwbParam	cParam( _sParamString );							///< パラメータ処理.
	
	TCHAR	*pMem = NULL;
	TCHAR	*pOut = NULL;
	int		ii, jj, iSourceLength;
	LPCTSTR	szFileName, szOutName;
	
	
	/// 引数の取り出し.
	/**
	 * ターゲットファイル (GetString(0)としても同じ).
	 * swb ファイルでは指定しない、システムで付加される引数.
	 */
	szFileName = cParam.GetPath();
	
	/**
	 * 出力パスを取得. GetString(1)以降の最初に見つかったオプションでない文字列を得る.
	 * %0等の特殊記号は変換される. 引数が1つしかないなら GetFilePath(1) としても同じ.
	 * swb で引数として指定する文字列. 指定がなければGetPath()と同じ物が入る.
	 */
	szOutName  = cParam.GetOutPath();
	
//	if( cParam.IsParam( 2 ) )	iVal = cParam.GetInt( 2 );		///< 第2引数が存在するなら数値として取得.
	
	
	/// 機能の初期化.
	Initialize();
	
	
	/// 元データ読み込み(関数内部でpMemに領域を確保している).
	iSourceLength = MEM_TextRead( &pMem, szFileName );							///< UNICODEの場合 UTF16に変換されて読まれます.
	if( iSourceLength == 0 )
	{
		/** エラーメッセージの表示　処理はMessage_printfと同じ、Message_errorを使用すると自動終了しなくなります */
		Message_error( TEXT("file not found:%s"), szFileName );
		return FALSE;						///< ファイルがない.
	}
	
	m_bImplemented = TRUE;					///< 実行済みフラグon. これをonにしないとQuit()が実行されない.
	
	/// 変換後のデータバッファを確保	元データがあまりに小さい場合があるので最低1KBは確保.
	mem_alloc( TCHAR, pOut, ((iSourceLength*FUNCTION_BASE_OUTAREA+1023)/1024)*1024 );
	
	ii = 0;
	#ifdef	FUNCTION_BASE_RANGE
	cRange.Init( pMem, iSourceLength );						///< 範囲限定機能を有効にするにはこの初期化と.
	while( cRange.Is( pMem, ii, iSourceLength ) )	ii++;	///<  初回スキップ、下の[スキップ判定]が必要。スキップが必要な間trueが返りループしている.
	#endif
	
	
	/// 変換処理部分.
	jj = 0;
	while( ii < iSourceLength )
	{
		#ifdef	FUNCTION_BASE_RANGE
		while(cRange.Is( pMem, ii, iSourceLength ))	ii++;	///< スキップ判定.
		#endif
		
	#if	0
		/// 検索サンプル "TEST"文字列を検索し、TEST??? のように後に続く３文字を表示.
		if(STRING_str(pMem+ii, TEXT("TEST") ) != 0){
			char	cTemp[4];
			cTemp[0] = *(pMem+ii+4);
			cTemp[1] = *(pMem+ii+5);
			cTemp[2] = *(pMem+ii+6);
			cTemp[3] = 0;
			Message_printf( TEXT("検索テスト : %s"), cTemp );
		}
	#endif
		
#ifndef _UNICODE
		/// 変換処理 このサンプルではただコピーしているだけ(テキスト処理用に全角を区別してみた).
		if( _ismbblead(*(pMem+ii)) != 0 ){	///< 全角文字だ.
			
		//	if(_WCHAR(pMem+ii) == '「');		///< 全角文字判定例.
			
			*(pOut+jj++) = *(pMem+ii++);
			*(pOut+jj++) = *(pMem+ii++);
		}else
#endif
		{
			*(pOut+jj++) = *(pMem+ii++);
		}
		
		///※コピーしているだけなのでここでは書き込み先のバッファオーバーはみていません.
		
		CHECK_LOOPOVER(32000);	///< 無限ループ安全処理	引数で指定した回数 ii が更新されないとbreakして処理停止.
	}
	
	
	/// Infoメッセージ出力(改行コードは\r\n).
	Message_printf( TEXT("file:%s %s"), szFileName, szOutName );
	
	
	/// 変換された pOut を出力　　出力ファイル名はバッチで指定、特に指定されていなければ元と同じファイル名.
	{
		TCHAR	cDrive[_MAX_DRIVE], cDir[_MAX_DIR], cName[_MAX_FNAME], cExt[_MAX_EXT], szTemp[_MAX_PATH];
		
		FILE_split( szOutName, cDrive, cDir, cName, cExt );
	#if	1
		FILE_merge( szTemp, cDrive, cDir, cName, cExt );	///<ここでは分解した物をそのまま連結、拡張子等を変えたい時はここで.
	#else
		FILE_merge( szTemp, cDrive, cDir, cName, TEXT(".txt") );	///<拡張子を".txt"に変えるサンプル.
	#endif
		
		/// ファイル出力(同名が存在する時はバックアップが作成される).
		file_textwrite( szTemp, pOut );						///< UNICODEの場合 S-JISに戻して書き込み.
	}
	
	
	/// メモリを開放.
	del_alloc( pMem );
	del_alloc( pOut );
	
	return TRUE;
}


FUNCTION_BASE	*pC_function_base = NULL;

#endif	// SW_MODULE_FUNCTION_BASE
