//---------------------------
// Includes
//---------------------------
#include "StdAfx.h"
#include "Barrel.h"

#include "Painter.h"
#include "ResourceLoader.h"
#include "InputState.h"
#include "CollisionMesh.h"
#include "Image.h"
//---------------------------
// Defines
//---------------------------
//

//---------------------------
// Constructor & Destructor
//---------------------------
Barrel::Barrel(ResourceLoader* resourceLoaderPtr, const String& imagename)
:Item(resourceLoaderPtr,imagename)
,m_HitCharacter(false)
,m_Trigger(false)
,m_Mass(10)
{
	m_FireForce = 70000;
	m_CollisionMeshPtr = resourceLoaderPtr->GetCollisionMesh();
	m_CollisionMeshPtr->CreateRect(0, 0, m_ImagePtr->GetWidth()/5-6, m_ImagePtr->GetHeight()/2);
	m_Restitution = 0.5;
	m_Friction = 0.8;
}

Barrel::~Barrel()
{
	SafeDelete(&m_ImagePtr);
	delete m_CollisionMeshPtr;
}

void Barrel::Paint(Painter *painterPtr, Matrix2D matTransform)
{

	int width = m_ImagePtr->GetWidth()/5;
	int height = m_ImagePtr->GetHeight()/2;
	int space = 10;

	switch(m_CurrentState)
	{
	case STATE_STANDING:
		m_SpriteBox.Set(0,0,width,height);
	break;
	case STATE_PICKED_UP:
		m_SpriteBox.Set(width,0,width*2,height);
	break;
	case STATE_ROLLING:
		m_SpriteBox.Set(width,0,width*2,height);
	break;
	}
	painterPtr->SetTransformMatrix(m_MatWorld * matTransform);
	painterPtr->DrawImage(m_ImagePtr,0,0,m_SpriteBox);

	/*painterPtr->SetColor(255,0,0,127);
	painterPtr->SetTransformMatrix(matTransform);
	painterPtr->FillCollisionMesh(m_CollisionMeshPtr);*/
}

void Barrel::Tick(InputState *inputStatePtr)
{
	Vector2D accelerationByFire;
	double dTime = inputStatePtr->GetDeltaTime();

	//niet zeker hiervan
	m_FireDirectionalForce = Vector2D(0,0);
	Vector2D SumOfAccelerations = m_Gravity;

	switch(m_CurrentState)
	{
	case STATE_STANDING:
		if(m_HitCharacter && m_Trigger)
		{
			m_CurrentState = STATE_PICKED_UP;
			SetPosition(m_liftPostion);
			SumOfAccelerations = Vector2D(0,0);
			//put a round collisionmesh on the barrel to do the collision when it hits the level
			m_CollisionMeshPtr->CreateEllipse(m_ImagePtr->GetWidth()/10-2, m_ImagePtr->GetHeight()/4+4,m_ImagePtr->GetWidth()/10-4,m_ImagePtr->GetWidth()/10-4);
			m_UseRayCast = true;
		}
		break;
	case STATE_PICKED_UP:
		if(m_Trigger)
		{
			m_CurrentState = STATE_ROLLING;
						
			Vector2D FireDirection(1,0);
			FireDirection = FireDirection.RotatedBy(-3.14/6); 
			m_FireDirectionalForce = FireDirection * m_FireForce;
			accelerationByFire =  m_FireDirectionalForce/m_Mass;
			SumOfAccelerations += accelerationByFire;
		} else {
			SumOfAccelerations = Vector2D(0,0);
		}
		break;
	case STATE_ROLLING:
		m_AngularSpeed = 10;
		break;
	}
	//resets the trigger
	m_Trigger = false;

	m_Velocity = m_Velocity + SumOfAccelerations * dTime;
	SetPosition(m_Position + m_Velocity * dTime);
	//adjust rotionAngle: pas m_Angle aan zodat het image roteert	
	m_Angle+=m_AngularSpeed*dTime;

	//calculate world matrix
	Matrix2D matCenter, matRotate, matPosition;

	//gebruik matCenter om het image te transleren zodat het midden van het image  op de oorsprong staat
	matCenter.SetAsTranslate(-(m_ImagePtr->GetWidth()/10-2),-(m_ImagePtr->GetHeight()/4+4));

	//Gebruik matRotate om een matrix te maken die een rotatie veroorzaakt met een hoek m_Angle
	matRotate.SetAsRotate(m_Angle);
	//Maak een matTranslate die het image op de positie m_Position zal verplaatsen
	matPosition.SetAsTranslate(m_Position);
	//calculate world matrix: Vermenigvuldig bovenstaande matrices en het resultaat wordt opgeslagen in m_MatWorld
	m_MatWorld = matCenter * matRotate * matPosition;
	//transform the collisionMesh
	m_CollisionMeshPtr->SetTransformMatrix(m_MatWorld);
}

bool Barrel::HitTest(Character *characterPtr)
{
	CollisionMesh *characterVMesh=characterPtr->GetVCollisionMesh();
	CollisionMesh *characterHMesh=characterPtr->GetHCollisionMesh();
	
	m_HitCharacter = false;
	if(characterVMesh->HitTest(m_CollisionMeshPtr) || characterHMesh->HitTest(m_CollisionMeshPtr))
	{
		m_liftPostion = Point2D(characterPtr->GetVCollisionMesh()->GetBounds().GetMinX()-10,characterPtr->GetVCollisionMesh()->GetBounds().GetMinY()-m_ImagePtr->GetHeight()/4+10);
		//m_liftPostion.y -= m_ImagePtr->GetHeight()/2;
		m_HitCharacter = true;
	}
	characterPtr->HitItem(m_HitCharacter);
	return m_HitCharacter;
}

void Barrel::KeyUp(TCHAR cKey)
{
	//When space is released, the character lifts
	if(cKey==VK_SPACE)
	{
		m_Trigger = true;
	}
}

Point2D Barrel::GetPosition() const
{
	//Point2D position;
	//if(m_UseRayCast)
	//{
	//	//Recalculation to get the center of the circle
	//	Rect2D meshbounds = m_CollisionMeshPtr->GetBounds();
	//	double centerX = meshbounds.GetMinX() + meshbounds.GetWidth()/2;
	//	double centerY = meshbounds.GetMinY() + meshbounds.GetHeight()/2;
	//	position = Point2D(m_Position.x + centerX,m_Position.y + centerY);
	//} else {
	//	position = m_Position;
	//}
	//return position;

	return m_Position;
}

void Barrel::SetPosition(Point2D pt)
{
	//if(m_UseRayCast)
	//{
	//	//Recalculation from the center of the circle to upper left corner
	//	Rect2D meshbounds = m_CollisionMeshPtr->GetBounds();
	//	double centerX = pt.x - (meshbounds.GetMinX() + meshbounds.GetWidth()/2);
	//	double centerY = pt.y - (meshbounds.GetMinY() + meshbounds.GetHeight()/2);
	//	m_Position = Point2D(centerX,centerY);
	//} else {
	//	m_Position = pt;
	//}

	m_Position = pt;
}