#include"CFileWrite.h"
#include"../CString.h"
#include"../Debug/CWarning.h"
#include"../Debug/CAssert.h"

#include<string>

namespace Maid
{
/*!
 	@class	CFileWrite CFileWrite.h
 	@brief	ファイルにたいして書き込みのみのクラス
\n			今のところ単一のファイルに書き込むだけです
\n			そのうち拡張する予定
 */ 
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! コンストラクタ
/*!
 */
CFileWrite::CFileWrite() : m_Handle(NULL)
{

}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! デストラクタ
/*!
 */
CFileWrite::~CFileWrite()
{
	Close();
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 書き込むファイルを開く
/*!
 	@param	FileName	[i ]	開くファイル名
 	@param	eOption		[i ]	開くモード
 */
void CFileWrite::Open( const mstring& FileName, CFileWrite::OPENOPTION eOption )
{
	Close();

	MySTL::string OpenMode;

	switch( eOption )
	{
	case OPENOPTION_NEW:	{ OpenMode = "wb"; }break;
	case OPENOPTION_ADD:	{ OpenMode = "ab";  }break;
	}

	MySTL::string str = CString::ConvertMAIDtoSJIS(FileName);

	m_Handle = ::fopen( str.c_str(), OpenMode.c_str() );

	if( m_Handle==NULL )
	{
		MAID_WARNING( "ファイルのオープンに失敗" << str );
	}
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 書き込みカーソルの移動
/*!
 *	ファイル範囲を超える指定があった場合　範囲内になるようにクリップされる
 *	\param	Size	[i ]	移動量（バイト単位）
 *	\param	ePos	[i ]	基準点
 *
 *	\return	関数の成功で DENRESULT_OK
 *			関数の失敗で 0以外
 */
void	CFileWrite::Seek( int Size, POSITION ePos )
{
	MAID_ASSERT( m_Handle==NULL, "ファイルが開かれていません" );
	if( m_Handle==NULL ) { return ; }

	long Origin;
	switch( ePos )
	{
	case POSITION_BEGIN:		{ Origin = SEEK_SET; }break;
	case POSITION_END:		{ Origin = SEEK_END; }break;
	case POSITION_CURRENT:	{ Origin = SEEK_CUR; }break;
	}
	
	::fseek( m_Handle, Size, Origin );
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ファイルに書き込む
/*!
 *	\param	pData		[i ]	書き込みたいデータの先頭アドレス
 *	\param	DataSize	[i ]	書き込むサイズ（バイト単位）
 *
 *	\return	実際に書き込んだバイト数
 */
int CFileWrite::Write( const void* pData, int DataSize )
{
	if( DataSize==0 ) { return 0; }

	MAID_ASSERT( m_Handle==NULL, "ファイルが開かれていません" );
	if( m_Handle==NULL ) { return 0; }

	const int count = (int)::fwrite( pData, DataSize, 1, m_Handle );

	if( count!=1 )
	{
		MAID_WARNING( "書き込んだ項目数が違います 戻り値 " << count );
	}

	return DataSize;
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 開いているファイルを閉じる
/*!
 */
void CFileWrite::Close()
{
	if( m_Handle==NULL ) { return ; }

	::fclose( m_Handle );
	m_Handle = NULL;
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! FileName に一括書き込みする
/*!
 	いちいち Open, Write と書くのがめんどくさいので用意しました
 
 	@param	FileName	[i ]	書き込みたいファイル名（すでに存在しているときは破壊されます
 	@param	pData		[i ]	書き込みたいデータの先頭アドレス
 	@param	Size		[i ]	書き込むサイズ（バイト単位）
 
 	@return	書き込んだファイルサイズ
 
 	@code
 	MySTL::vector<STRUCT>	Data;
 	CFileWrite::Write( MAIDTEXT("hoge.dat"), &Data[0], Data.size()*sizeof(STRUCT) );	//	これで読み込みの終わり
 	@endcode
 */
int CFileWrite::Write( const mstring& FileName, const void* pData, int Size )
{
	CFileWrite	hFile;

	hFile.Open( FileName, OPENOPTION_NEW );
	const int size = hFile.Write( pData, Size );

	if( size!=Size ) { return 0; }

	return size;
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! FileName に0byteのファイルを作成する
/*!
 	@param	FileName	[i ]	書き込みたいファイル名（すでに存在しているときは破壊されます
 
 */
void	CFileWrite::Create( const mstring& FileName )
{
	CFileWrite	hFile;

	hFile.Open( FileName, OPENOPTION_NEW );
}

}
