/***************************************************************/
//
//
//		DirectX	[locus.cpp]
//
//										Author	kazuki tanaka
//										Date	2016 07/08
/*---------------------------------------------------------------
■Update : 2016/0


/*---------------------------------------------------------------
	インクルードファイル
---------------------------------------------------------------*/
#include "main.h"
#include "locus.h"

#include "enemy.h"
#include "game_equation.h"

/*---------------------------------------------------------------
	マクロ定義
---------------------------------------------------------------*/
/*---------------------------------------------------------------
	定数定義
---------------------------------------------------------------*/
#define LOCUS_TEXTURENAME "data/TEXTURE/effect000.jpg"
//#define LOCUS_TEXTURENAME "data/TEXTURE/bullet000.jpg"


#define LOCUS_LIFE ( 100 )						// エフェクトの寿命

#define NUM_NUNBER ( 200 )

#define LOCUS_MAX (255*16)						// エフェクトの最大数
#define RELOAD_TIME (20)						// 装填時間:単位(秒/s)

#define LOCUS_RADIUS (30)						// 背景の半径

// エフェクト(軌跡)構造体
typedef struct{

	D3DXVECTOR2 center;							// 中心座標
	float       radius;							// オブジェクト半径
	D3DXCOLOR   color;							// 色情報
	float radiusValue;							// 半径の変化量
	float colorValue;							// 色の変化量
	unsigned int life;							// 寿命

}LOCUS;


/*---------------------------------------------------------------
	プロトタイプ宣言
---------------------------------------------------------------*/
HRESULT MakeVertexLocus(LPDIRECT3DDEVICE9 pDevice);
												// 頂点の作成
void SetVertexLocus( VERTEX_2D *pVtx , const int arrayPos );
												// エフェクトの設置
void SetColorLocus ( VERTEX_2D *pVtx , const int arrayPos );
												// 色の設定
/*----------------------------------------------------------------
	グローバル変数
----------------------------------------------------------------*/

LPDIRECT3DTEXTURE9 g_pTextureLocus=nullptr;	// テクスチャ-インターフェ-ス用

LPDIRECT3DVERTEXBUFFER9 g_pVtxBufferLocus=nullptr;
											// 頂点バッファインターフェースへのポインタ
LOCUS locuses[ LOCUS_MAX ] = {};			// エフェクト



// エフェクトの初期化
void InitLocus( void )
{

	LPDIRECT3DDEVICE9 g_pPD3DDevice=nullptr;	//デバイス受け取り用関数

	// デバイスの受け取り
	g_pPD3DDevice = GetDevice( );

	// 構造体の初期化
	for( int inc = 0; inc < LOCUS_MAX ; inc++ ){

		locuses[ inc ].radius = LOCUS_RADIUS;

		locuses[ inc ].color.a = 1.0f;
		locuses[ inc ].color.r = 1.0f;
		locuses[ inc ].color.g = 1.0f;
		locuses[ inc ].color.b = 1.0f;

		locuses[ inc ].life = 0;

	}

	// VERTEX_2Dの設定
	MakeVertexLocus( g_pPD3DDevice );

	// テクスチャの読み込み
	if(FAILED( D3DXCreateTextureFromFile( g_pPD3DDevice, LOCUS_TEXTURENAME, &g_pTextureLocus )))
	{
		MessageBox(NULL,"テクスチャのファイルの読み込みに失敗しました","失敗", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2);
	}

}

// エフェクトの終了処理
void UninitLocus( void )
{

	// テクスチャインターフェースの開放
	SAFE_RELEASE(g_pTextureLocus)

	// 頂点バッファインターフェースの開放
	SAFE_RELEASE(g_pVtxBufferLocus)


}

// エフェクトの更新
void UpdateLocus( void )
{

	VERTEX_2D *pVtx;											// 仮想アドレス
	D3DXVECTOR2 radius;											// 判定使用用半径

	// バッファをロックし仮想アドレスを取得する
	g_pVtxBufferLocus -> Lock(0,0,(void**)&pVtx,0);				// GPUからのVRAMへの操作をロックする


	// エフェクトの更新
	for( int inc = 0; inc < LOCUS_MAX; inc++ ){

		if( locuses[ inc ].life ){			

			//エフェクトの寿命の更新
			locuses[ inc ].life -= 1 ;

			
			// 色の設定
			locuses[ inc ].color.a -= locuses[ inc ].colorValue;
			if( locuses[ inc ].color.a < 0.0f ){
				locuses[ inc ].color.a = 0.0f;
			}
				
			// 頂点バッファにカラー情報の書き込み
			SetColorLocus( pVtx , inc );

			// 半径の更新と設定
			locuses[ inc ].radius -= locuses[ inc ].radiusValue;
			if( locuses[ inc ].radius < 0.0f ){
				locuses[ inc ].radius = 0.0f;
			}

			radius = D3DXVECTOR2( locuses[ inc ].radius, locuses[ inc ].radius);

			// 画面外防止処理
			if( __ObjectScreenOut( &locuses[ inc ].center, &radius )){
				
				locuses[ inc ].life = 0;
			} 


			// エフェクトの設置
			SetVertexLocus( pVtx , inc );
			
			
		}	//if( locuses[ inc ].life ) -> END
	}	// for -> END

	// バッファのアンロック
	g_pVtxBufferLocus->Unlock();

}

// エフェクトの描画
void DrawLocus( void )
{


	// デバイスの受け取り処理
	LPDIRECT3DDEVICE9 pDevice = GetDevice( );


	// 加算合成の設定
	pDevice ->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );			// 半透明処理
	pDevice ->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );		// 元のα
	pDevice ->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );			// 先のα


	// ストリーム
	pDevice ->SetStreamSource( 0,		
	g_pVtxBufferLocus,									// どの頂点バッファ―と結ぶか...
	0,													// データのオフセット
	sizeof(VERTEX_2D));									// ストライド値(バイト)

	// 頂点フォーマットの設定
	pDevice ->SetFVF( FVF_VERTEX_2D );

	// テクスチャの設定
	pDevice ->SetTexture( 0, g_pTextureLocus );	
	
	// ポリゴンの描画
	for( int index = 0; index < LOCUS_MAX ; index++ ){
		if( locuses[ index ].life ){
	
			pDevice ->DrawPrimitive( D3DPT_TRIANGLESTRIP, index*NUM_VERTEX, NUM_LOCUS );
	
		}
	}


	// 元の状態に戻す
	pDevice ->SetRenderState( D3DRS_ALPHABLENDENABLE,TRUE );			//半透明処理
	pDevice ->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );		//元のα
	pDevice ->SetRenderState( D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA );	//先のα


}

// 頂点の作成
HRESULT MakeVertexLocus( LPDIRECT3DDEVICE9 pDevice )
{


	VERTEX_2D *pVtx;									//仮想アドレス

	if(FAILED(pDevice->CreateVertexBuffer(
			sizeof(VERTEX_2D) * NUM_VERTEX * LOCUS_MAX,//確保するバッファサイズ(頂点数分確保) 単位:バイト
			D3DUSAGE_WRITEONLY,							//使用方法
			FVF_VERTEX_2D,								//使用する頂点フォーマット(特殊な処理をしない限り参照されないので0でよい)
			D3DPOOL_MANAGED,							//バッファの管理方法(バッファの中に書き込んだものの管理方法)
			&g_pVtxBufferLocus,						//格納するポインタ先
			NULL)))
	{

		MessageBox(NULL,"バッファへの書き込みに失敗しました!!","vertex buffer ERROR!!",MB_OK);
		return E_FAIL;
	}



	// バッファをロックし仮想アドレスを取得する
	g_pVtxBufferLocus -> Lock(0,0,(void**)&pVtx,0);		//GPUからのVRAMへの操作をロックする


	// 頂点座標の設定
	for( int inc = 0; inc < LOCUS_MAX ; inc++ ){

		SetVertexLocus( pVtx , inc );

		pVtx[0 + inc*4].rhw=1.0f;
		pVtx[1 + inc*4].rhw=1.0f;
		pVtx[2 + inc*4].rhw=1.0f;
		pVtx[3 + inc*4].rhw=1.0f;

		pVtx[0 + inc*4].color=D3DCOLOR_RGBA(255, 255, 255, 255);
		pVtx[1 + inc*4].color=D3DCOLOR_RGBA(255, 255, 255, 255);
		pVtx[2 + inc*4].color=D3DCOLOR_RGBA(255, 255, 255, 255);
		pVtx[3 + inc*4].color=D3DCOLOR_RGBA(255, 255, 255, 255);

	}
	// バッファのアンロック
	g_pVtxBufferLocus->Unlock();

	return S_OK;

}

// エフェクトの設置
void SetVertexLocus( VERTEX_2D *pVtx , const int arrayPos )
{


	D3DXVECTOR2 start,end;			// 始点と終点



	// 座標計算
	start.x = locuses[ arrayPos ].center.x - locuses[ arrayPos ].radius;
	start.y = locuses[ arrayPos ].center.y - locuses[ arrayPos ].radius;
	end.x = locuses[ arrayPos ].center.x + locuses[ arrayPos ].radius;
	end.y = locuses[ arrayPos ].center.y + locuses[ arrayPos ].radius;


	// 頂点座標の設定
	pVtx[0 + (arrayPos * NUM_VERTEX) ].pos = D3DXVECTOR3( start.x, start.y, 0.0f);
	pVtx[1 + (arrayPos * NUM_VERTEX) ].pos = D3DXVECTOR3( end.x,   start.y, 0.0f);
	pVtx[2 + (arrayPos * NUM_VERTEX) ].pos = D3DXVECTOR3( start.x, end.y,   0.0f);
	pVtx[3 + (arrayPos * NUM_VERTEX) ].pos = D3DXVECTOR3( end.x,   end.y,   0.0f);

	pVtx[0 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.0f , 0.0f );
	pVtx[1 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 1.0f , 0.0f );
	pVtx[2 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.0f , 1.0f );
	pVtx[3 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 1.0f , 1.0f );

	/*
	int inc =2;
	int i =0;

	pVtx[0 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.0f +(inc*0.17f), 0.0f +( i *0.5f ));
	pVtx[1 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.17f+(inc*0.17f), 0.0f +( i *0.5f ));
	pVtx[2 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.0f+(inc*0.17f), 0.5f +( i *0.5f ));
	pVtx[3 + (arrayPos * NUM_VERTEX) ].tex = D3DXVECTOR2( 0.17f+(inc*0.17f), 0.5f +( i *0.5f ));
	*/

}

// エフェクトの色変更関数
void SetColorLocus ( VERTEX_2D *pVtx , const int arrayPos )
{

	// αの変更
	pVtx[ 0 + (arrayPos * NUM_VERTEX) ].color = locuses[ arrayPos ].color;
	pVtx[ 1 + (arrayPos * NUM_VERTEX) ].color = locuses[ arrayPos ].color;
	pVtx[ 2 + (arrayPos * NUM_VERTEX) ].color = locuses[ arrayPos ].color;
	pVtx[ 3 + (arrayPos * NUM_VERTEX) ].color = locuses[ arrayPos ].color;

}

// エフェクトの発射
void SetLocus( const LPD3DXVECTOR2 pos, const float* radius, unsigned int life, D3DXCOLOR color )
{

	// エフェクトの設置
	for( int index = 0; index < LOCUS_MAX; index++ ){

		if( !locuses[ index ].life ){


			{ // effect 各種設定


				// エフェクトの発射位置
				locuses[ index ].center = (*pos);

				// エフェクトの半径
				locuses[ index ].radius = (*radius);

				// エフェクトの色情報
				locuses[ index ].color = color;

				// エフェクトの寿命の設定
				locuses[ index ].life = life;

				// エフェクト定数の設定
				locuses[ index ].colorValue = locuses[ index ].color.a / locuses[ index ].life;
				locuses[ index ].radiusValue = locuses[ index ].radius / locuses[ index ].life;


			} // -> Setting End 

			break;
		}
	}

}

// エフェクトの発射( VECTOR3用 )
void SetLocus( const LPD3DXVECTOR3 pos, const float radius, unsigned int life, D3DXCOLOR color )
{

	// エフェクトの設置
	for( int index = 0; index < LOCUS_MAX; index++ ){

		if( !locuses[ index ].life ){


			{ // effect 各種設定


				// エフェクトの発射位置
				locuses[ index ].center.x = (pos->x);
				locuses[ index ].center.y = (pos->y);

				// エフェクトの半径
				locuses[ index ].radius = radius;

				// エフェクトの色情報
				locuses[ index ].color = color;

				// エフェクトの寿命の設定
				locuses[ index ].life = life;

				// エフェクト定数の設定
				locuses[ index ].colorValue = locuses[ index ].color.a / locuses[ index ].life;
				locuses[ index ].radiusValue = locuses[ index ].radius / locuses[ index ].life;


			} // -> Setting End 

			break;
		}
	}

}


