#pragma once

/*!
@page intro_sound_page Sound
@section intro_sound_decoder_sec Decoder

<ol type="1">
	<li><b>プロジェクトの作成</b></li><br>
	メインメニューの「ファイル」→「新規作成」→「プロジェクト」を選んで、「Win32 コンソールアプリケーション」で 空のDLLのプロジェクトを作成します。<br>
	次にプロジェクトのプロパティを開き、「構成プロパティ」→「C/C++」→「全般」にある「追加のインクルードディレクトリ」に Mix のインクルードファイルがあるディレクトリ(※)を指定します。<br>
	<br>
	※ "Mix\Engine\Include\"<br>

	<li><b>デコーダクラスの作成</b></li><br>
	Mix::Plugin::Sound::IDecoder を継承したクラスを作成し、必要なメソッドを実装します。

	Mix::Plugin::Sound::IDecoder::Initialize<br>
	Mix::Plugin::Sound::IDecoder::Destroy<br>
	Mix::Plugin::Sound::IDecoder::GetFormat<br>
	Mix::Plugin::Sound::IDecoder::GetSize<br>
	Mix::Plugin::Sound::IDecoder::GetPosition<br>
	Mix::Plugin::Sound::IDecoder::Read<br>
	Mix::Plugin::Sound::IDecoder::Reset<br>

	<li><b>DLL エクスポートのソースファイルの作成</b></li><br>
	プロジェクトに <b>"main.cpp"</b> を追加し、以下の関数を実装します。<br>
	<ul>
		<li><b>Mix::Plugin::INFORMATION __stdcall GetInformation( void )</b></li><br>
		このプラグインの情報を取得する関数です。<br>

		<li><b>bool __stdcall CheckFormat( const void* pKey, unsigned int& keySize )</b></li><br>
		このプラグインでデコードできるかどうかを判定する関数です。<br>
		pKey には keySize( バイト単位 ) 分の先頭のデータが渡されます。<br>
		その内容をみてデコード可能な場合は true を返してください。<br>
		また、pKey に NULL が設定されていた場合、keySize にはデコード可能かどうかを判定する際に必要なキーのサイズを渡して true を返してください。<br>

		<li><b>bool __stdcall CreateDecoder( Mix::Plugin::Sound::IDecoder** ppDecoder )</b></li><br>
		デコーダを作成する関数です。<br>
		ppDecoder には作成したデコーダを渡してください。<br>
		作成に成功した場合は true を返します。
	</ul>

	<li><b>DLL エクスポートのモジュール定義ファイルの作成</b></li><br>
	プロジェクトに以下のモジュール文を記述したファイル <b>"main.def"</b> を追加してください。<br>

	<pre><b>EXPORTS</b>
	<b>GetInformation</b>
	<b>CheckFormat</b>
	<b>CreateDecoder</b></pre>

	最後にプロジェクトのプロパティの「構成プロパティ」→「リンカ」→「入力」にある「モジュール定義ファイル」に "main.def" を指定してください。

</ol>
*/

#include "Mix/Plugin/Common.h"
#include "Mix/Plugin/IReader.h"

namespace Mix{ namespace Plugin{ namespace Sound{

	//! @class IDecoder
	//! @brief サウンドデコーダーインターフェース
	class IDecoder
	{
	protected:
		//! @brief デストラクタ
		virtual ~IDecoder( void ){}

	public:
		//! @brief 初期化します
		//! @param[in] pSrc 波形のソースを表す Mix::Plugin::IReader インターフェースのポインタ
		//! @return 成功した場合は true を返します
		//! @note このメソッドで波形のフォーマット( GetFormat )、サイズ( GetSize )を設定します。
		virtual bool Initialize( Mix::Plugin::IReader* pSrc ) = 0;
		//! @brief 自身を破棄します
		//! @note デコーダクラスのインスタンスを new で作成した場合、メッソッドの実装は自身を解放する delete this になります。
		virtual void Destroy( void ) = 0;

		//! @brief 波形のフォーマットを取得します
		//! @return 波形のフォーマットを返します
		virtual LPCWAVEFORMATEX GetFormat( void ) = 0;

		//! @brief 波形の読み取り位置を取得します
		//! @return 波形の読み取り位置を返します
		virtual unsigned long long GetPosition( void ) = 0;
		//! @brief 波形のサイズを取得します
		//! @return 波形のサイズを返します
		virtual unsigned long long GetSize( void ) = 0;

		//! @brief 波形を読み取ります
		//! @param[in] pSrc 波形のソースを表す Mix::Plugin::IReader インターフェースのポインタ
		//! @param[out] pDst 読み取った波形を格納するバッファ
		//! @param[in] size 読み取る波形のサイズ( バイト単位 )
		//! @return 実際に読み取った波形のサイズ( バイト単位 )を返します
		virtual unsigned int Read( Mix::Plugin::IReader* pSrc, void* pDst, unsigned int size ) = 0;

		//! @brief 波形の読み取り位置をを先頭に戻します
		//! @param[in] pSrc 波形のソースを表す Mix::Plugin::IReader インターフェースのポインタ
		virtual void Reset( Mix::Plugin::IReader* pSrc ) = 0;
	};

}}}
