//==============================================================================================================================
//	renewfiles
//
//	２つのフォルダを比較し、更新されているファイルを抽出
//==============================================================================================================================
#define	SW_MODULE_RENEWFILES

//------------------------------------------------------------------
//		スクリプトコマンドクラス
//------------------------------------------------------------------
class RENEWFILES{
	
	BOOL		m_bInitialized;
	BOOL		m_bImplemented;
	BOOL		m_FullInit;
	
	void		Initialize( LPCTSTR oldpath, LPCTSTR updatepath );
	
	int			mode;
	TCHAR		listname[_MAX_PATH];
	char		*m_pListMem;
	int			m_iListLen;
	
	int			newfiles;
public:
	int			Func( CPARAMS cParams );
//	int			Func(char *path,char *oldpath,char *updaetpath);
	void		Quit( BOOL _bExit );
	
	RENEWFILES();
	~RENEWFILES();
	
};

//	アプリケーション起動時
RENEWFILES::RENEWFILES(){
		m_FullInit = FALSE;
		m_bInitialized = FALSE;
		m_bImplemented = FALSE;
}
//	アプリケーション終了時
RENEWFILES::~RENEWFILES(){
}


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

//------------------------------------------------------------------
//		スクリプトコマンドの初期化
//			(特に必要ないなら変更の必要なし)
//------------------------------------------------------------------
void	RENEWFILES::Initialize( LPCTSTR oldpath, LPCTSTR updatepath )
{
		
		if(m_bInitialized == TRUE)	return;
		m_bInitialized = TRUE;	//	初期済みフラグ
		
		if(m_FullInit == FALSE){
			m_FullInit = TRUE;
			//	全体を通して一度しか行わない初期化
			
			//Message_printf("全体の初期化");
			
			mode = 0;
			if(STRING_str( updatepath, TEXT(".") ) != NULL){
				//	書き出しモード
				STRING_cpy( listname, updatepath );
				FILE_delete( listname );
				mode = 1;
			}else if(STRING_str( oldpath, TEXT(".") ) != NULL){
				//	読み込みモード
				mode = 2;
				m_pListMem = NULL;
				m_iListLen = MEM_TargetRead( &m_pListMem, oldpath );
				if( m_iListLen == 0 ){
					Message_error( TEXT("file not found:%s"), oldpath );
					mode = 0;
				}
			}
			newfiles = 0;
		}
		
		//	初期化処理
		//	１つのバッチに同じスクリプトが２度指定されていたならここには２度来る
		//Message_printf("初期化");
		
		
}

//------------------------------------------------------------------
//		スクリプトコマンドの終了
//			(特に必要ないなら変更の必要なし)
//------------------------------------------------------------------
void	RENEWFILES::Quit( BOOL _bExit )
{
		int		ii;
		
		//	ここにはスクリプトを使っていなくても来るので注意
		
		if(m_bImplemented == FALSE)	return;		//	変換処理が実行されていないなら帰還
		m_bImplemented = FALSE;
		m_bInitialized = FALSE;
		
		//	終了処理
		//Message_printf("完了");
		
		if(et == 1){
			//	次のスクリプトは存在しない、完全な終了
			//	１つのバッチに同じスクリプトに別パラメータを渡しての処理で
			//	逐一結果を出さず、全体で統合して結果を出したい場合などはここで
			
			//Message_printf("終了");
			
			if(mode == 1){
				int		zero = 0;
				FILE_TargetWriteMerge( listname, &zero, sizeof(int) );
			}
			if(mode == 2){
				
				for(ii=0 ; ii<m_iListLen-4 ; ii++){
					ii++;
					if(*(m_pListMem+ii-1) == 0){
						Message_printf( TEXT("削除されたファイル:%s"), (m_pListMem+ii) );
					}
					ii += STRING_len(m_pListMem+ii);	//forで +1 されるのでここで帳尻を合わせる
					ii += sizeof(FILETIME);
				}
				
				mem_del(m_pListMem);
			}
			
			if(mode != 1)
				Message_printf( TEXT("%d renewfile(s)."), newfiles );
			
		}
		
}







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

#define	RENEWFILES_RANGE				//	このdefineを有効にすると範囲限定機能が有効になる

//------------------------------------------------------------------
//	変換フィルターサンプル　機能:無変換(ファイルコピー)
//------------------------------------------------------------------
int		RENEWFILES::Func( CPARAMS cParams ){
		TCHAR		drive[_MAX_DRIVE],dir[_MAX_DIR],name[_MAX_FNAME],ext[_MAX_EXT],temp[_MAX_PATH],path2[_MAX_PATH];
		char		*mem=NULL;
		char		*ptr_flg;
		int			ii, len;
		HANDLE		hFile;
		FILETIME	*pFileTime;
		FILETIME	ftFileTime_new;
		FILETIME	ftFileTime_old;
		LPCTSTR		sPath;
		LPCTSTR		sOldPath;
		LPCTSTR		sUpdatePath;
		
		sPath       = cParams.GetPath();		///< ターゲットファイル (GetFilePath(0)としても同じ).
		sOldPath    = cParams.GetString(1);
		sUpdatePath = cParams.GetString(2);
		
		
		Initialize( sOldPath, sUpdatePath );
		
		m_bImplemented = TRUE;	//	実行済みフラグ
		
		
		FILE_split( sPath, drive, dir, name, ext );
		STRING_cpy( temp, sOldPath );
		
		for(ii=0 ; ii<STRING_len(dir) ; ii++)	if(*(dir+ii)=='\\')	break;
		STRING_cat(temp,dir+ii);
		FILE_merge( path2, drive, temp, name, ext );
		
		
		hFile = CreateFile( sPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
		if (hFile == INVALID_HANDLE_VALUE) {
			//	error
			Message_error( TEXT("file not found:%s"), sPath );
			return FALSE;		//	ファイルがない
		}
		GetFileTime(hFile , NULL , NULL , &ftFileTime_new);
		CloseHandle(hFile);
		
		
		if(mode == 1){
			char	dmy = 0;
			
			FILE_TargetWriteMerge( listname, &dmy, 1 );		//	使用済みフラグ領域
			FILE_TargetWriteMerge( listname, sPath ,STRING_len(sPath) + 1 );
			FILE_TargetWriteMerge( listname, &ftFileTime_new, sizeof(FILETIME) );
			//	_printf("%-32s	%08x%08x\n",path,ftFileTime_new.dwHighDateTime,ftFileTime_new.dwLowDateTime);
			
			return 1;
		}
		
		
		ptr_flg = NULL;
		if(mode == 2)
		{
			for(ii=0 ; ii<m_iListLen ; ii++)
			{
				ptr_flg = (m_pListMem+ii);
				ii++;
				if( STRING_cmp( (m_pListMem+ii), sPath ) == 0 )
				{
					if( ptr_flg != NULL )	*ptr_flg = 1;
					ii += STRING_len(m_pListMem+ii) + 1;
					
					pFileTime = (FILETIME*)(m_pListMem+ii);
					ftFileTime_old.dwHighDateTime = pFileTime->dwHighDateTime;
					ftFileTime_old.dwLowDateTime = pFileTime->dwLowDateTime;
					//	_printf("%-32s	%08x%08x\n",path,ftFileTime_old.dwHighDateTime,ftFileTime_old.dwLowDateTime);
					break;
				}
				ii += STRING_len(m_pListMem+ii);	//forで +1 されるのでここで帳尻を合わせる
				ii += sizeof(FILETIME);
			}
			if(ii >= m_iListLen){
				Message_printf( TEXT("新規のファイル : %s"), pickup_name( sPath ));
				ftFileTime_old.dwHighDateTime = 0;
			}
		}else{
			hFile = CreateFile( path2, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
			if (hFile == INVALID_HANDLE_VALUE) {
				Message_printf( TEXT("新規のファイル : %s"), pickup_name(path2) );
				ftFileTime_old.dwHighDateTime = 0;
			}else{
				GetFileTime(hFile , NULL , NULL , &ftFileTime_old);
				CloseHandle(hFile);
			}
		}
		
		//	更新されているなら抽出
		if( ftFileTime_new.dwHighDateTime > ftFileTime_old.dwHighDateTime ||
			(ftFileTime_new.dwHighDateTime > ftFileTime_old.dwHighDateTime && ftFileTime_new.dwLowDateTime > ftFileTime_old.dwLowDateTime))
		{
			FILE_split( sPath, drive, dir, name, ext );
			STRING_cpy( temp, sUpdatePath );
			STRING_ToSmall( temp );	//	スクリプトは強制的に大文字になるので、小文字に変換
			
			for(ii=0 ; ii<STRING_len(dir) ; ii++)	if(*(dir+ii)=='\\')	break;
			STRING_cat(temp,dir+ii);
			FILE_merge( path2, drive, temp, name, ext );
			
			len = MEM_TargetRead( &mem, sPath );
			if(len == 0){
				//	エラーメッセージの表示　処理はMessage_printfと同じ、Message_errorを使用すると自動終了しなくなります
				Message_error( TEXT("file not found:%s"), sPath );
				return FALSE;		//	ファイルがない
			}
			
			file_targetwrite(path2,mem,len);
			mem_del(mem);
			
			
			//	日付もコピー
			hFile = CreateFile( path2, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
			if (hFile == INVALID_HANDLE_VALUE)
			{
				//	error
				Message_error( TEXT("file not found:%s"), path2 );
				return FALSE;		//	ファイルがない
			}
			SetFileTime( hFile, NULL, NULL, &ftFileTime_new );
			CloseHandle(hFile);
			
			Message_printf( TEXT("%s"), path2 );
			newfiles++;
		}
		
		return TRUE;
}


RENEWFILES	*pC_renewfiles = NULL;
