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

#include "Painter.h"
#include "ResourceLoader.h"
#include "InputState.h"
#include "CollisionMesh.h"
#include "Image.h"

//---------------------------
// Constructor & Destructor
//---------------------------
Arrow::Arrow(ResourceLoader* resourceLoaderPtr, const String& imagename, int healthModifier)
:Item(resourceLoaderPtr,imagename)
,m_ArrowMass(10)
,m_ArrowFireAngle(0)
,m_Visible(false)
,m_Fire(false)
,m_HeadingRight(false)
{
	m_HealthModifier = healthModifier;
	m_FireForce = 10000;
	m_CollisionMeshPtr = resourceLoaderPtr->GetCollisionMesh();
	m_CollisionMeshPtr->CreateRect(0, 0, m_ImagePtr->GetWidth()/2, m_ImagePtr->GetHeight());
	m_CurrentState = STATE_WAITING;
	m_Position = Point2D(500,500);
}

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

void Arrow::Paint(Painter *painterPtr, Matrix2D matTransform)
{
	if(m_Visible)
	{
		double width = m_ImagePtr->GetWidth();
		double height = m_ImagePtr->GetHeight();
		m_SpriteBox.Set(0,0,width/2,height);
		painterPtr->SetTransformMatrix(m_MatWorld * matTransform);
		painterPtr->DrawImage(m_ImagePtr,0,0,m_SpriteBox);
		
		//Draw the collisionMesh
		/*painterPtr->SetColor(0,0,255,127);
		painterPtr->SetTransformMatrix(matTransform);
		painterPtr->FillCollisionMesh(m_CollisionMeshPtr);*/
	}
}
void Arrow::Tick(InputState *inputStatePtr)
{
}
void Arrow::Tick(InputState *inputStatePtr,Hero *hero)
{
	double dTime = inputStatePtr->GetDeltaTime();
	Vector2D accelerationByFire;
	
	// Calculates the acceleration when the arrow has to be fired
	// Depends on the distance from the starting position of the arrow to the target
	if(m_Fire)
	{
		m_CurrentState = STATE_FLYING;
		Vector2D distanceToTarget = hero->GetPosition() - m_Position;
		double InitialVelocityY = -m_FireForce;
		double InitialVelocityX = distanceToTarget.x/dTime;
		m_FireDirectionalForce = Vector2D(InitialVelocityX,InitialVelocityY);
		accelerationByFire =  m_FireDirectionalForce;
		m_Fire = false;
	}

	Vector2D SumOfAccelerations = Vector2D(0,0);
	if(m_CurrentState == STATE_FLYING)
	{
		SumOfAccelerations = m_Gravity + accelerationByFire;
	}
	m_Velocity = m_Velocity + SumOfAccelerations * dTime;
	m_Angle = m_Velocity.Angle();
	SetPosition(m_Position + m_Velocity * dTime);
	
	//mirrors the image
	Matrix2D matTransform, matPosition, matRotate;
	matPosition.SetAsTranslate(m_Position.x,m_Position.y);

	matRotate.SetAsRotate(m_Angle);
	m_MatWorld = matTransform * matRotate * matPosition;
	m_CollisionMeshPtr->SetTransformMatrix(m_MatWorld);
}

void Arrow::SetVisible(bool visible)
{
	m_Visible = visible;
}

bool Arrow::IsVisible() const
{
	return m_Visible;
}

void Arrow::Fire()
{
	m_Fire = true;
}

bool Arrow::ReadyToFire() const
{
	return (m_CurrentState == STATE_WAITING);
}

void Arrow::Reset()
{
	m_CurrentState = STATE_WAITING;
	SetVisible(false);
	m_Velocity = Vector2D(0,0);
}

void Arrow::SetHeadingDirection(bool headingRight)
{
	m_HeadingRight = headingRight;
}