/*!
 	@file 
 	@brief	複数のファイル読み込みをサポートするクラス
\n			複数のファイルがパック化されているファイルの読み込み(CPackFileManager)にも対応しています
 
 	@par アーカイブファイルの使用例
 	@code

	CFileRead::GetArchiveFile().Mount( "Arc.dat" );	//	アーカイブファイルをマウントする


	CFileRead hFile;

	hFile.Open( "Arc\\sample.bmp" );	//  こうすると 実際に存在している Arc\sample.bmp を探した後
										//	見つからなかったら Arc.dat 内の sample.bmp を探します。
 	@endcode
 */


#ifndef CFileRead_h
#define CFileRead_h

#include"../../Setup/CompileMode.h"
#include"../Debug/CAssert.h"
#include"../mstring.h"
#include"CFileReadInterface.h"
#include"CPackFileManager.h"
#include<vector>
#include<string>

#include<boost/smart_ptr.hpp>
#include"../Debug/CWarning.h"
#include<windows.h>

namespace Maid
{
	class CFileRead : public IFileRead
	{
	public:
		CFileRead();
		virtual ~CFileRead();

				void	Open( const mstring& FileName );
				void	OpenOnmemory( const mstring& FileName );
		virtual void	Close();
		virtual int		Read( void* pData, int Size );
		virtual void	Seek( int Size, IFileRead::POSITION ePos );
		virtual int		GetSize()    const;
		virtual int		GetPosition()const;

		void	SetPosition( int pos );

		const CFileRead& operator = ( const CFileRead& src )
		{
			if( src.m_pFile.get()==NULL ) { return *this; }

			if( src.m_IsOnmemory )	{ OpenOnmemory(src.m_FileName); }
			else					{ Open(src.m_FileName); }
			Seek( src.GetPosition(), IFileRead::POSITION_BEGIN );
			return *this;
		}

		bool IsEOF() const;

		unt08 Read1ByteBigEndian();
		unt16 Read2ByteBigEndian();
		unt32 Read3ByteBigEndian();
		unt32 Read4ByteBigEndian();
		float ReadfloatBigEndian();
		double ReaddoubleBigEndian();
		unt08 Read1ByteLittleEndian();
		unt16 Read2ByteLittleEndian();
		unt32 Read3ByteLittleEndian();
		unt32 Read4ByteLittleEndian();
		float ReadfloatLittleEndian();
		double ReaddoubleLittleEndian();

		mstring ReadString( int endian=1 );


		//! ファイルを一括読み込みする
		/*!
		 	いちいち Open, Read と書くのがめんどくさいので用意しました
		 	一括読み込みなので GetSize()%T != 0 の時は危険です。
		 
		 	@param	FileName	[i ]	読み込むファイル名
		 	@param	Data		[ o]	出力先
		 
		 	@return	関数の成功で DENRESULT_OK
		\n			それ以外は失敗
		 
		 	@code
		 	MySTL::vector<STRUCT>	pData;
		 	CFileRead::Read( "hoge.dat", Data );	//	これで読み込みの終わり
		 	@endcode
		 */
		
		template <typename T>
		static void	Read( const mstring& FileName, MySTL::vector<T>& Data )
		{
			CFileRead	hFile;

			hFile.Open( FileName );
			const unt32 Size = hFile.GetSize();

			if( Size==0 ) { return ; }

			MAID_ASSERT( Size%sizeof(T)!=0, "ファイルサイズがおかしいです" );

			Data.resize( Size/sizeof(T) );
			hFile.Read( &(Data[0]), Size );
		}

		//! ファイルを一括読み込みする。テキストとして。
		static void	Read( const mstring& FileName, MySTL::string& Text )
		{
			MySTL::vector<char> dat;

			Read( FileName, dat ); 

			dat.push_back('\0');
			Text = (char*)(&dat[0]);
		}

		static bool		IsExist( const mstring& FileName );
		static CPackFileManager& GetPackFile();

	private:
		boost::shared_ptr<IFileRead>	m_pFile;
		mstring							m_FileName;
		bool							m_IsOnmemory;
	private:
		static CPackFileManager s_PackManager;
	};
}
#endif
