

#include "..\..\00_HeaderFiles\02_DerivedClasses\CProtagonistCharacter.h"
#include "..\..\00_HeaderFiles\00_ManagementClasses\CImageManager.h"
#include "..\..\00_HeaderFiles\03_OtherClasses\CAllKeysState.h"
#include "..\..\00_HeaderFiles\00_ManagementClasses\CMapCellManager.h"

CProtagonistCharacter::CProtagonistCharacter( void )
{
	m_bGenerate = true;

	m_bRequestSituationExistence = false;
	
	// とりあえずなにか入れとく。値に意味は無い。
	m_eRequestSituationType = CConquestScene::ESituationType::BEGIN;
	m_eRequestSwitchType = CMapCellManager::ESwitchType::TOP;
}

CProtagonistCharacter::~CProtagonistCharacter( void )
{

}

const int CProtagonistCharacter::STEPMOVE_QUANTITY[ STEPMOVE_CYCLE_FRAME ] = {
    50, 5, 3, 1, 1, 0,
};

void CProtagonistCharacter::Run( CImageManager*   arg_pinImageManager,
                                 CAllKeysState*   arg_pinAllKeysState,
                                 CMapCellManager* arg_pinMapCellManager )
{
	// 主人公クラスの状態構造体。
	// このクラスでメンバ変数をつかわないようにするために静的ローカル変数を持つ。
	static tag_ProtagonistState st_SprotagonistState = { 0 };
	
	if ( m_bGenerate )
	{
		// 初期化（初回のみ）
		m_bGenerate = false;
	
		StateInitialize( &st_SprotagonistState );
	}

	// キー入力処理
	CheckKeys( &st_SprotagonistState, arg_pinAllKeysState );
	
	// 移動したい先が壁で、移動できなくても、移動のアニメーションするし、
	// 移動のモーションが終わるまでは他の動作はできない。

	// 待機中で、キューにステップ移動が入っていたら
	if ( st_SprotagonistState.bStepMoveIdle &&
	     !st_SprotagonistState.qeCommand.empty() )
	{
		st_SprotagonistState.bStepMoveIdle = false;
		st_SprotagonistState.iCurrentStepFrame = 0;

		// 移動方向を登録
		SetStepMoveDirection( &st_SprotagonistState,
		                      arg_pinMapCellManager );

		st_SprotagonistState.qeCommand.pop();

		// 移動先が何かチェック
		CMapCellManager::EMapObjectType eTempMapObjectType;
		
		eTempMapObjectType = CheckDestination( &st_SprotagonistState,
		                                       arg_pinMapCellManager );

		switch ( eTempMapObjectType )
		{
		case CMapCellManager::EMapObjectType::EMPTY:
			st_SprotagonistState.bEnableStep = true;
			break;

		case CMapCellManager::EMapObjectType::WALL:
			st_SprotagonistState.bEnableStep = false;
			break;

		case CMapCellManager::EMapObjectType::OUTSIDE_TOP:
			m_bRequestSituationExistence = true;
			m_eRequestSituationType =
				CConquestScene::ESituationType::SWITCH_MAPCELL_FADE_OUT;
			break;

		case CMapCellManager::EMapObjectType::OUTSIDE_UNDER:
			m_bRequestSituationExistence = true;
			m_eRequestSituationType =
				CConquestScene::ESituationType::SWITCH_MAPCELL_FADE_OUT;
			break;
		}
	}

	// 座標計算
	Calculate( &st_SprotagonistState, arg_pinMapCellManager );
	
	// 描画
	Draw( arg_pinImageManager, &st_SprotagonistState );
	
	printfDx( "x : %d\n", st_SprotagonistState.iGrid_X );
	printfDx( "y : %d\n", st_SprotagonistState.iGrid_Y );
}

void CProtagonistCharacter::StateInitialize(
                                tag_ProtagonistState* st_SprotagonistState )
{
	st_SprotagonistState->iX =
		INITIAL_POSITION_X * CMapCellManager::MAP_CHIP_LENGTH;
	st_SprotagonistState->iY =
		INITIAL_POSITION_Y * CMapCellManager::MAP_CHIP_LENGTH;
		
	st_SprotagonistState->iGrid_X = INITIAL_POSITION_X;
	st_SprotagonistState->iGrid_Y = INITIAL_POSITION_Y;
		
	// 予約座標
	st_SprotagonistState->iAdvance_X = 0;
	st_SprotagonistState->iAdvance_Y = 0;
		
	// 予約座標（グリッド）
	st_SprotagonistState->iAdvanceGrid_X = 0;
	st_SprotagonistState->iAdvanceGrid_Y = 0;
		
	st_SprotagonistState->iCurrentStepFrame = 0;
		
	st_SprotagonistState->eFacingDirection = EFacingDirection::FORWARD;
	st_SprotagonistState->eStepMoveDirection = EStepDirection::DOWN_STEP;
		
	st_SprotagonistState->bStepMoveIdle = true;
	st_SprotagonistState->bEnableStep = true;
	st_SprotagonistState->bAdvanceInput = false;
}

void CProtagonistCharacter::CheckKeys( tag_ProtagonistState* arg_SprotagonistState,
                                       CAllKeysState*        arg_pinAllKeysState )
{
	if ( arg_SprotagonistState->qeCommand.size() <= 1 )
	{
		if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_UP ) )
		{
			arg_SprotagonistState->qeCommand.push( ECommand::UP_STEP_COMMAND );
		}
		else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_DOWN ) )
		{
			arg_SprotagonistState->qeCommand.push( ECommand::DOWN_STEP_COMMAND );
		}
		else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_LEFT ) )
		{
			arg_SprotagonistState->qeCommand.push( ECommand::LEFT_STEP_COMMAND );
		}
		else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_RIGHT ) )
		{
			arg_SprotagonistState->qeCommand.push( ECommand::RIGHT_STEP_COMMAND );
		}
		
		// キューのサイズが2なら先行入力
		if ( 2 == arg_SprotagonistState->qeCommand.size() )
		{
			arg_SprotagonistState->bAdvanceInput = true;
		}
	}
	
	// wasd
	if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_W ) )
	{
		arg_SprotagonistState->eFacingDirection = EFacingDirection::BACK;
	}
	else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_S ) )
	{
		arg_SprotagonistState->eFacingDirection = EFacingDirection::FORWARD;
	}
	else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_A ) )
	{
		arg_SprotagonistState->eFacingDirection = EFacingDirection::LEFT;
	}
	else if ( arg_pinAllKeysState->IsKeyPushed( KEY_INPUT_D ) )
	{
		arg_SprotagonistState->eFacingDirection = EFacingDirection::RIGHT;
	}
}

void CProtagonistCharacter::SetStepMoveDirection(
                                tag_ProtagonistState* arg_SprotagonistState,
                                CMapCellManager* arg_pinMapCellManager )
{
	switch( arg_SprotagonistState->qeCommand.front() )
	{
	case EStepDirection::UP_STEP:
		arg_SprotagonistState->eStepMoveDirection = EStepDirection::UP_STEP;
		break;
		
	case EStepDirection::DOWN_STEP:
		arg_SprotagonistState->eStepMoveDirection = EStepDirection::DOWN_STEP;
		break;

	case EStepDirection::LEFT_STEP:
		arg_SprotagonistState->eStepMoveDirection = EStepDirection::LEFT_STEP;
		break;

	case EStepDirection::RIGHT_STEP:
		arg_SprotagonistState->eStepMoveDirection = EStepDirection::RIGHT_STEP;
		break;
	}
}


CMapCellManager::EMapObjectType CProtagonistCharacter::CheckDestination(
                                    tag_ProtagonistState* arg_SprotagonistState,
                                    CMapCellManager* arg_pinMapCellManager )
{
	// 進行方向のタイプを調べる
	switch( arg_SprotagonistState->eStepMoveDirection )
	{
	case EStepDirection::UP_STEP:
		return arg_pinMapCellManager->GetMapCellDataByGrid(
			                              arg_SprotagonistState->iGrid_X,
			                              arg_SprotagonistState->iGrid_Y,
			                               0, 1 );
		break;

	case EStepDirection::DOWN_STEP:
		return arg_pinMapCellManager->GetMapCellDataByGrid(
			                              arg_SprotagonistState->iGrid_X,
			                              arg_SprotagonistState->iGrid_Y,
			                               0, -1 );
		break;

	case EStepDirection::LEFT_STEP:
		return arg_pinMapCellManager->GetMapCellDataByGrid(
			                              arg_SprotagonistState->iGrid_X,
			                              arg_SprotagonistState->iGrid_Y,
			                              -1, 0 );
		break;

	case EStepDirection::RIGHT_STEP:
		return arg_pinMapCellManager->GetMapCellDataByGrid(
			                              arg_SprotagonistState->iGrid_X,
			                              arg_SprotagonistState->iGrid_Y,
			                               1, 0 );
		break;
	}
	return CMapCellManager::EMapObjectType::OTHER;
}

void CProtagonistCharacter::Calculate( tag_ProtagonistState* arg_SprotagonistState,
                                       CMapCellManager* arg_pinMapCellManager )
{
	// ステップ移動中であれば
	if ( !arg_SprotagonistState->bStepMoveIdle )
	{
		// ステップ可能フラグ
		if ( arg_SprotagonistState->bEnableStep )
		{
			// 保存されている移動要求に対する処理分け
			switch( arg_SprotagonistState->eStepMoveDirection )
			{
			case EStepDirection::UP_STEP:
				arg_SprotagonistState->iY +=
				    STEPMOVE_QUANTITY[ arg_SprotagonistState->iCurrentStepFrame ];
				break;
				
			case EStepDirection::DOWN_STEP:
				arg_SprotagonistState->iY -=
				    STEPMOVE_QUANTITY[ arg_SprotagonistState->iCurrentStepFrame ];
				break;
				
			case EStepDirection::LEFT_STEP:
				arg_SprotagonistState->iX -=
				    STEPMOVE_QUANTITY[ arg_SprotagonistState->iCurrentStepFrame ];
				break;
				
			case EStepDirection::RIGHT_STEP:
				arg_SprotagonistState->iX +=
				    STEPMOVE_QUANTITY[ arg_SprotagonistState->iCurrentStepFrame ];
				break;
			}
		}
		arg_SprotagonistState->iCurrentStepFrame++;
	}
	
	if ( arg_SprotagonistState->iCurrentStepFrame >= STEPMOVE_CYCLE_FRAME )
	{
		arg_SprotagonistState->iCurrentStepFrame = 0;
		arg_SprotagonistState->bStepMoveIdle = true;
		
		arg_SprotagonistState->iGrid_X =
			arg_SprotagonistState->iX / CMapCellManager::MAP_CHIP_LENGTH ;

		arg_SprotagonistState->iGrid_Y =
			arg_SprotagonistState->iY / CMapCellManager::MAP_CHIP_LENGTH ;

		CMapCellManager::EMapObjectType eTempDestination;
		eTempDestination = arg_pinMapCellManager->GetMapCellDataByGrid(
		                                          arg_SprotagonistState->iGrid_X,
		                                          arg_SprotagonistState->iGrid_Y,
		                                          0, 0 );
		
		// 現在地がマップセルの出入口
		switch( eTempDestination )
		{
		case CMapCellManager::EMapObjectType::OUTSIDE_TOP:
			arg_SprotagonistState->iY = 0 *  CMapCellManager::MAP_CHIP_LENGTH;
			arg_SprotagonistState->iGrid_Y =
				arg_SprotagonistState->iY / CMapCellManager::MAP_CHIP_LENGTH ;
			m_bRequestSituationExistence = true;
			m_eRequestSituationType =
				CConquestScene::ESituationType::SWITCH_MAPCELL_FADE_IN;
			m_eRequestSwitchType = CMapCellManager::ESwitchType::TOP;
			
			break;
		case CMapCellManager::EMapObjectType::OUTSIDE_UNDER:
			arg_SprotagonistState->iY = 8 * CMapCellManager::MAP_CHIP_LENGTH;
			arg_SprotagonistState->iGrid_Y =
				arg_SprotagonistState->iY / CMapCellManager::MAP_CHIP_LENGTH ;
			m_bRequestSituationExistence = true;
			m_eRequestSituationType =
				CConquestScene::ESituationType::SWITCH_MAPCELL_FADE_IN;
			m_eRequestSwitchType = CMapCellManager::ESwitchType::UNDER;

			break;
		}


	}
}

void CProtagonistCharacter::Draw( CImageManager* arg_pinImageManager,
                                  tag_ProtagonistState* arg_SprotagonistState )
{
	switch( arg_SprotagonistState->eFacingDirection )
	{
	case EFacingDirection::BACK:
		DrawBase( arg_pinImageManager,
		          arg_SprotagonistState->iX,
		          arg_SprotagonistState->iY,
		          CImageManager::EImageID::PROTAGONIST_BACK );
		break;
		
	case EFacingDirection::FORWARD:
		DrawBase( arg_pinImageManager,
		          arg_SprotagonistState->iX,
		          arg_SprotagonistState->iY,
		          CImageManager::EImageID::PROTAGONIST_FORWARD );
		break;
		
	case EFacingDirection::LEFT:
		DrawBase( arg_pinImageManager,
		          arg_SprotagonistState->iX,
		          arg_SprotagonistState->iY,
		          CImageManager::EImageID::PROTAGONIST_LEFT );
		break;
		
	case EFacingDirection::RIGHT:
		DrawBase( arg_pinImageManager,
		          arg_SprotagonistState->iX,
		          arg_SprotagonistState->iY,
		          CImageManager::EImageID::PROTAGONIST_RIGHT );
		break;
	}

}

bool CProtagonistCharacter::GetRequestSituationExistence()
{
	// 変更の要求は一度だけ渡すようにする。
	if ( m_bRequestSituationExistence )
	{
		m_bRequestSituationExistence = false;
		return true;
	}
	return false;
}

CConquestScene::ESituationType CProtagonistCharacter::GetRequestSituationType()
{
	return m_eRequestSituationType;
}

CMapCellManager::ESwitchType CProtagonistCharacter::GetRequestSwitchType()
{
	return m_eRequestSwitchType;
}

