#include "stdafx.h"
#include "refCMActフリップボード.h"
#include "..\Direct3D9\CDirect3DNative.h"

namespace FDK
{
// public:

	void CMActフリップボード::t表示( String^ str表示文字列 )
	{
		lock l( this );

		this->ctアニメ用 = gcnew CCounter( 0, this->_n表示し続ける時間ms + this->_nフェードアウトにかける時間ms, 1 );
		this->str表示文字列 = str表示文字列;
		this->b文字列変更 = true;
	}

	CMActフリップボード::CMActフリップボード( D3DFormat TextureFormat )
	{
		this->_n表示し続ける時間ms = 1000;
		this->_nフェードアウトにかける時間ms = 1000;

		this->b文字列変更 = false;
		this->TextureFormat = TextureFormat;
		this->txフリップボード = nullptr;
		this->str表示文字列 = nullptr;
		this->font文字列 = nullptr;
		this->ctアニメ用 = nullptr;
	}
	CMActフリップボード::CMActフリップボード( D3DFormat TextureFormat, int n表示し続ける時間ms, int nフェードアウトにかける時間ms )
		:CMActフリップボード( TextureFormat )
	{
		this->_n表示し続ける時間ms = n表示し続ける時間ms;
		this->_nフェードアウトにかける時間ms = nフェードアウトにかける時間ms;
	}

	void CMActフリップボード::Onデバイスリソースの作成()
	{
		lock l( this );
		HANDLE hDevice = NULL;
		
		try
		{
			CDirect3DNative::tデバイスをロックする( true, &hDevice, NULL );

			this->font文字列 = gcnew Font( FontFamily::GenericSansSerif, 32.0f, FontStyle::Regular, GraphicsUnit::Pixel );
			this->tフリップボードの作成( hDevice );
		}
		finally
		{
			CDirect3DNative::tデバイスのロックを解除する( hDevice );
		}
	}
	void CMActフリップボード::Onデバイスリソースの解放()
	{
		lock l( this );

		SAFE_REF_DELETE( this->txフリップボード );
		SAFE_REF_DELETE( this->font文字列 );
		SAFE_REF_DELETE( this->ctアニメ用 );
	}

	int CMActフリップボード::On進行()
	{
		lock l( this );

		if( nullptr == this->ctアニメ用 )
			return 0;	// 表示が開始されていない

		if( this->ctアニメ用->t進行()->b終了値に達した )
			this->ctアニメ用 = nullptr;
			
		return 0;
	}
	void CMActフリップボード::On描画( IntPtr hDevice )
	{
		lock l( this );

		if( this->ctアニメ用 == nullptr )
			return;		// 表示が開始されていない


		// フリップボードの作成・変更。

		if( this->b文字列変更 )
		{
			this->tフリップボードの作成( static_cast<HANDLE>( hDevice.ToPointer() ), str表示文字列 );
			this->b文字列変更 = false;
		}

		if( nullptr == this->txフリップボード )
			return;


		// 透明度の設定。

		if( this->ctアニメ用->n現在の値 < this->_n表示し続ける時間ms )
			this->txフリップボード->n透明度 = 255;
		else
			this->txフリップボード->n透明度 = (int) ( ( 1.0 - ( this->ctアニメ用->n現在の値 - this->_n表示し続ける時間ms ) / ( double ) this->_nフェードアウトにかける時間ms ) * 255.0 );


		// 描画。

		this->txフリップボード->t2D描画( hDevice, 0, 0 );
	}

// private:

	void CMActフリップボード::tフリップボードの作成( HANDLE hDevice, String^ str表示文字列 )
	{
		this->str表示文字列 = str表示文字列;
		this->tフリップボードの作成( hDevice );
	}
	void CMActフリップボード::tフリップボードの作成( HANDLE hDevice )
	{
		if( String::IsNullOrEmpty( this->str表示文字列 ) || nullptr == this->font文字列 || NULL == hDevice )
			return;

		SAFE_REF_DELETE( this->txフリップボード );

		SizeF sz文字列のサイズ;

		#pragma region [ 文字列のサイズ(SizeF)[px] を取得する。]
		//-----------------
		Bitmap^ bitmap = gcnew Bitmap( 1, 1 );
		{
			Graphics^ g = Graphics::FromImage( bitmap );
			{
				g->PageUnit = GraphicsUnit::Pixel;
				sz文字列のサイズ = g->MeasureString( this->str表示文字列, this->font文字列 );
			}
			delete g;
		}
		delete bitmap;
		//-----------------
		#pragma endregion
		#pragma region [ 取得したサイズで文字列を描画し、フリップボードテクスチャを作成する。 ]
		//-----------------
		bitmap = gcnew Bitmap( (int) sz文字列のサイズ.Width, (int) sz文字列のサイズ.Height, PixelFormat::Format32bppArgb );
		{
			Graphics^ g = Graphics::FromImage( bitmap );
			{
				// 白地に黒の文字。

				g->Clear( Color::White );
				g->DrawString( this->str表示文字列, this->font文字列, Brushes::Black, 0.0f, 0.0f );
				try
				{
					this->txフリップボード = gcnew CTexture( IntPtr( hDevice ), bitmap, this->TextureFormat );
				}
				catch( Exception^ )
				{
					this->txフリップボード = nullptr;
				}
			}
			delete g;
		}
		delete bitmap;
		//-----------------
		#pragma endregion
	}
}
