/***************************************************************/
//
//
//		DirectX	[ gamesystem.h ]
//
//											Author	kazuki tanaka
//											Date	2017 1/26
/*---------------------------------------------------------------
■Update : 2017/1/26
			gamesystem.hの作成
			GAMESYSTEMの初期化処理の追加
			GAMESYSTEMの終了処理の追加
			GAMESYSTEMの更新処理の追加
			GAMESYSTEMの描画処理の追加

■Update : 2016/1/26



/*-------------------------------------------------------------*/
#ifndef _GAMESYSTEM_H_

#define _GAMESYSTEM_H_

#include "rendererdx9.h"

/*---------------------------------------------------------------
	マクロ定義
---------------------------------------------------------------*/

#define LIMIT_MAX(a,b) ( a>b ? b : a )				// 最大値の設定( 低い値を返す )
#define LIMIT_MIM(a,b) ( a>b ? a : b )				// 最小値の設定( 高い値を返す )

/*---------------------------------------------------------------
	class
---------------------------------------------------------------*/

// 計算便利関数クラス
class GameSystem
{
public:
	
	//#ifndef D3DXToRadian
	static inline float DegreeToRadian( float degree )
	{
		return  (float)((( degree ) * D3DX_PI ) / 180 );
	}
	//#endif // D3DXToRadian
	
	//#ifndef D3DXToDegree
	static inline float RadianToDegree( float radian )
	{
		return  (float)(( radian/ D3DX_PI ) * 180 );
	}
	//#endif // D3DXToDegree
	
	// dot Calc Angle
	static inline float VecDotAngle( const LPD3DXVECTOR3 source, const LPD3DXVECTOR3 vec ){

		D3DXVECTOR3 src( 0, 0, 0), ref( 0, 0, 0 );
		
		D3DXVec3Normalize( &src, source );
		D3DXVec3Normalize( &ref, vec );

		// ベクトルの大きさを算出
		float vecLengthStart = D3DXVec3Length( &src );
		float vecLengthEnd   = D3DXVec3Length( &ref );

		// ベクトルの内積算出
		float dot = D3DXVec3Dot( &src, &ref );

		float cos;
		if( (int)vecLengthStart == 0 || (int)vecLengthEnd == 0 ){
			cos = 0.0f;
		}else{
			cos = dot * ( vecLengthStart * vecLengthEnd );
		}

		// ベクトルのなす角算出
		float arc = acosf( cos );

		return arc;
	}

	// cube to cube Collision 
	static inline bool CollisionObjectCube( const LPD3DXVECTOR3 objectA_s ,const LPD3DXVECTOR3 objectA_e, const LPD3DXVECTOR3 objectB_s, const LPD3DXVECTOR3 objectB_e )
	{

		// CollisionRectAngle
		if( ( objectA_s->x < objectB_e->x )
			&& ( objectA_e->x > objectB_s->x )
			&& ( objectA_s->y < objectB_e->y )
			&& ( objectA_e->y > objectB_s->y )
			&& ( objectA_s->z < objectB_e->z )
			&& ( objectA_e->z > objectB_s->z ) ){

			return true;
		}

		return false;
	}

	// field to obj Collison
	static inline bool ObjectSquareField( const LPD3DXVECTOR3 objPosA, const LPD3DXVECTOR3 sizeA, const LPD3DXVECTOR3 objPosB, const LPD3DXVECTOR3 sizeB )
	{

		// coord, A,B
		D3DXVECTOR3 startA, endA, startB, endB;

		startA = D3DXVECTOR3( objPosA->x - sizeA->x, objPosA->y,            objPosA->z - sizeA->z );
		endA   = D3DXVECTOR3( objPosA->x + sizeA->x, objPosA->y + sizeA->y, objPosA->z + sizeA->z );
		startB = D3DXVECTOR3( objPosB->x - sizeB->x, objPosB->y,            objPosB->z - sizeB->z );
		endB   = D3DXVECTOR3( objPosB->x + sizeB->x, objPosB->y + sizeB->y, objPosB->z + sizeB->z );

		// CollisionRectAngle
		if( ( startA.x < endB.x )
			&& ( endA.x > startB.x )
			&& ( startA.y <= endB.y )
			&& ( endA.y >= startB.y )
			&& ( startA.z < endB.z )
			&& ( endA.z > startB.z )){
			return true;
		}

		return false;
	}

	// field to obj Collison
	static inline bool ObjectSquareField( LPD3DXVECTOR3 srcForce, const LPD3DXVECTOR3 src, const LPD3DXVECTOR3 srcSize, const LPD3DXVECTOR3 obj, const LPD3DXVECTOR3 objSize )
	{

		// coord, A,B
		D3DXVECTOR3 startA, endA, startB, endB, coord;
		bool flag = false;

		coord = *src + *srcForce;
		
		startA = D3DXVECTOR3( coord.x - srcSize->x, coord.y,              coord.z - srcSize->z );
		endA   = D3DXVECTOR3( coord.x + srcSize->x, coord.y + srcSize->y, coord.z + srcSize->z );
		startB = D3DXVECTOR3( obj->x - objSize->x,  obj->y,               obj->z - objSize->z );
		endB   = D3DXVECTOR3( obj->x + objSize->x,  obj->y + objSize->y,  obj->z + objSize->z );

		// CollisionRectAngle
		if( ( startA.x < endB.x )
			&& ( endA.x > startB.x )){
			flag = true;
			srcForce->x = 0.0f;
		}
		if(  ( startA.y <= endB.y )
			&& ( endA.y >= startB.y )){
			flag = true;
			srcForce->x = 0.0f;
		}
		if(  ( startA.z < endB.z )
			&& ( endA.z > startB.z )){
			flag = true;
			srcForce->x = 0.0f;
		}

		return flag;
	}



};



#endif	//	_GAMESYSTEM_H_


