//==============================================================================================================================
//	変換ルーチンベースプログラム
//==============================================================================================================================

#define	KANJI1BUFF_MAX		8000
#define	KANJIBUFF_MAX		1000
#define	KANJISUBBUFF_MAX	256


#ifdef	_UNICODE
		#define		_NUM(val)	(val)
#else
		#define		_NUM(val)	(val/2)
#endif

//		
class KANJI_CHECK{
	
	BOOL		m_bInitialized;
	BOOL		m_bImplemented;
	
	
	int			searchDouble( LPCTSTR _pPtr );
	BOOL		buffCheck( LPCTSTR ptr, LPCTSTR str );
	void		subtotal( LPCTSTR fname );
	
	TCHAR		*pKnjall1;			//	漢字保管用
	TCHAR		*pKnjall2;
	TCHAR		*pKnjallNEC;
	TCHAR		*pKnjallIBM;
	TCHAR		*pKnjallEXT;
	TCHAR		*pKnjsub2;
	TCHAR		*pKnjsubNEC;
	TCHAR		*pKnjsubIBM;
	TCHAR		*pKnjsubEXT;
	
	long		iLevel1;
	long		iLevel2;
	long		iLevel3;
	long		iLevel4;
	long		iLevel5;
	
	long		iTotalLevel1;
	long		iTotalLevel2;
	long		iTotalLevel3;
	long		iTotalLevel4;
	long		iTotalLevel5;
	
	
public:
	int			iConvLevel;		//	1:小計を表示
	
	BOOL		Initialize();
	int			Func( LPCTSTR _sParamString );
	void		Quit( BOOL _bExit );
	
	KANJI_CHECK();
	~KANJI_CHECK();
	
};


KANJI_CHECK::KANJI_CHECK()
	: m_bInitialized( FALSE )
	, m_bImplemented( FALSE )
	, pKnjall1( NULL )
	, pKnjall2( NULL )
	, pKnjallNEC( NULL )
	, pKnjallIBM( NULL )
	, pKnjallEXT( NULL )
	, pKnjsub2( NULL )
	, pKnjsubNEC( NULL )
	, pKnjsubIBM( NULL )
	, pKnjsubEXT( NULL )
	, iLevel1( 0 )
	, iLevel2( 0 )
	, iLevel3( 0 )
	, iLevel4( 0 )
	, iLevel5( 0 )
	, iTotalLevel1( 0 )
	, iTotalLevel2( 0 )
	, iTotalLevel3( 0 )
	, iTotalLevel4( 0 )
	, iTotalLevel5( 0 )
	, iConvLevel( 0 )
{
}
KANJI_CHECK::~KANJI_CHECK()
{
	
}


BOOL	KANJI_CHECK::Initialize()
{
	//	随時初期化する必要のある処理はここで
	
	if( m_bInitialized == TRUE )	return TRUE;
	m_bInitialized = TRUE;	//	初期済みフラグ
	
	//	一回だけ行う初期化はここで
	
	// 第1水準漢字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjall1, KANJI1BUFF_MAX );
	// 第2水準漢字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjall2, KANJIBUFF_MAX );
	// NEC選定IBM拡張文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjallNEC, KANJIBUFF_MAX );
	// IBM拡張文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjallIBM, KANJIBUFF_MAX );
	// 外字文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjallEXT, KANJIBUFF_MAX );
	
	// 第2水準漢字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjsub2, KANJISUBBUFF_MAX );
	// NEC選定IBM拡張文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjsubNEC, KANJISUBBUFF_MAX );
	// IBM拡張文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjsubIBM, KANJISUBBUFF_MAX );
	// 外字文字コードを保管するためのバッファ
	mem_alloc(TCHAR, pKnjsubEXT, KANJISUBBUFF_MAX );
	
	T_ASSERT( NULL != pKnjall1 );
	T_ASSERT( NULL != pKnjall2 );
	T_ASSERT( NULL != pKnjallNEC );
	T_ASSERT( NULL != pKnjallIBM );
	T_ASSERT( NULL != pKnjallEXT );
	T_ASSERT( NULL != pKnjsub2 );
	T_ASSERT( NULL != pKnjsubNEC );
	T_ASSERT( NULL != pKnjsubIBM );
	T_ASSERT( NULL != pKnjsubEXT );
	if( NULL == pKnjall1 || NULL == pKnjall2 || NULL == pKnjallNEC || NULL == pKnjallIBM || NULL == pKnjallEXT
	 || NULL == pKnjsub2 || NULL == pKnjsubNEC || NULL == pKnjsubIBM || NULL == pKnjsubEXT )	return FALSE;
	
	*pKnjall1 = *pKnjall2 = *pKnjallNEC = *pKnjallIBM = *pKnjallEXT = 
	*pKnjsub2 = *pKnjsubNEC = *pKnjsubIBM = *pKnjsubEXT = '\0';
	
	iLevel1 = iLevel2 = iLevel3 = iLevel4 = iLevel5 = 
	iTotalLevel1 = iTotalLevel2 = iTotalLevel3 = iTotalLevel4 = iTotalLevel5 = 0;
	
	return TRUE;
}

//		
void	KANJI_CHECK::Quit( BOOL _bExit )
{
	if( m_bImplemented == FALSE)	return;
	m_bImplemented = FALSE;
	m_bInitialized = FALSE;
	//	終了処理は変換処理が実行された場合のみ行う
	
	
	Message_win( TEXT("\r\n---TOTAL---") );
//	Message_printf( "第1水準漢字    = %dｹ所",iTotalLevel1 );
	
	if(iTotalLevel1 > 0)
	{
		if( STRING_len( pKnjall1 ) == 0){
			Message_printf( TEXT("第1水準漢字    = %dｹ所"), iTotalLevel1 );
		}else{
			Message_printf( TEXT("第1水準漢字    = %dｹ所\r\n%s %d(s)"), iTotalLevel1,pKnjall1, STRING_len( pKnjall1 ) / 2 );
		}
	}
	if( iTotalLevel2 > 0 )	Message_printf( TEXT("第2水準漢字    = %dｹ所\r\n%s %d(s)"), iTotalLevel2,pKnjall2  , _NUM(STRING_len( pKnjall2 )) );
	if( iTotalLevel3 > 0 )	Message_printf( TEXT("NEC選定IBM拡張 = %dｹ所\r\n%s %d(s)"), iTotalLevel3,pKnjallNEC, _NUM(STRING_len( pKnjallNEC )) );
	if( iTotalLevel4 > 0 )	Message_printf( TEXT("IBM拡張        = %dｹ所\r\n%s %d(s)"), iTotalLevel4,pKnjallIBM, _NUM(STRING_len( pKnjallIBM )) );
	if( iTotalLevel5 > 0 )	Message_printf( TEXT("外字           = %dｹ所\r\n%s %d(s)"), iTotalLevel5,pKnjallEXT, _NUM(STRING_len( pKnjallEXT )) );
	
	
	mem_del( pKnjall1 );
	mem_del( pKnjall2 );
	mem_del( pKnjallNEC );
	mem_del( pKnjallIBM );
	mem_del( pKnjallEXT );
	mem_del( pKnjsub2 );
	mem_del( pKnjsubNEC );
	mem_del( pKnjsubIBM );
	mem_del( pKnjsubEXT );
	
}

//		
int		KANJI_CHECK::Func( LPCTSTR _sParamString )
{
	CSwbParam	cParam( _sParamString );							///< パラメータ処理.
	LPCTSTR		sPath;
	TCHAR		*pMem = NULL;
	int			ii, iLen;
	
	
	sPath		= cParam.GetPath();		///< ターゲットファイル (GetFilePath(0)としても同じ).
	iConvLevel	= cParam.GetInt(1);
	
	
	if( FALSE == Initialize() )	return FALSE;
	
	iLen = MEM_TextRead(&pMem, sPath );
	if( iLen == 0 )	return FALSE;
	m_bImplemented = TRUE;	//	実行済みフラグ
	
	iLen = FILT_deleteREM( pMem, iLen, TEXT("//"), TEXT("/*"), TEXT("*/"),'\"' );
	iLen = FILT_excessiveSPACE( pMem, iLen );
	
	ii = 0;
	while( ii < iLen )
	{
		ii += searchDouble( pMem+ii );
	}
	subtotal( sPath );
	
	mem_del(pMem);
	
	return TRUE;
}




//==================================================
//		ダブルバイト文字だとTRUEを返す
//==================================================
int	KANJI_CHECK::searchDouble( LPCTSTR _pPtr )
{
	const TCHAR		cTextAreaOver[] = TEXT("領域オーバー");
	unsigned short	uCode;
	TCHAR			sMoji[4] = TEXT("　");
	
	
#ifdef	_UNICODE
	uCode = *(WORD*)_pPtr;
	{
		//! 判定の時だけちゃちゃっとS-JISにしてしまう
		CTOSJIS		cJis;
		sMoji[ 0 ] = uCode;
		BYTE	*pJis = (BYTE*)cJis.From( sMoji );
		uCode = *(pJis)*0x100 + *(pJis+1);
	}
	
	if( uCode > 0xff )
#else
	if(	_ismbblead(*(_pPtr)) == 0 ||		///< マルチバイト文字の1バイト目？
		_ismbbtrail(*(_pPtr+1)) == 0 )		///< マルチバイト文字の2バイト目？
			return 1;
	
	uCode = *((BYTE*)_pPtr) * 0x0100 + *((BYTE*)_pPtr+1);
	sMoji[0] = *(_pPtr);
	sMoji[1] = *(_pPtr+1);
	
	if( _ismbclegal(uCode) != 0 )			///< UNICODEでは常に 0 を返すぞ
#endif
	{
		if( 0x8140 <= uCode && uCode <= 0x9872 )
		{
			/// 第1水準漢字
			iLevel1++;
			iTotalLevel1++;
			if(iConvLevel >= 2){
				if(STRING_len( pKnjall1 ) >= KANJI1BUFF_MAX)	Message_win( cTextAreaOver );
				else	if( buffCheck( pKnjall1, sMoji ) == TRUE )	STRING_cat( pKnjall1, sMoji );
			}
		}
		else if( 0x9890 <= uCode && uCode <= 0xEAA4 )
		{
			/// 第2水準漢字
			iLevel2++;
			iTotalLevel2++;
			if(iConvLevel >= 1){
				if(STRING_len( pKnjsub2 ) >= KANJISUBBUFF_MAX)	Message_win( cTextAreaOver );
				else	if( buffCheck( pKnjsub2, sMoji ) == TRUE )	STRING_cat( pKnjsub2, sMoji );
			}
			if(STRING_len( pKnjall2 ) >= KANJIBUFF_MAX)	Message_win( cTextAreaOver );
			else	if( buffCheck( pKnjall2, sMoji ) == TRUE )	STRING_cat( pKnjall2, sMoji );
		}
		else if( 0xED40 <= uCode && uCode <= 0xEEFB )
		{
			/// NEC選定IBM拡張
			iLevel3++;
			iTotalLevel3++;
			if(iConvLevel >= 1){
				if(STRING_len( pKnjsubNEC ) >= KANJISUBBUFF_MAX)	Message_win( cTextAreaOver );
				else	if( buffCheck( pKnjsubNEC, sMoji ) == TRUE )	STRING_cat( pKnjsubNEC, sMoji );
			}
			if(STRING_len( pKnjallNEC ) >= KANJIBUFF_MAX)	Message_win( cTextAreaOver );
			else	if( buffCheck( pKnjallNEC, sMoji ) == TRUE )	STRING_cat( pKnjallNEC, sMoji );
		}
		else if( 0xFA40 <= uCode && uCode <= 0xFC4B )
		{
			/// IBM拡張
			iLevel4++;
			iTotalLevel4++;
			if(iConvLevel >= 1){
				if(STRING_len( pKnjsubIBM ) >= KANJISUBBUFF_MAX)	Message_win( cTextAreaOver );
				else	if( buffCheck( pKnjsubIBM, sMoji ) == TRUE )	STRING_cat( pKnjsubIBM, sMoji );
			}
			if(STRING_len( pKnjallIBM ) >= KANJIBUFF_MAX)	Message_win( cTextAreaOver );
			else	if( buffCheck( pKnjallIBM, sMoji ) == TRUE )	STRING_cat( pKnjallIBM, sMoji );
		}
		else if( 0xF040 <= uCode && uCode <= 0xF14b )
		{
			/// 外字
			iLevel5++;
			iTotalLevel5++;
			if(iConvLevel >= 1){
				if(STRING_len( pKnjsubEXT ) >= KANJISUBBUFF_MAX)	Message_win( cTextAreaOver );
				else	if( buffCheck( pKnjsubEXT, sMoji ) == TRUE )	STRING_cat( pKnjsubEXT, sMoji );
			}
			if(STRING_len( pKnjallEXT ) >= KANJIBUFF_MAX)	Message_win( cTextAreaOver );
			else	if( buffCheck( pKnjallEXT, sMoji ) == TRUE )	STRING_cat( pKnjallEXT, sMoji );
		}
		
		return	2 / sizeof(TCHAR);
	}
	
	return	1;
}


//==================================================
//		文字列チェック
//==================================================
BOOL	KANJI_CHECK::buffCheck( LPCTSTR ptr, LPCTSTR str )
{
#ifdef	_UNICODE
	return (STRING_str( ptr, str ) == NULL);
#else
	int		ii;
	
	for(ii=0 ; ii<STRING_len(ptr) ; ii+=2){
		if( *(ptr+ii) == str[0] && *(ptr+ii+1) == str[1] )	return FALSE;
	}
	return TRUE;
#endif
}


//==================================================
//		情報表示
//==================================================
void	KANJI_CHECK::subtotal( LPCTSTR fname )
{
	if(iConvLevel >= 1)
	{
		Message_printf(  TEXT("<%s>") ,fname );
		if(iLevel1 > 0)	Message_printf(  TEXT("第1水準 = %d") ,iLevel1 );
		if(iLevel2 > 0)
			Message_printf(  TEXT("第2水準 = %d\r\n	%s %d(s)") ,		iLevel2, pKnjsub2,		_NUM(STRING_len(pKnjsub2)) );
		if(iLevel3 > 0)
			Message_printf(  TEXT("NEC選定IBM拡張 = %d\r\n	%s %d(s)") ,iLevel3, pKnjsubNEC,	_NUM(STRING_len(pKnjsubNEC)) );
		if(iLevel4 > 0)
			Message_printf(  TEXT("IBM拡張 = %d\r\n	%s %d(s)") ,		iLevel4, pKnjsubIBM,	_NUM(STRING_len(pKnjsubIBM)) );
		if(iLevel5 > 0)
			Message_printf(  TEXT("外字 = %d\r\n	%s %d(s)") ,		iLevel5, pKnjsubEXT,	_NUM(STRING_len(pKnjsubEXT)) );
		
		Message_win( TEXT("") );
	}
	
	/// 初期化
	*pKnjsub2 = *pKnjsubNEC = *pKnjsubIBM = *pKnjsubEXT = '\0';
	iLevel1 = iLevel2 = iLevel3 = iLevel4 = iLevel5 = 0;
	
}


KANJI_CHECK	*pC_kchk = NULL;
