#include "utils/logger.h"
#include "render/modelmanager.h"

#include "game_object.h"

#include <glm/gtx/euler_angles.hpp>

IMPLEMENT_RTTI_ROOT(GameObject);

GameObject::GameObject() : 
	m_position(0.0f), m_rotation(0.0f), m_scale(1.0f),
	m_model(nullptr)
{
	m_boundingBox = g_identityBoundingBox;
}

GameObject::~GameObject()
{
}

bool GameObject::IsKindOf(const RuntimeClass* _typeInfo) const
{
	for (const RuntimeClass* typeInfo = GetRuntimeClass(); typeInfo != nullptr; typeInfo = typeInfo->m_baseRuntimeClass)
		if (typeInfo == _typeInfo)
			return true;

	return false;
}

GameObject* GameObject::_Construct()
{
	return new GameObject();
}

void GameObject::LoadModel(const char* filename)
{
	m_model = g_modelManager->LoadModel(filename);
	if (!m_model)
	{
		Msg("Failed to load %s, no physic or animation", filename);
		return;
	}

	// get model bounds
	m_boundingBox = m_model->GetBoundingBox();
}

glm::mat4 GameObject::GetModelMatrix()
{
	glm::mat4 model = glm::mat4(1.0f);
	model = glm::translate(model, glm::vec3(m_position.x, m_position.y, m_position.z));

	glm::vec3 radiansRot = glm::radians(glm::vec3(m_rotation.x, m_rotation.y, m_rotation.z));

	// rotation
	glm::mat4 rotationMatrix = glm::yawPitchRoll(radiansRot.y, radiansRot.x, radiansRot.z);
	model *= rotationMatrix;

	return model;
}

void GameObject::GetTransformedBBox( BoundingBox* boundinBox )
{
	// local copy of BBox
	BoundingBox transformedBBox = m_boundingBox;

	// rotate
	TransformBoundingBox(transformedBBox, GetModelMatrix());

	assert(boundinBox);
	*boundinBox = transformedBBox;
}
