#include "GShot.h"

#ifdef _DXLIB
#include "GStaticDataDX.h"
#else
#include "GStaticData.h"
#endif

using namespace GEnum;

GShot::GShot( int t ): HPLShot( t ) {
	// スプライト登録
	this->setSprite( getStaticData()->getSprite( GEnum::SpriteType::SHOT )->clone() );

	//////
	// デフォルト設定

	this->m_bIsAliveAfterHit = false;	// ヒット後消滅	
	this->m_bIsBounceToNoHit = false;	// バウンド後も当たる

//	this->m_aryObjectAttribute[ObjectAttribute::GRAVITY] = false;
	this->setObjectAttribute( ObjectAttribute::HIT_TO_BLOCK, true );
	this->setObjectAttribute( ObjectAttribute::HIT_TO_PLAYER, true );
	this->setObjectAttribute( ObjectAttribute::HIT_TO_ENEMY, true );
//	this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_BLOCK] = true;
//	this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_PLAYER] = true;
//	this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_ENEMY] = true;
//	this->setGravity(false);		// 重力の影響を受けない
//	this->setHitToBlock(true);		// ブロックに接触する
//	this->setHitToPlayer(true);		// プレイヤーにヒットしない
//	this->setHitToEnemy(true);		// 敵にヒットする

	/*if( this->isBoundShot() ) {
		// バウンドする弾
		this->setGravity( true );
	}*/

	// デフォルト（BULLET）
	this->setSize(32,32);
	this->setHitRect(6,13,12,10);

	if( t == ShotType::BULLET ) {
		// do nothing
	} else if( t == ShotType::SLASH ) {			// ペセル
		this->setSize(128,104);
		this->setHitRect(9,2,115,99);
		this->setHitToBlock(false);

	} else if( t == ShotType::BEAM ) {			// 目からビーム
		this->setSize(400,96);
		this->setHitRect(0,50,344,10);
		this->setHitToBlock(false);

	} else if( t == ShotType::FIRE_BALL ) {		// 火の玉
		this->setSize(32,32);
		this->setHitRect(5,5,20,20);

	} else if( t == ShotType::SWORD_SLASH ||	// トリラーマの剣
		t == ShotType::ONLY_SLASH)				// デュランダナの剣、ターニャのバール
	{
		this->setSize(64,96);
		this->setHitRect(10,7,44,80);
		this->setHitToBlock(false);

	} else if( t == ShotType::ODORO ) {			// 沼下級
		this->setSize(96,96);
		this->setHitRect(7,8,81,78);
		this->setHitToBlock(false);

	} else if( t == ShotType::THUNDER_BOLT ) {
		this->setSize(32,480);
		this->setHitRect(5,0,21,474);
		this->setHitToBlock(false);

	} else if( t == ShotType::MISSILE ) {
		this->setHitRect(10,12,10,10);

	} else if( t == ShotType::EXPLOSION ) {
		this->setSize(72,96);
		this->setHitRect(8,27,54,43);

		/////
		// 爆発音
		//getStaticData()->getMixerManager()->playSE(
		//	TTEnum::SE::Bosu00, TTEnum::SEChannel::Slash, 1);

	} else if( t == ShotType::PINE_APPLE_0 ||
		t == ShotType::PINE_APPLE_1)
	{
		this->setObjectAttribute( ObjectAttribute::GRAVITY, true );
		this->setObjectAttribute( ObjectAttribute::HIT_TO_ENEMY, true );
//		this->m_aryObjectAttribute[ObjectAttribute::GRAVITY] = true;
//		this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_ENEMY] = false;
//		this->setGravity( true );
//		this->setHitToEnemy( false );

		// 直撃有り
		this->setObjectAttribute( ObjectAttribute::HIT_TO_PLAYER, t == ShotType::PINE_APPLE_0 ?
			true: false );
//		this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_PLAYER] = 
		//this->setHitToPlayer(
		;
		//);
		this->m_bIsBounceToNoHit = t == ShotType::PINE_APPLE_0 ?
			true: false;
		
	} else if( t == ShotType::RYUHA_1 ) {
		this->setSize(300,96);
		this->setHitRect(59,18,165,60);
		this->setHitToBlock(false);
	} else if( t == ShotType::RYUHA_2 ) {
		this->setSize(198,300);
		this->setHitRect(21,94,158,203);
		this->setHitToBlock(false);
	} else if( t == ShotType::SAUCER ) {
		// same as default
	} else if( t == ShotType::FRAME_THROWER_FIRE ) {
		this->setHitRect(6,8,18,18);
		this->setHitToBlock(false);
	}

}


GShot::~GShot() {
}

/////////////////////////////////////////////////////
// override
void GShot::changeState(int st){
	int oldSt = this->getState()->getState();

	if(oldSt != st){
		this->getSequence()->resetCounter();
	}

	this->getState()->setState(st);

}

HPLSequence* GShot::getSequence(){
	HPLSequence* seq = NULL;
#ifdef _DXLIB
	seq = this->getSprite()->getPair(this->getSequenceID())->left;
#else
	if(this->getFaceDirection() == FaceDirection::LEFT){
		seq = this->getSprite()->getPair(this->getSequenceID())->left;
	}else{
		seq = this->getSprite()->getPair(this->getSequenceID())->right;
	}
#endif
	return seq;
}
int GShot::getSequenceID(){

	return getStaticData()->m_ObjectManager.m_ShotManager.getSequenceID( this->getType() );
}

#ifdef _DXLIB
void GShot::draw(){
#else
void GShot::draw(HPLSDLImageManager* imageManager){
#endif
	HPLScroller* scroller = getStaticData()->getScrollManager()->getScroller(0);
	float left = this->getArea().getX() + scroller->getVirtualRect().getX();
	float top = this->getArea().getY() + scroller->getVirtualRect().getY();
	float fCenterX = this->getCenter().getX() + scroller->getVirtualRect().getX();
	float fCenterY = this->getCenter().getY() + scroller->getVirtualRect().getY();
	float fZoom = scroller->m_fZoomRate;
	fCenterX *= fZoom;
	fCenterY *= fZoom;

	HPLSequence* seq = this->getSequence();

	float rotate = 0;
	int alpha = 255;

	float zoom = 1;

	if(getStaticData()->m_CommonWork.m_Game.isCheat()){
#ifdef _DXLIB
#else
		getStaticData()->fillRect(
			(int)(left + this->getHitRect().getX()),
			(int)(top + this->getHitRect().getY()),
			(int)(this->getHitRect().getWidth()),
			(int)(this->getHitRect().getHeight()),
			255,0,0);
#endif
	}

	float rate = 1;
	float zoomx = rate;
	float zoomy = rate;

#ifdef _DXLIB
	getStaticData()->m_Basic.m_Graphics.draw(
		fCenterX, fCenterY, seq,
		this->getFaceDirection(), rotate, fZoom );
#else
	HPLSDLImageTool::blitRotozoomSpriteLeftTop(
		left, top, rotate, seq, imageManager,
		getStaticData()->getGraphics()->getScreen(), alpha,
		rate, rate);
#endif

	if(getStaticData()->m_CommonWork.m_Game.isTheWorld() == false){
		seq->step();
	}
}

/*
bool GShot::collision(HPLMatrix<int>* lpBlockMatrix,
			   std::map<int, HPLBlock*>* lpBlockMap )
{
	// TODO


	const float RESIST = getStaticData()->getSetting()->resist;
	const float GRAVITY = getStaticData()->getSetting()->gravity;
	// 自由落下最大速度（空気抵抗とのつりあい）
	const float FALL_MAX_SPEED = getStaticData()->getSetting()->fallMaxSpeed;

	
	int tileSize = getStaticData()->getSetting()->tileSize;
	

	HPLRect hitArea = getHitArea();
	HPLVector velocityAngle = getVelocityAngle();
	HPLVector center = getCenter();

	bool hitBlock = false;

	if( isHitToBlock() ){
		{
			CollisionState stateX = HPLCollisionTool::adjustCollisionX(
				hitArea.getWidth(),
				hitArea.getHeight(),
				hitArea.getX(), hitArea.getY(),
				velocityAngle.getX(), velocityAngle.getY(),
				lpBlockMatrix, tileSize, 
				*lpBlockMap, this->m_nSlopePreviousTileCoordX,this->m_nSlopePreviousTileCoordY);

			bool isTouch = stateX.m_nTouchBlockID != 0;
			
			this->getTrigger()->setTrigger(TriggerType::HIT_TO_THE_LEFT,
				isTouch && stateX.isHitX == HitDirectionX::LEFT);
			this->getTrigger()->setTrigger(TriggerType::HIT_TO_THE_RIGHT,
				isTouch && stateX.isHitX == HitDirectionX::RIGHT);
			///////
			// 横方向にぶつかった
			if(isTouch){
				center.setX(stateX.m_nNewX);
				//hitArea.setX(hitArea.getX() + stateX.fixDeltaX);

				if(this->isBoundWhenHitToBlock()){
					float fRate = 1;
					if( this->getType() == ShotType::PINE_APPLE_0 ||
						this->getType() == ShotType::PINE_APPLE_1 )
					{
						fRate = 0.7f;
					}

					velocityAngle.setX(- velocityAngle.getX() * fRate);

				}

				if(isHitToBlock() && isDieWhenHitToBlock()){
					setAlive(false);
				}
					hitBlock = true;
			}else{
			}
			//
			///////

			this->setCenter( center );
		}
		{
			
			hitArea = this->getHitArea();

			CollisionState stateY = HPLCollisionTool::adjustCollisionY(
				hitArea.getWidth(), hitArea.getHeight(),
				hitArea.getX(), hitArea.getY(),
				velocityAngle.getX(), velocityAngle.getY(),
				lpBlockMatrix, tileSize, 
				*lpBlockMap, this->m_nSlopePreviousTileCoordX,this->m_nSlopePreviousTileCoordY);
			// 修正量
			bool isTouch = stateY.m_nTouchBlockID != 0;
			this->getTrigger()->setTrigger(TriggerType::ON_THE_GROUND,
				isTouch && stateY.isHitY == HitDirectionY::BOTTOM);
			this->getTrigger()->setTrigger(TriggerType::HIT_TO_THE_CEILING,
				isTouch && stateY.isHitY == HitDirectionY::TOP);

			if(isTouch){
				// 触れている
				center.setY(stateY.m_nNewY);
				//hitArea.setY(hitArea.getY() + stateY.fixDeltaY);


				if(this->isBoundWhenHitToBlock()){
					const float EPS = 0.7f;
					velocityAngle.setY((float)(-fabs(velocityAngle.getY()) * EPS));
				}
				{
					if(stateY.isHitY == HitDirectionY::BOTTOM){
						//velocityAngle.setY(0);
						////
						// 減速(X)

						float fRate = 1.f;
						if( this->getType() == ShotType::PINE_APPLE_0 ||
							this->getType() == ShotType::PINE_APPLE_1 )
						{
							fRate = 1.f;
						}

						velocityAngle.setX(HPLActionMoveTool::reduceSpeed(
							RESIST * fRate,
							velocityAngle.getX()));

					}else{
						velocityAngle.setY(0);
					}
				}

				if(isHitToBlock() && isDieWhenHitToBlock()){
					setAlive(false);
				}
				hitBlock = true;

			}else{

				/////
				// 特殊な弾を除いて重力の影響は受けない
				if(this->m_aryObjectAttribute[ObjectAttribute::GRAVITY] == true){
					velocityAngle.setY(velocityAngle.getY() + GRAVITY);
				}else{
				}
			}
		}
	}

	if( hitBlock ) {
		if( m_bIsBounceToNoHit ) {
			this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_ENEMY] = false;// setHitToEnemy( false ) ;
			this->m_aryObjectAttribute[ObjectAttribute::HIT_TO_PLAYER] = false;// setHitToPlayer( false ) ;
		}
	}
	center.add(velocityAngle);

	setCenter(center);
	setVelocityAngle(velocityAngle);


	//HPLActionMoveTool::checkGroundAtTheFaceDirection((HPLShootingObject*)this,
	//	getStaticData()->getBlockManager(), tileSize);
	
	return hitBlock;
}
*/
void GShot::die(HPLShootingObject* damageSource){
}

void GShot::damage(float dmg, HPLShootingObject* damageSource){
}

/*
bool GShot::isBoundShot(){
	int t = this->getType();

	return false;
}*/

/*bool GShot::isDisappearWhenHit(){
	int t = this->getType();

	return true;
}*/

/** 殴り攻撃か？
  */
/*bool GShot::isBlowShot() {
	int t = this->getType();
	return t == ShotType::SLASH;
}*/

bool GShot::isDieWhenHitToBlock(){
	int t = this->getType();
	return t == ShotType::FIRE_BALL ||
		t == ShotType::BULLET;


}

bool GShot::isBoundWhenHitToBlock(){
	int t = this->getType();
	return t == ShotType::PINE_APPLE_0 ||
		t == ShotType::PINE_APPLE_1;
}
