/////////////////////////////////////////////////
//
//  filename: Coco.cpp
//  author:Chafumi Touji
//  date: 2021/07/04 ver1.00
//
/////////////////////////////////////////////////

#include "Cha3D/defcha3d.h"
#include "ChaSound/ChaSound.h"
#include "Coco.h"
#include "Stick.h"
#include "Piske.h"

CCoco::CCoco() : CCharacterBase() {

	Move = false;
	Attack = false;
	CollisionCheck = true;

	Audio = NULL;
	AudioPlaying = false;
}

CCoco::CCoco(CDispWindow *disp_window) : CCharacterBase( disp_window ){

	Move = false;
	Attack = false;
	CollisionCheck = true;
	DispWindow = disp_window;
}

CCoco::~CCoco() {

}

void CCoco::OnKeyDown(UINT nChar) {

	if (Attack == false) {
		if (nChar == 39 /* 겑 */) {
			RotationZ = 90.0f;

			if (Move == false) {
				SetCurrentAnimation(L"WALK", 5, 3, true, false);
				SetRefrainSec(L"WALK", 20.0f);
			}
			Move = true;
		}
		if (nChar == 40 /* 겒 */) {
			RotationZ = 0.0f;

			if (Move == false) {
				SetCurrentAnimation(L"WALK", 5, 3, true, false);
				SetRefrainSec(L"WALK", 20.0f);
			}
			Move = true;
		}
		if (nChar == 37 /* 겏 */) {
			RotationZ = 270.0f;

			if (Move == false) {
				SetCurrentAnimation(L"WALK", 5, 3, true, false);
				SetRefrainSec(L"WALK", 20.0f);
			}
			Move = true;
		}
		if (nChar == 38 /* 겓 */) {
			RotationZ = 180.0f;

			if (Move == false) {
				SetCurrentAnimation(L"WALK", 5, 3, true, false );
				SetRefrainSec(L"WALK", 20.0f);
			}
			Move = true;
		}
	}
	if (nChar == 32 /* enter */) {
		if (Attack == false) {
			Move = false;
			SetCurrentAnimation(L"ATTACK", 0, 4, false, false);
			SetFrameCount(0);
			SetRefrainSec(L"ATTACK", 0.0f);
			Attack = true;
			SetCollisionCheck(false);
		}
	}
}

void CCoco::PreAction() {

	if (Move == true) {

		XMFLOAT4 rotation = GetRotation();

		float rot_z = RotationZ - rotation.z;
		if (rot_z < -180.0f)
			rot_z += 360.0f;
		else if (rot_z > 180.0f)
			rot_z -= 360.0f;

		if (rot_z < 0.0f) {
			rot_z = max(rot_z, -30.0f);
		}
		else {
			rot_z = min(rot_z, 30.0f);
		}

		AddRotation(XMFLOAT4(0, 0, rot_z, 0));
		rotation = GetRotation();
		if (rotation.z < -180.0f) {
			AddRotation(XMFLOAT4(0, 0, 360.0f, 0));
		}
		if (rotation.z > 180.0f) {
			AddRotation(XMFLOAT4( 0, 0, -360.0f, 0 ));
		}

		AddVelocity( 0.1f );
		if (GetVelocity() >= 0.3f)
			SetVelocity( 0.3f );

		XMVECTOR vec = XMVector3Normalize(XMVectorSet(cos(ToRadian(RotationZ)), sin(ToRadian(RotationZ)), 0.0f, 1.0f));
		SetVector( XMFLOAT4(XMVectorGetX(vec) * GetVelocity(), XMVectorGetY(vec) * GetVelocity(), 0, 0 ));

		XMFLOAT4 vec2 = GetVector();
		AddPosition(XMFLOAT4(-vec2.x, -vec2.y, 0, 0));
	}
}

void CCoco::Action() {

	CStick* stick = (CStick*)DispWindow->ObjectManager->GetCharacterData(L"STICK");
	CPiske* piske = (CPiske*)DispWindow->ObjectManager->GetCharacterData(L"PISKE");

	if (Attack == true) {

		if (AudioPlaying == false) {
			AudioPlaying = true;
			Audio->SetLoop(2, false);
			Audio->Play(2);
		}
		if (IsAnimationFinished(L"ATTACK") == true) {
			Attack = false;
			AudioPlaying = false;
			SetCurrentAnimation(L"STOP", 0, 3, true, false);
			SetRefrainSec(L"STOP", 0.0f);
			SetCollisionCheck(true);
			stick->SetCollisionCheck(false);
		}
		else {
			SetCollisionCheck(false);
			stick->SetCollisionCheck(true);
		}
	}
	else {
		SetCollisionCheck(true);
		stick->SetCollisionCheck(false);
		AudioPlaying = false;
		Audio->Stop(2);
	}

	XMVECTOR vec = XMVector3Normalize(XMVectorSet(cos(ToRadian(RotationZ)), sin(ToRadian(RotationZ)), 0.0f, 1.0f));
	XMVECTOR vec2 = vec;
	static XMFLOAT4 prev_pos = XMFLOAT4(0, 0, 0, 0);
	static float xy_prev_x = 0.0f;
	static float xy_prev_y = 0.0f;

	if (CollisionXY == true && XYCollisionObject->CheckID(L"STICK") == false ) {

		if (XYCollisionObject->CheckID(L"PISKE") == true) {

			XMVECTOR vec = XMVector3Normalize(XMVectorSet(cos(ToRadian(RotationZ)), sin(ToRadian(RotationZ)), 0.0f, 1.0f));
			VecX = XMVectorGetX(vec) * Velocity / 5.0f;
			VecY = XMVectorGetY(vec) * Velocity / 5.0f;

			XMFLOAT4 pos = GetPosition();
			pos.x = prev_pos.x - VecX;
			pos.y = prev_pos.y - VecY;
			SetPosition(pos);

			XMVECTOR vec2 = XMVector3Normalize(XMVectorSet(xy_prev_x - pos.x, xy_prev_y - pos.y, 0, 0 ));
			XMVECTOR vec3 = XMVector3Normalize(XMVectorSet(VecX, VecY, 0, 0));
			float dot = abs( XMVectorGetX(XMVector3Dot(vec2, vec3))) + 1.0f;

			XMFLOAT4 piske_pos = piske->GetPosition();
			XMFLOAT4 piske_prev_pos = piske_pos;
			piske_pos.x = piske_pos.x - XMVectorGetX(vec3 - vec2) * Velocity / dot / 5.0f;
			piske_pos.y = piske_pos.y - XMVectorGetY(vec3 - vec2) * Velocity / dot / 5.0f;
			piske->SetPosition(piske_pos);

			piske->ChaResourceObject->UpdateTransform();
			piske->ChaColliderObject->Transform();

			SetCollisionCheck(false);
			piske->CheckCollision();
			if (piske->CollisionXY == true ) {
				piske->SetPosition(piske_prev_pos);
				SetPosition( prev_pos );
			}
			else {
				prev_pos = GetPosition();
				xy_prev_x = XYCollisionObject->ChaResourceObject->Position.x;
				xy_prev_y = XYCollisionObject->ChaResourceObject->Position.y;
				if ( ZCollisionObject != NULL && ZCollisionObject->CollisionZ == true) {
					XMFLOAT4 z_collision_pos = ZCollisionObject->GetPosition();
					z_collision_pos.z = z_collision_pos.z - ZCollisionObject->DistZ + 0.5f;
					XYCollisionObject->SetPosition(z_collision_pos);
				}
			}
			SetCollisionCheck(true);
		}
		else{
			XMVECTOR n = XMVector3Normalize(XMVectorSet(CollisionNormalXY.x, CollisionNormalXY.y, CollisionNormalXY.z, 0.0f));
			float dot = XMVectorGetX(XMVector3Dot(vec, n));
			if (dot < 0.0f) {
				n = -n;
				vec2 = XMVector3Normalize(-XMVector3Normalize(vec) + XMVector3Normalize(n));
			}
			else {
				vec2 = XMVector3Normalize(-XMVector3Normalize(vec) + XMVector3Normalize(n));
			}

			VecX = XMVectorGetX(vec2) * Velocity;
			VecY = XMVectorGetY(vec2) * Velocity;

			XMFLOAT4 pos = GetPosition();
			pos.x = prev_pos.x + VecX + XMVectorGetX(n) * 0.001f;
			pos.y = prev_pos.y + VecY + XMVectorGetY(n) * 0.001f;
			SetPosition(pos);
			stick->SetPosition(pos);

			ChaResourceObject->UpdateTransform();
			ChaColliderObject->Transform();

			stick->ChaResourceObject->UpdateTransform();
			stick->ChaColliderObject->Transform();

			CheckCollision();
			if (CollisionXY == true) {
				SetPosition(prev_pos);
				stick->SetPosition(prev_pos);
			}
			else {
				prev_pos = GetPosition();
			}
		}
	}
	else
		prev_pos = GetPosition();

	static float gravity = 0.05f;
	if (CollisionZ == true)
		gravity = 0.05f;
	else if( CollisionCheck == true ){
		gravity *= 2.0f;
		AddPosition( XMFLOAT4( 0, 0, -gravity, 0 ));
		CollisionPosZ.z -= gravity;
	}

	if (CollisionZ == true && ZCollisionObject->CheckID(L"PISKE") == false && ZCollisionObject->CheckID(L"STICK") == false) {
		if (ChaResourceObject->Position.z < CollisionPosZ.z + 0.4f) {
			XMFLOAT4 pos = GetPosition();
			pos.z = CollisionPosZ.z + 0.4f;
			SetPosition(pos);
			stick->SetPosition(pos);
		}
	}

	//긇긽깋긜긞긣
	XMFLOAT4 pos = GetPosition();
	DispWindow->Camera->SetCameraAt(pos.x, pos.y, pos.z);
	DispWindow->Camera->SetEyePos(pos.x - 5.0f, pos.y, pos.z + 4.0f);
}

void CCoco::OnKeyUp(UINT nChar) {

	if (Move == true) {
		SetCurrentAnimation(L"STOP", 5, 3, true, false);
		SetRefrainSec(L"STOP", 0.0f);
	}

	Move = false;
	Velocity = 0.0f;
}

void CCoco::OnLButtonDown(UINT nFlag, CPoint point) {
}

void CCoco::OnLButtonUp(UINT nFlag, CPoint point) {
}

void CCoco::OnRButtonDown(UINT nFlag, CPoint point) {
}

void CCoco::OnRButtonUp(UINT nFlag, CPoint point) {
}
