//--------------
//   ログ出力
//--------------
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "LogFile.h"


//--------------------------------------------------------------------
//	[ 書式 ]
//		CLogFile()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		デフォルトコンストラクタ
//--------------------------------------------------------------------
CLogFile::CLogFile()
{
	SetDefault();
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		CLogFile( const char* pFileName , int iMode )
//
//	[ 引数 ]
//		const char* pFileName		ログファイル名
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ファイル名指定つきのコンストラクタ
//--------------------------------------------------------------------
CLogFile::CLogFile( const char* pFileName , int iMode )
{
	SetDefault();

	BOOL bRes;
	bRes = SetFileName( pFileName );
	SetMode( iMode );
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		CLogFile( CLogFile& rLogFile )
//
//	[ 引数 ]
//		CLogFile& rLogFile			コピーもとコンストラクタ
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		コピーコンストラクタ
//--------------------------------------------------------------------
CLogFile::CLogFile( CLogFile& rLogFile )
{
	SetDefault();

	BOOL bRes;
	bRes = CopyMembers( rLogFile );
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		~CLogFile()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		デストラクタ
//--------------------------------------------------------------------
CLogFile::~CLogFile()
{
	Close();
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void SetDefault()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		コンストラクタでの初期値設定
//--------------------------------------------------------------------
void CLogFile::SetDefault()
{
	m_pFileName	= NULL;
	m_pStream	= NULL;
	m_iMode		= LOGFILE_NOTOUT;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		BOOL CopyMembers( CLogFile& rLogFile )
//
//	[ 引数 ]
//		CLogFile& rLogFile			コピーもとオブジェクトへの参照
//
//	[ 戻り値 ]
//		成功：TRUE
//		失敗：FALSE
//
//	[ 解説 ]
//		オブジェクトの内容を複製する
//--------------------------------------------------------------------
BOOL CLogFile::CopyMembers( CLogFile& rLogFile )
{
	BOOL bRes;

	// まずは閉じる
	Close();
	m_pFileName	= NULL;
	m_pStream	= NULL;
	m_iMode		= LOGFILE_NOTOUT;

	// ファイル名
	if( rLogFile.m_pFileName!=NULL ){
		int iLength;
		iLength = strlen( rLogFile.m_pFileName );

		m_pFileName = (char*)malloc( iLength +1 );
		if( m_pFileName==NULL ){
			return FALSE;
		}
	}

	// ファイルストリーム
	if( rLogFile.m_pStream ){
		// ファイルが開いている場合は、オープンする
		bRes = Open( rLogFile.m_pFileName );
		if( bRes==FALSE ){
			free( m_pFileName );
			m_pFileName = NULL;
			return FALSE;
		}
	}

	// 出力レベル
	m_iMode = rLogFile.m_iMode;

	// 終了
	return TRUE;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		BOOL SetFileName( const char* pFileName )
//
//	[ 引数 ]
//		const char* pFileName		ファイル名
//
//	[ 戻り値 ]
//		成功：TRUE
//		失敗：FALSE
//
//	[ 解説 ]
//		ログファイル名を設定します。
//		すでに設定されている場合は、一度解放されて上書きされます。
//--------------------------------------------------------------------
BOOL CLogFile::SetFileName( const char* pFileName )
{
	if( m_pFileName ){
		free( m_pFileName );
	}

	int iLength;
	iLength = strlen( pFileName );
	m_pFileName = (char*)malloc( iLength + 1 );
	if( m_pFileName==NULL ){
		return FALSE;
	}

	strcpy( m_pFileName , pFileName );

	return TRUE;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void SetMode( int iMode )
//
//	[ 引数 ]
//		int iMode					ログ出力レベル
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ログの出力レベルを設定します。
//--------------------------------------------------------------------
void CLogFile::SetMode( int iMode )
{
	m_iMode = iMode;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		int GetMode()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		現在のログ出力レベル
//
//	[ 解説 ]
//		現在設定されているログ出力レベルを取得します。
//--------------------------------------------------------------------
int CLogFile::GetMode()
{
	return m_iMode;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		BOOL Open( const char* pFileName , int iMode )
//
//	[ 引数 ]
//		const char* pFileName		ログファイルのファイル名
//		int iMode					ログの出力レベル
//
//	[ 戻り値 ]
//		成功：TRUE
//		失敗：FALSE
//
//	[ 解説 ]
//		pFileName のファイル名で、新規にログファイルをオープンします。
//		既存のファイルがあった場合は上書きされます。
//--------------------------------------------------------------------
BOOL CLogFile::Open( const char* pFileName , int iMode )
{
	BOOL bRes;

	// モード設定
	SetMode( iMode );

	// 開く
	bRes = Open( pFileName );
	if( bRes==FALSE ){
		Close();
		return FALSE;
	}

	return TRUE;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		BOOL Open( const char* pFileName )
//
//	[ 引数 ]
//		const char* pFileName		ログファイルのファイル名
//
//	[ 戻り値 ]
//		成功：TRUE
//		失敗：FALSE
//
//	[ 解説 ]
//		pFileName のファイル名で、新規にログファイルをオープンします。
//		既存のファイルがあった場合は上書きされます。
//--------------------------------------------------------------------
BOOL CLogFile::Open( const char* pFileName )
{
	BOOL bRes;

	bRes = SetFileName( pFileName );
	if( bRes==FALSE ){
		Close();
		return FALSE;
	}

	bRes = Open();
	if( bRes==FALSE ){
		Close();
		return FALSE;
	}

	return TRUE;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		BOOL Open()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		成功：TRUE
//		失敗：FALSE
//
//	[ 解説 ]
//		pFileName のファイル名で、新規にログファイルをオープンします。
//		既存のファイルがあった場合は上書きされます。
//--------------------------------------------------------------------
BOOL CLogFile::Open()
{
	if( m_pFileName==NULL )return FALSE;

	if( m_pStream!=NULL ){
		fclose( m_pStream );
	}

	m_pStream = fopen( m_pFileName , "wt" );
	if( m_pStream==NULL ){
		Close();
		return FALSE;
	}

	return TRUE;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void Log( char* pMes , ... )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		[argument]...		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ファイルにログを出力します。
//		LOGFILE_NOTOUT 設定以外の場合は必ず出力されます。
//--------------------------------------------------------------------
void CLogFile::Log(const char* pMes , ... )
{
	va_list marker;
	va_start( marker , pMes );
	Log( pMes , marker );
	va_end( marker );
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void DebugLog( char* pMes , ... )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		[argument]...		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_DEBUG 以上の場合にログを出力します。
//--------------------------------------------------------------------
void CLogFile::DebugLog(const char* pMes , ... )
{
#ifndef __DISABLE_LOGFILE__
	va_list marker;
	va_start( marker , pMes );
	DebugLog( pMes , marker );
	va_end( marker );
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void CheckLog( char* pMes , ... )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		[argument]...		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_CHECK 以上のときにログを出力します。
//--------------------------------------------------------------------
void CLogFile::CheckLog(const  char* pMes,... )
{
#ifndef __DISABLE_LOGFILE__
	va_list marker;
	va_start( marker , pMes );
	CheckLog( pMes , marker );
	va_end( marker );
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void TrackLog( char* pMes , ... )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		[argument]...		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_TRACE 以上の場合にログを出力します。
//--------------------------------------------------------------------
void CLogFile::TraceLog(const char* pMes , ... )
{
#ifndef __DISABLE_LOGFILE__
	va_list marker;
	va_start( marker , pMes );
	TraceLog( pMes , marker );
	va_end( marker );
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void ErrorLog( char* pMes , ... )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		[argument]...		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		LOGFILE_NOTOUT 以外の場合にログを出力します。
//		出力されるメッセージの先頭に「[error]」という
//		プレフィックスが付加されます。
//--------------------------------------------------------------------
void CLogFile::ErrorLog( const char* pMes , ... )
{
	va_list marker;
	va_start( marker , pMes );
	ErrorLog( pMes , marker );
	va_end( marker );
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void Log( char* pMes , va_list marker )
//
//	[ 引数 ]
//			char*	pMes		フォーマット文字列
//			va_list marker		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ファイルにログを出力します。
//		LOGFILE_NOTOUT 設定以外の場合は必ず出力されます。
//--------------------------------------------------------------------
void CLogFile::Log(const char* pMes , va_list marker )
{
	switch( m_iMode ){
		case LOGFILE_NOTOUT:
			return;
			break;

		default:
			OutputLog( pMes , marker );		// メッセージの出力
			fflush( m_pStream );
			return;
			break;
	}
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void DebugLog( char* pMes , va_list marker )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		va_list marker		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_DEBUG 以上の場合にログを出力します。
//--------------------------------------------------------------------
void CLogFile::DebugLog(const char* pMes , va_list marker )
{
#ifndef __DISABLE_LOGFILE__
	switch( m_iMode ){
		case LOGFILE_DEBUG:
		case LOGFILE_CHECK:
		case LOGFILE_TRACE:
			OutputLog( pMes,marker );	// エラーメッセージの出力
			fflush( m_pStream );
			return;
			break;

		default:
			return;
			break;
	}
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void CheckLog( char* pMes , va_list marker )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		va_list marker		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_CHECK 以上のときにログを出力します。
//--------------------------------------------------------------------
void CLogFile::CheckLog(const char* pMes,va_list marker )
{
#ifndef __DISABLE_LOGFILE__
	switch( m_iMode ){
		case LOGFILE_CHECK:
		case LOGFILE_TRACE:
			OutputLog( pMes,marker );	// エラーメッセージの出力
			fflush( m_pStream );
			return;
			break;

		default:
			return;
			break;
	}
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void TrackLog( char* pMes , va_list marker )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		va_list marker		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		出力レベルが LOGFILE_TRACE 以上の場合にログを出力します。
//--------------------------------------------------------------------
void CLogFile::TraceLog(const char* pMes , va_list marker )
{
#ifndef __DISABLE_LOGFILE__
	switch( m_iMode ){
		case LOGFILE_TRACE:
			OutputLog( pMes,marker );			// エラーメッセージの出力
			fflush( m_pStream );
			return;
			break;

		default:
			return;
			break;
	}
#endif
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void ErrorLog( char* pMes , va_list marker )
//
//	[ 引数 ]
//		char*	pMes		フォーマット文字列
//		va_list marker		オプションの引数
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		LOGFILE_NOTOUT 以外の場合にログを出力します。
//		出力されるメッセージの先頭に「[error]」という
//		プレフィックスが付加されます。
//--------------------------------------------------------------------
void CLogFile::ErrorLog( const char* pMes , va_list marker )
{
	if( m_iMode==LOGFILE_NOTOUT )return;

	if( m_pStream==NULL ){
		BOOL bRes;
		bRes = Open();
		if( bRes==FALSE ){
			return;
		}
	}
	fprintf( m_pStream , "[error] " );
	fflush( m_pStream );

	OutputLog( pMes,marker );			// エラーメッセージの出力
	fflush( m_pStream );
	return;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void Close()
//
//	[ 引数 ]
//		なし
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ログファイルを閉じます。
//		すでにログが閉じている状態で呼ばれても問題ありません。
//--------------------------------------------------------------------
void CLogFile::Close()
{
	if( m_pStream!=NULL ){
		fclose( m_pStream );
	}

	if( m_pFileName!=NULL ){
		free( m_pFileName );
	}

	m_pFileName		= NULL;
	m_pStream		= NULL;
	m_iMode			= LOGFILE_NOTOUT;
}


//--------------------------------------------------------------------
//	[ 書式 ]
//		void OutputLog( char* pMes , va_list marker )
//
//	[ 引数 ]
//		FILE*	pDStream		出力先のファイルポインタ
//		char*	pMes			出力フォーマット文字列
//		va_list	marker			パラメータリスト
//
//	[ 戻り値 ]
//		なし
//
//	[ 解説 ]
//		ログを出力します。
//--------------------------------------------------------------------
void CLogFile::OutputLog( const char* pMes,va_list marker )
{
	if( m_pStream==NULL ){
		BOOL bRes;
		bRes = Open();
		if( bRes==FALSE )return;
	}

	vfprintf( m_pStream , pMes , marker );					// エラーメッセージの出力
}
