#include "GPlayer.h"

#include "../game/GStaticData.h"

////
// 頭上表示delta (y軸)
const float HEAD_UP_RADIUS = 60;

/////
// draw mana cards
HPLRect MANA_CARD_SRC_RECT(0,0,20,32);

GPlayer::GPlayer(int t): HPLPlayer(t){
	
	setObjectType(ObjectType::PLAYER);
	setFaceDirection(FaceDirection::RIGHT);


/*	undelsenSprite = staticData->getImageSetContainer()->getSprite(GEnum::SpriteType::Undelsen)->clone();
	durandanaSprite = staticData->getImageSetContainer()->getSprite(GEnum::SpriteType::Durandana)->clone();
	setSprite(undelsenSprite);
	if(t == PlayerType::Durandana){
		setSprite(durandanaSprite);
	}*/

	setSprite(staticData->getImageSetContainer()->getSprite(GEnum::SpriteType::Udonge)->clone());


	int numMax = 1;
	HPLJumpManager* jm = new HPLJumpManager(numMax);
	this->setJumpManager(jm);

	setHitRect(76,70,53,133);
	setSize(204,204);

	setSequenceID(0);

	setBind(false);
	setHeld(false);
	//aibo = NULL;

	//manaCardRotateCounter = new HPLCounter(60);

	/////
	// テストマナカード
	
	/*
	for(int i = 0; i < 5; i ++){
		int chargeMax = 30;
		GManaCard card(i, chargeMax);
		this->manaCardList.push_back(card);
	}

	selectedManaCardIndex = 0;
	isManaCardLight = true;
	manaCardBlinkCounter = new HPLCounter(2);

	isChargeLight = true;

	setCharging(false);

	mabatakiCounter = new HPLCounter(40);
*/

	oldID = GEnum::Udonge::STAND;
	groundY = 0;

}

GPlayer::~GPlayer(){
/*	delete mabatakiCounter;
	delete manaCardBlinkCounter;

	setSprite(undelsenSprite);
	if(aibo != NULL){
		delete aibo;
	}
	delete durandanaSprite;*/
	//delete manaCardRotateCounter;
}

void GPlayer::die(HPLShootingObject* damageSource){
	changeState(StateType::DEAD);
	setAlive(false);
}

/**
	@param dmg ダメージ量
	@param damageSource ダメージ源となるオブジェクト
*/
void GPlayer::damage(float dmg, HPLShootingObject* damageSource,
					  bool isInv, int nextState){
	float oldHP = getHP();

	setHP(oldHP - dmg);
	

	if(oldHP > 0 && getHP() <= 0){
		die(damageSource);
	}else{
		startInvinsible();
		changeState(nextState);
	}
}

void GPlayer::draw(HPLSDLImageManager* imageManager){

	if(getState()->getState() == StateType::DISAPPEAR){
		return;
	}


	HPLScroller* scroller = staticData->getScrollManager()->getScroller(0);


	// draw shadow
	{
		float rotateAngle = 0;
		HPLSequence* seq = staticData->getSequence(GEnum::SpriteType::Common,
			GEnum::Common::Shadow);

		float w = seq->getImageInformation(0)->srcRect.getWidth();
		float h = seq->getImageInformation(0)->srcRect.getHeight();
		float left = getCenter().getX() - w / 2;
		float top = getArea().getBottom() - h / 2;

		int alpha = 180;
		HPLSDLImageTool::blitRotozoomSpriteLeftTop(
			left, top, rotateAngle, seq, imageManager,
			staticData->getGraphics()->getScreen(), alpha);

	}

	float left = this->getArea().getX() + scroller->getVirtualRect().getX();
	float top = this->getArea().getY() + scroller->getVirtualRect().getY();
	float rotateAngle = 0;

	HPLSequence* seq = this->getSequence();
	//this->setHitRect(seq->getHitRect());

	int alpha = 255;
	if(isInvinsible()){
		alpha = 180;
	}

	/////
	// hit areaの矩形表示

/*	staticData->fillRect(
		left + this->getHitRect().getX(),
		top + this->getHitRect().getY(),
		this->getHitRect().getWidth(),
		this->getHitRect().getHeight(),
		255,0,0);
//		*/

	HPLSDLImageTool::blitRotozoomSpriteLeftTop(
		left, top, rotateAngle, seq, imageManager,
		staticData->getGraphics()->getScreen(), alpha);

	if(staticData->getGame()->isTheWorld() == false){
		seq->step();
	}

	HPLSDLKanjiManager* sdlkanji = staticData->getSDLKanjiManager();


	//////
	// シーケンス情報を表示
	{

		std::vector<std::string> messages;

		HPLImageInformation* info = seq->getImageInformation();
		
		messages.push_back(HPLString::chrToStr(
			"フレーム      [%5d/%5d]",
			seq->getFrameIndex(), seq->getNumberOfFrames()
			));
		messages.push_back(HPLString::chrToStr(
			"繰り返し回数  [%5d]",
			seq->getLoopNumMax()
			));
		messages.push_back(HPLString::chrToStr(
			"無限ループ    [%3s]",
			seq->getLoopNumMax() < 0 ? "YES": "NO"
			));

		char seqNameList[][20] ={
			"立ち",

			"歩き準備",
			"歩き",
			"ブレーキング",

			"ジャンプ準備",
			"上昇",
			"下降",
			"着地",

			"しゃがみ",

			"ダメージ通常",
			"ダメージ腹",
			"ダメージ腹2",
			"ダメージ腹3",
			"ダメージ腹4",
			"ダメージ強",
			"ダメージ通常＋α",

			"機械",
			"機械2",

			"ラミア",
			"ラミア2",

			"触手",
		};
		messages.push_back(HPLString::chrToStr(
			"シーケンス    [%5d:%3s]",
			getSequenceID(),
			(seqNameList[getSequenceID()])
			));

		float STEP_Y = 20;
		int r = 255, g = 255, b = 255;
		int fontID = 0;
		for(int i = 0; i < messages.size(); i ++){
			float left = 10;
			float top = 10 + i * STEP_Y;
			sdlkanji->drawString(staticData->getGraphics()->getScreen(),
				left, top, fontID, r, g, b, messages[i].c_str());
		}
	}
	
	
/*	/////
	// draw list 左上の一覧
	if(this->getType() == PlayerType::Undelsen){


		float MANA_CARD_LIST_LEFT = 10;
		float MANA_CARD_LIST_INTERVAL_X = 30;
		float HP_BAR_TOP = 10;
		float MANA_CARD_LIST_TOP = HP_BAR_TOP + 30;

		///////
		// HPバー表示
		{
			float WIDTH = 100;
			float HEIGHT = 10;

			float left = MANA_CARD_LIST_LEFT;
			float top = HP_BAR_TOP;

			///
			// 枠
			staticData->fillRect(
				left - 1,
				top - 1,
				WIDTH + 2,
				HEIGHT + 2,
				255,255,255);

			/////
			// 背景色
			staticData->fillRect(
				left,
				top,
				WIDTH,
				HEIGHT,
				80,0,0);

			float w = WIDTH * getHP() / getHPMax();
			staticData->fillRect(
				left,
				top,
				w,
				HEIGHT,
				255,0,0);
		}


		for(int i = 0; i < (int)manaCardList.size(); i ++){
			rotateAngle = 0;
			alpha = 255;

			left = MANA_CARD_LIST_LEFT + i * MANA_CARD_LIST_INTERVAL_X;
			top = MANA_CARD_LIST_TOP;


			int seqID = GEnum::Common::UnselectedMana;
			if(selectedManaCardIndex == i){
				seqID = GEnum::Common::Mana;
			}
			seq = staticData->getSequence(GEnum::SpriteType::Common, seqID);

			seq->getImageInformation(0)->srcRect = 
				HPLRect(manaCardList[i].getType() * MANA_CARD_SRC_RECT.getWidth(), 0, MANA_CARD_SRC_RECT.getWidth(), MANA_CARD_SRC_RECT.getHeight());


			HPLSDLImageTool::blitRotozoomSpriteLeftTop(
				left, top, rotateAngle,
				seq,
				imageManager,
				staticData->getGraphics()->getScreen(), alpha);
		}


		/////
		// 頭上に表示。
		if(isAlive()){
			drawHeadUpMana(imageManager);
			////
			// チャージ表示
			if(isCharging()){
				drawCharge(imageManager);
			}
		}

	}
	*/
/*	if(manaCardRotateCounter->isAlive() == false){
		manaCardRotateCounter->reset();
	}

	if(manaCardList.size() > 0){
		float rotateDegree = 360.f * (float)manaCardRotateCounter->getStepCounter() / (float)manaCardRotateCounter->getImageInformation(0)->waitFrame;
		float cardDeltaDegree = 360.f / (float)manaCardList.size();
		for(int i = 0; i < manaCardList.size(); i ++){
			float degree = rotateDegree + cardDeltaDegree * i;
			HPLVector center;
			if(degree == 0){
				degree = 1.f;
			}
			center.setByDegree(degree);
			center.multiple(HEAD_UP_RADIUS);
			center.add(getCenter());

			rotateAngle = 0;
			alpha = 255;
			left = center.getX() - MANA_CARD_SRC_RECT.getWidth() / 2;
			top = center.getY() - MANA_CARD_SRC_RECT.getHeight() / 2;

			seq = staticData->getSequence(GEnum::SpriteType::Common, GEnum::Common::Mana);

			seq->getImageInformation(0)->srcRect = 
				HPLRect(i * MANA_CARD_SRC_RECT.getWidth(), 0, MANA_CARD_SRC_RECT.getWidth(), MANA_CARD_SRC_RECT.getHeight());


			HPLSDLImageTool::blitRotozoomSpriteLeftTop(
				left, top, rotateAngle,
				seq,
				imageManager,
				staticData->getGraphics()->getScreen(), alpha);
		}
	}
	manaCardRotateCounter->step();*/
}
/*
void GPlayer::drawHeadUpMana(HPLSDLImageManager* imageManager){

	HPLScroller* scroller = staticData->getScrollManager()->getScroller(0);
	HPLSequence* seq = this->getSequence();
	float left = getCenter().getX() - MANA_CARD_SRC_RECT.getWidth() / 2 + scroller->getVirtualRect().getX();
	float top = getCenter().getY() - HEAD_UP_RADIUS - MANA_CARD_SRC_RECT.getHeight() / 2 + scroller->getVirtualRect().getY();
	float rotateAngle = 0;
	int alpha = 255;




	/////
	// 背景色
	{
		int seqID = GEnum::Common::UnselectedMana;
		seq = staticData->getSequence(GEnum::SpriteType::Common, seqID);

		seq->getImageInformation(0)->srcRect = 
			HPLRect(manaCardList[selectedManaCardIndex].getType() * MANA_CARD_SRC_RECT.getWidth(), 0, MANA_CARD_SRC_RECT.getWidth(),
			MANA_CARD_SRC_RECT.getHeight());


		HPLSDLImageTool::blitRotozoomSpriteLeftTop(
			left, top, rotateAngle,
			seq,
			imageManager,
			staticData->getGraphics()->getScreen(), alpha);
	}

	magic.addByTime();


	// 倍率で掛け算して高さを求める
	float h = (float)MANA_CARD_SRC_RECT.getHeight() * magic.getPoint() / magic.getPointMax();

	// MAXモード！→点滅
	if(magic.isReady()){

		manaCardBlinkCounter->step();

		if(manaCardBlinkCounter->isAlive() == false){
			manaCardBlinkCounter->reset();
			isManaCardLight = !isManaCardLight;
		}

	}else{
		// 通常時→常に点灯
		isManaCardLight = true;
	}

	if(isManaCardLight && magic.getPoint() > 0){
		/////
		// 通常
		top = getCenter().getY() - HEAD_UP_RADIUS - MANA_CARD_SRC_RECT.getHeight() / 2 + (MANA_CARD_SRC_RECT.getHeight() - h) + scroller->getVirtualRect().getY();

		int seqID = GEnum::Common::Mana;
		seq = staticData->getSequence(GEnum::SpriteType::Common, seqID);

		seq->getImageInformation(0)->srcRect = 
			HPLRect(
			manaCardList[selectedManaCardIndex].getType() * MANA_CARD_SRC_RECT.getWidth(), 
			MANA_CARD_SRC_RECT.getHeight() - h,
			MANA_CARD_SRC_RECT.getWidth(),
			h);


		HPLSDLImageTool::blitRotozoomSpriteLeftTop(
			left, top, rotateAngle,
			seq,
			imageManager,
			staticData->getGraphics()->getScreen(), alpha);
	}
}

void GPlayer::drawCharge(HPLSDLImageManager* imageManager){
	HPLScroller* scroller = staticData->getScrollManager()->getScroller(0);
	HPLSequence* seq = this->getSequence();
	float HEIGHT_MAX = MANA_CARD_SRC_RECT.getHeight();
	float WIDTH = 10;
	float CHARGE_LEFT_DELTA = -50;

	//////
	// 枠表示
	{
		float left = getCenter().getX() + CHARGE_LEFT_DELTA - 1 + scroller->getVirtualRect().getX();
		float top = getCenter().getY() - HEAD_UP_RADIUS - MANA_CARD_SRC_RECT.getHeight() / 2 - 1 + scroller->getVirtualRect().getY();

		staticData->fillRect(
			left,
			top,
			WIDTH + 2,
			HEIGHT_MAX + 2,
			255,255,255);
	}

	/////
	// 背景表示
	int col[][3] ={
		{255,0,0},
		{0,0,255},
		{0,255,0},
		{255,255,0},
		{255,0,255},
	};
	int BACKGROUND_COLOR_RATE = 0.5;

	{
		float left = getCenter().getX() + CHARGE_LEFT_DELTA + scroller->getVirtualRect().getX();
		float top = getCenter().getY() - HEAD_UP_RADIUS - MANA_CARD_SRC_RECT.getHeight() / 2 + scroller->getVirtualRect().getY();

		staticData->fillRect(
			left,
			top,
			WIDTH,
			HEIGHT_MAX,
			col[getSelectedManaCardIndex()][0] * BACKGROUND_COLOR_RATE,
			col[getSelectedManaCardIndex()][1] * BACKGROUND_COLOR_RATE,
			col[getSelectedManaCardIndex()][2] * BACKGROUND_COLOR_RATE
			);
	}

	//////
	// 前景色

	if(getSelectedManaCard()->getCharge() == getSelectedManaCard()->getChargeMax()){
		isChargeLight = !isChargeLight;
	}else{
		isChargeLight = true;
	}
	if(isChargeLight){
		int h = (int)((float)HEIGHT_MAX * (float)getSelectedManaCard()->getCharge() /
				(float)getSelectedManaCard()->getChargeMax());
		float left = getCenter().getX() + CHARGE_LEFT_DELTA + scroller->getVirtualRect().getX();
		float top = getCenter().getY() - HEAD_UP_RADIUS - MANA_CARD_SRC_RECT.getHeight() / 2 + (HEIGHT_MAX - h) + scroller->getVirtualRect().getY();

		staticData->fillRect(
			left,
			top,
			WIDTH,
			h,
			col[getSelectedManaCardIndex()][0],
			col[getSelectedManaCardIndex()][1],
			col[getSelectedManaCardIndex()][2]
			);


	}

	HPLSDLKanjiManager* sdlkanji = staticData->getSDLKanjiManager();
	//////
	// 仮：チャージ状況表示
	int fontID = 0;
	int r = 255, g = 255, b = 0;
	
	sdlkanji->drawString(staticData->getGraphics()->getScreen(),
		100, 5, fontID, r,g,b,
		"チャージ！：%d/%d", (int)getSelectedManaCard()->getCharge() , (int)getSelectedManaCard()->getChargeMax());
}

*/

/**
	自然落下、障害物接触判定
*
void GPlayer::collision(HPLMatrix<int>* matrix,
	std::map<int, HPLBlock*>* blockMap){


	// TODO

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

	int tileSize = staticData->getSetting()->tileSize;
	
	CollisionState states[2];

	HPLCollisionTool::commonCollision((HPLShootingObject*)this,
		matrix, tileSize,
		blockMap,
		states,
		GRAV, RESIST, FALL_MAX_SPEED);

	HPLActionMoveTool::checkGroundAtTheFaceDirection((HPLShootingObject*)this,
		staticData->getBlockManager(), tileSize);

	if(getTrigger()->getTrigger(TriggerType::ON_THE_GROUND)){
		getJumpManager()->resetJumpNumMax();
	}
	
}*/

HPLSequence* GPlayer::getSequence(){
	int seqID = getSequenceID();
	HPLSequence* seq = getSprite()->getPair(seqID)->left;
	if(getFaceDirection() == FaceDirection::RIGHT){
		seq = getSprite()->getPair(seqID)->right;
	}

	return seq;
}

int GPlayer::getSequenceID(){

//	return seqID;
	int id = GEnum::Udonge::STAND;

	int st = getState()->getState();

//	id = GEnum::Undelsen::STAND;

	if(st == StateType::FLYDOWN || st == StateType::FLYUP){
		id = GEnum::Udonge::FLYUP;

		if(getVelocityAngle().getY() > staticData->getSetting()->flydownSpeedThreshold){
			id = GEnum::Udonge::FLYDOWN;
		}
	}else if(st == StateType::WALK){
		id = GEnum::Udonge::WALK;
	}else if(st == StateType::CROUCH){
		id = GEnum::Udonge::CROUCH;
	}else if(st == StateType::CROUCH_2){
		id = GEnum::Udonge::CROUCH_2;
	}else if(st == StateType::WALK_READY){
		id = GEnum::Udonge::READY_TO_WALK;
	}else if(st == StateType::READY_TO_JUMP){
		id = GEnum::Udonge::READY_TO_JUMP;
	}else if(st == StateType::BREAK){
		id = GEnum::Udonge::BREAK;
	}else if(st == StateType::SET_ON_THE_GROUND){
		id = GEnum::Udonge::SET_ON_THE_GROUND;

	}else if(st == StateType::ATTACK){
//		id = GEnum::Udonge::ATTACK;
	}else if(st == StateType::DAMAGE){
		id = GEnum::Udonge::DAMAGE;
	}else if(st == StateType::DAMAGE_FLYDOWN){
		id = oldID;
//		id = GEnum::Udonge::DAMAGE_FLYDOWN;
	}else if(st == StateType::DAMAGE_FLYDOWN_REVERSE){
		id = oldID;
//		id = GEnum::Udonge::DAMAGE_FLYDOWN_REVERSE;
	}else if(st == StateType::DAMAGE_ELEC){
		id = oldID;
//		id = GEnum::Udonge::DAMAGE_ELEC;
	}else if(st == StateType::DEAD){
		id = GEnum::Udonge::DAMAGE_A_4;
	}else if(st == StateType::DEAD_FLYDOWN){
		id = GEnum::Udonge::DAMAGE_A_4;
//		id = GEnum::Udonge::DEAD_FLYDOWN;
	}else if(st == StateType::DEAD_FLYUP){
		id = GEnum::Udonge::DAMAGE_A_4;
//		id = GEnum::Udonge::DEAD_FLYUP;

	}else if(st == StateType::DAMAGE_A){
		id = GEnum::Udonge::DAMAGE_A;

	}else if(st == StateType::DAMAGE_A_2){
		id = GEnum::Udonge::DAMAGE_A_2;
	}else if(st == StateType::DAMAGE_A_3){
		id = GEnum::Udonge::DAMAGE_A_3;
	}else if(st == StateType::DAMAGE_A_4){
		id = GEnum::Udonge::DAMAGE_A_4;

	}else if(st == StateType::DAMAGE_B){
		id = GEnum::Udonge::DAMAGE_B;
	}else if(st == StateType::DAMAGE_C){
		id = GEnum::Udonge::DAMAGE_C;
	}
	

	oldID = id;
	////
	// 特殊
	// なし
	return id;
}


void GPlayer::changeState(int st){

	int oldSt = getState()->getState();
	//////
	// 死亡時は異なるシーケンスにする
	if(this->isAlive() ){
	}else if(st != StateType::DISAPPEAR && 
		st != StateType::BROKEN){
		/////
		// 死亡
		if(oldSt == StateType::STAND || oldSt == StateType::WALK){
			st = StateType::DEAD;
		}
	}

	if(oldSt != st){
		this->getSequence()->resetCounter();
		printf("%d\t->\t%d\n",oldSt, st);
	}

	setState(st);
}

int GPlayer::rollBackState(){
	if(this->getTrigger()->getTrigger(TriggerType::ON_THE_GROUND)){
		this->changeState(StateType::STAND);
	}else{
		if(this->getVelocityAngle().getY() > staticData->getSetting()->flydownSpeedThreshold){
			this->changeState(StateType::FLYDOWN);
		}else{
			this->changeState(StateType::FLYUP);
		}
	}
	return this->getState()->getState();
}

/*void GPlayer::processMabataki(){
	int st = this->getState()->getState();
	if(st == StateType::STAND || st == StateType::CROUCH){
		mabatakiCounter->step();
		if(this->isBoring()){
			printf("boring start\n");
			int nextSt = StateType::BORING;
			if(st == StateType::CROUCH){
				printf(" boring-crouch\n");
				nextSt = StateType::BORING_CROUCH;
			}
			this->changeState(nextSt);
		}


	}else if(st == StateType::BORING || st == StateType::BORING_CROUCH){
		if(this->getSequence()->getState().isFinishAnimation){
			printf("boring end\n");

			int nextSt = StateType::STAND;

			if(st == StateType::BORING_CROUCH){
				printf(" boring-crouch\n");
				nextSt = StateType::CROUCH;
			}
			this->changeState(nextSt);
			mabatakiCounter->reset();
		}
	}
}
*/
void GPlayer::setType(int t){
	HPLPlayer::setType(t);

	/////
	// スプライト変更
	/*
	if(t == PlayerType::Undelsen){
		this->setSprite(this->undelsenSprite);
	}else if(t == PlayerType::Durandana){
		this->setSprite(this->durandanaSprite);
	}*/
}
void GPlayer::damage(float dmg, HPLShootingObject* damageSource){
	HPLError::error("使用不可。");
	HPLError::abort();
}

