#pragma once
#include<DxLib.h>
#include<Image.h>


///	<summary>
///	クラス説明
///	</summary>
namespace DXFW
{
///	<summary>イメージの合成</summary>
/// 合成元のイメージに入力イメージを合成し、
/// 画像編集ソフトにあるような合成処理を施す。
/// 合成率は0.0〜1.0の範囲で指定し、率が高い程入力の影響が強くなる。
///	<example>
///	[サンプルコード:未完成]<BR>
/// サンプル説明<BR>
///	<code>
///	int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )<BR>
///	{<BR>
///		if( !Dx::Initialise() ) return -1;<BR>
///		Dx::End();<BR>
///		return 0;<BR>
/// }<BR>
/// </code>	
/// </example>
class Blend
{
public:
	/// <summary>加算合成</summary>
	/// 合成イメージに入力イメージの色を足す。
	bool Add( Image* 合成イメージ , const Image *入力イメージ ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_ADD);
	}
			
	/// <summary>焼き込み合成</summary>
	/// 合成して暗くする。
	///[計算方法]
	///合成後の色 = 1.0 - ( 1.0 -  合成元の色 ) / 入力の色
	///※入力の色が0.0の時、合成後の色は0.0
	bool Burn( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_BURN);
	}
			
	/// <summary>比較合成(暗)</summary>
	/// 合成と入力の暗い方を合成後の色にする。
	bool Darken( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DARKEN);
	}
			
	/// <summary>減算合成</summary>
	/// 合成イメージから、入力イメージを減算する。
	bool Difference( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DIFFERENCE);
	}
			
	/// <summary>覆い焼き合成</summary>
	/// 合成後、明るくする。
	///[計算方法]
	///合成後の色 = 合成元の色 / (1.0 - 入力の色)
	///※入力の色が1.0の場合、合成後の色は1.0
	bool Dodge( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DODGE);
	}
			
	/// <summary>除外合成</summary>
	/// 合成後、暗くする。
	///[計算方法]
	///合成後 = 合成元 + 入力 - 2.0 * 合成元 * 入力
	bool Exclusion( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_EXCLUSION);
	}
			
	/// <summary>ハードライト合成</summary>
	/// オーバーレイ合成の条件を、合成元から入力に変更して計算。
	bool HardLight( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend(合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_HARDLIGHT);
	}
			
	/// <summary>比較合成(明)</summary>
	/// 合成と入力の明るい方を合成後の色にする。
	bool Lighten( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_LIGHTEN);
	}
			
	/// <summary>乗算合成</summary>
	/// 二つのイメージの色を乗算する。
	/// 各成分は0.0〜1.0の値に見立てて乗算を行うので、
	/// 元の色より暗くなる事はあっても明るくなることはない。
	bool Multiple( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_MULTIPLE);
	}
			
	/// <summary>通常合成</summary>
	/// 特殊な効果を付けずに合成
	/// 合成率が1に近いほど、入力画像の不透明度が高くなる。
	bool Normal( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle() , (int)(合成率*255) ,DX_GRAPH_BLEND_NORMAL);
	}
			
	/// <summary>オーバーレイ合成</summary>
	/// 合成イメージの色が0.5以下の部分は暗く、それ以外は明るくする合成。
	///[計算方法]
	///GrHandleの色が0.5以下:
	///合成後の色 = 合成元の色 * 入力の色 * 2.0
	///それ以外:
	///合成後の色 = 2.0 * ( 合成元の色 + 入力の色 - 合成元の色 * 入力の色 ) - 1.0
	bool OverLay( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_OVERLAY);
	}
			
	///<summary>RGBAの要素を選択して合成</summary>
	///合成後の画像として赤・緑・青・アルファの各成分を 合成元、入力のどちらのどの要素から取るかを指定する。
	///例えば、赤要素 に RGBA::BlendR を指定した場合は、合成後の画像の赤成分は、入力イメージの緑成分になる。
	bool RgbaSelectMix( Image* 合成イメージ , const Image *入力イメージ, RGBA 赤要素 , RGBA 緑要素 , RGBA 青要素 , RGBA 透明要素 ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_RGBA_SELECT_MIX, 赤要素 , 緑要素 , 青要素 , 透明要素 );
	}
			
	/// <summary>スクリーン合成</summary>
	/// 加算合成のように明るくする。
	///[計算方法]
	/// 合成後の色 = 1.0f - ( ( 1.0f - 合成イメージの色 ) * ( 1.0f - 入力イメージの色 ) )
	bool Screen( Image* 合成イメージ , const Image *入力イメージ,double 合成率 = 1.0)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_SCREEN);
	}
			
	/// <summary>ソフトライト合成</summary>
	/// 合成イメージの色が0.5以下の部分は暗く、それ以外は明るくする合成。
	///[計算方法]
	///GrHandleの色が0.5以下:
	///合成後の色 = pow( 合成元, ( 1.0f - 入力 ) * 2.0 )
	///それ以外:
	///合成後の色 = pow( 合成元, 0.5 / 入力 )
	bool SoftLight( Image* 合成イメージ , const Image *入力イメージ,double 合成率)
	{
		return !DxLib::GraphBlend( 合成イメージ->GetHandle() , 入力イメージ->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_SOFTLIGHT);
	}
};
	
/// <summary>イメージを合成して合成[未実装]</summary>
/// Blendクラスを参照。
/// ２つのイメージを特殊効果付きでブレンドし、イメージのハンドルを返す。
/// 修正中なので使えません。
///	<example>
///	[サンプルコード:未完成]<BR>
/// サンプル説明<BR>
///	<code>
///	int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )<BR>
///	{<BR>
///		if( !Dx::Initialise() ) return -1;<BR>
///		Dx::End();<BR>
///		return 0;<BR>
/// }<BR>
/// </code>	
/// </example>
class BlendBlt
{
public:
	/// <summary>説明</summary>
	static Image Add(const Image *imgA,const Image *imgB,double 合成率)
	{
		const int width  = max( imgA->GetWidth() , imgB->GetWidth() );
		const int height = max( imgA->GetHeight() , imgB->GetHeight() );
		Image outPut( width , height , true , true , true );

		DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , outPut.GetHandle(),int(合成率*255),DX_GRAPH_BLEND_ADD);
		return outPut;
	}
	static bool Add(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_ADD);
	}
		
	/// <summary>説明</summary>
	static bool Burn(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_BURN);
	}
	static bool Burn(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_BURN);
	}
		
	/// <summary>説明</summary>
	static bool Darken(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DARKEN);
	}
	static bool Darken(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_DARKEN);
	}
		
	/// <summary>説明</summary>
	static bool Diference(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DIFFERENCE);
	}
	static bool Difference(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_DIFFERENCE);
	}
		
	/// <summary>説明</summary>
	static bool Dodge(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_DODGE);
	}
	static bool Dodge(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_DODGE);
	}
		
	/// <summary>説明</summary>
	static bool Exclusion(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_EXCLUSION);
	}
	static bool Exclusion(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_EXCLUSION);
	}
		
	/// <summary>説明</summary>
	static bool HardLight(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_HARDLIGHT);
	}
	static bool HardLight(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_HARDLIGHT);
	}
		
	/// <summary>説明</summary>
	static bool Lighten(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_LIGHTEN);
	}
	static bool Lighten(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_LIGHTEN);
	}
		
	/// <summary>説明</summary>
	static bool Multiple(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_MULTIPLE);
	}
	static bool Multiple(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_MULTIPLE);
	}
	
	/// <summary>説明</summary>
	static bool Normal(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_NORMAL);
	}
	static bool Normal(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_NORMAL);
	}
		
	/// <summary>説明</summary>
	static bool OverLay(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_OVERLAY);
	}
	static bool OverLay(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_OVERLAY);
	}
		
	/// <summary>説明</summary>
	static bool RgbaSelectMix(Image *image ,const Image *imgA,const Image *imgB,double 合成率, RGBA selectR , RGBA selectG , RGBA selectB , RGBA selectA)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_RGBA_SELECT_MIX, selectR , selectG , selectB , selectA );
	}
	static bool RgbaSelect(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率, RGBA selectR , RGBA selectG , RGBA selectB , RGBA selectA)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_RGBA_SELECT_MIX, selectR , selectG , selectB , selectA );
	}
		
	/// <summary>説明</summary>
	static bool Screen(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlendBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_SCREEN);
	}
	static bool Screen(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_SCREEN);
	}
		
	/// <summary>説明</summary>
	static bool SoftLight(Image *image ,const Image *imgA,const Image *imgB,double 合成率)
	{
		return !DxLib::GraphBlend(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle(),int(合成率*255),DX_GRAPH_BLEND_SOFTLIGHT);
	}
	static bool SoftLight(Image *image ,const Image *imgA,const Image *imgB, int srcX1, int srcY1, int srcX2, int srcY2, int blendX, int blendY, int destX, int destY,double 合成率)
	{
		return !DxLib::GraphBlendRectBlt(imgA->GetHandle() , imgB->GetHandle() , image->GetHandle() , srcX1, srcY1, srcX2, srcY2, blendX, blendY, destX, destY,int(合成率*255),DX_GRAPH_BLEND_SOFTLIGHT);
	}
};
}