#include "stdafx.h"
#include "BarrierPost.h"
#include "Components/Components.h"
#include "CrashBandicoot/Scene/CrashScene.h"
#include "Physx/PhysxManager.h"
#include "Boulder.h"
#include "Materials/Shadow/DiffuseMaterial_Shadow.h"

int BarrierPost::MaterialIdx = -1;

BarrierPost::BarrierPost(const XMFLOAT3& initPos, const XMFLOAT3& initRot)
	:m_InitPos(initPos), m_InitRot(initRot), m_CurrRot(initRot)
{
}

BarrierPost::~BarrierPost()
{
}

void BarrierPost::KnockOver()
{
	if(!m_IsKnocked)
	{
		m_IsKnocked = true;
		m_FinalRot = { m_InitRot.x - 80.0f, m_InitRot.y, m_InitRot.z };
	}
}

void BarrierPost::Initialize(const GameContext & gameContext)
{
	UNREFERENCED_PARAMETER(gameContext);

	if(MaterialIdx == -1)
	{
		auto mat = new DiffuseMaterial_Shadow();
		mat->SetDiffuseTexture(L"./Resources/Textures/CrashBandicoot/BarrierWood.png");
		mat->SetLightDirection(gameContext.pShadowMapper->GetLightDirection());
		MaterialIdx = gameContext.pMaterialManager->AddNextMaterial(mat);
	}
	//Model Component
	auto model = new ModelComponent(L"./Resources/Meshes/CrashBandicoot/BarrierPost.ovm");
	model->SetMaterial(MaterialIdx);
	AddComponent(model);

	auto physX = PhysxManager::GetInstance()->GetPhysics();

	auto nothing = physX->createMaterial(0.0f, 0.0f, 0);

	//Rigid Body used for collsion
	auto collObj = new GameObject();
	collObj->GetTransform()->Translate(m_InitPos);
	collObj->GetTransform()->Rotate(m_InitRot);
	auto rigidColl = new RigidBodyComponent(true);
	rigidColl->SetCollisionGroup(CollisionGroupFlag(CollisionChanel::Character));
	rigidColl->SetCollisionIgnoreGroups(CollisionGroupFlag(CollisionChanel::Boulder));
	collObj->AddComponent(rigidColl);
	
	std::shared_ptr geom = std::make_shared(10.8f, 11.0f, 1.05f);
	auto coll = new ColliderComponent(geom, *nothing, PxTransform(0, 11.0f,0));
	collObj->AddComponent(coll);
	AddChild(collObj);

	//Add child obj for trigger
	auto triggerObj = new GameObject();
	triggerObj->GetTransform()->Translate(m_InitPos);
	triggerObj->GetTransform()->Rotate(m_InitRot);
	auto triggerRigid = new RigidBodyComponent();
	triggerRigid->SetKinematic(true);
	triggerRigid->SetCollisionGroup(CollisionGroupFlag(CollisionChanel::Boulder));
	
	triggerObj->AddComponent(triggerRigid);
	geom = std::make_shared(12.8f, 13.0f, 1.55f);
	auto triggerColl = new ColliderComponent(geom, *nothing, PxTransform(0, 12.0f, 0));
	triggerColl->EnableTrigger(true);
	triggerObj->AddComponent(triggerColl);
	
	triggerObj->SetOnTriggerCallBack(OnBarrierPostTrigger);
	
	AddChild(triggerObj);
}

void BarrierPost::PostInitialize(const GameContext & gameContext)
{
	UNREFERENCED_PARAMETER(gameContext);
	GetTransform()->Translate(m_InitPos);
	GetTransform()->Rotate(m_InitRot);
}

void BarrierPost::Draw(const GameContext & gameContext)
{
	UNREFERENCED_PARAMETER(gameContext);
}

void BarrierPost::Update(const GameContext & gameContext)
{
	if(m_IsKnocked && !m_ReachedRot)
	{
		auto newRot = XMFLOAT3{ m_CurrRot.x - m_RotationSpeed * gameContext.pGameTime->GetElapsed(), m_CurrRot.y, m_CurrRot.z };

		if(newRot.x < m_FinalRot.x)
		{
			newRot.x = m_FinalRot.x;
			m_ReachedRot = true;
		}
		GetTransform()->Rotate(newRot);
		m_CurrRot = newRot;
	}
}

void BarrierPost::OnBarrierPostTrigger(GameObject * triggerObject, GameObject * otherObject, TriggerAction action)
{
	if(action == ENTER)
	{
		auto barrier = static_cast(triggerObject->GetParent());
		auto boulder = dynamic_cast(otherObject);
		if (boulder && barrier)
		{
			barrier->KnockOver();
		}
	}
}