//---------------------------
// Includes
//---------------------------
#include "StdAfx.h"
#include "resource.h"
#include "Hero.h"

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

//---------------------------
// Defines
//---------------------------
//

//---------------------------
// Constructor & Destructor
//---------------------------
Hero::Hero(ResourceLoader* resourceLoaderPtr,const String& imagename,int hitPoints, int rage)
:Character(resourceLoaderPtr,imagename,hitPoints)
,m_Rage(rage)
,m_CurrentRage(0)
,m_JumpPressed(false)
,m_AttackReleased(false)
,m_AttackKeyTimer(0)
,m_NextState(STATE_WAITING)
{
	m_VCollisionMeshPtr->CreateRect((36/2)-2,18,4,53);
	m_HCollisionMeshPtr->CreateRect(1,20,34,52/1.355);

	m_WeaponCollisionMeshPtr = resourceLoaderPtr->GetCollisionMesh();
	m_WeaponCollisionMeshPtr->CreateRect(0,0,0,0);

	m_DamageAmount = -5;
}

Hero::~Hero()
{
	delete m_VCollisionMeshPtr;
	delete m_HCollisionMeshPtr;
	delete m_WeaponCollisionMeshPtr;
	SafeDelete(&m_ImagePtr);
}

void Hero::Paint(Painter *painterPtr, Matrix2D matView)
{
	//Draw the image
	int width = 141;
	int height = 84;
	int space = 10;

	switch(m_CurrentState)
	{
	case STATE_WAITING:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(0,0+space,width,height);
			break;
		case 15:
			m_SpriteBox.Set(width,0+space,width*2,height);
			break;
		}
		break;

	case STATE_WALKING:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*2,0+space,width*3,height);
			break;
		case 7:
			m_SpriteBox.Set(width*3,0+space,width*4,height);
			break;
		}
		break;
	case STATE_JUMPING:
		m_SpriteBox.Set(width*4,0+space,width*5,height);
		break;
	case STATE_FALLING:
		m_SpriteBox.Set(0,height+space,width,height*2);
		break;
	case STATE_LIGHT_ATTACK1:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*2,height*2+space,width*3,height*3);
			break;
		case 4:
			m_SpriteBox.Set(width*3,height*2+space,width*4,height*3);
			break;
		case 7:
			m_SpriteBox.Set(width*4,height*2+space,width*5,height*3);
			break;
		case 10:
			m_SpriteBox.Set(0,height*3+space,width,height*4);
			break;
		}
		break;
	case STATE_LIGHT_ATTACK2:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(0,height*3+space,width,height*4);
			break;
		case 6:
			m_SpriteBox.Set(width,height*3+space,width*2,height*4+3);
			break;
		case 12:
			m_SpriteBox.Set(width*2,height*3+space,width*3,height*4);
			break;
		}
		break;

	case STATE_LIGHT_ATTACK3:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*4,height*3+space,width*5,height*4);
			break;
		case 6:
			m_SpriteBox.Set(0,height*4+space,width,height*5);
			break;
		case 12:
			m_SpriteBox.Set(width,height*4+space,width*2,height*5);
			break;
		}
		break;

	case STATE_HEAVY_ATTACK:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*2,height*4+space,width*3,height*5);
			break;
		case 20:
			m_SpriteBox.Set(width*3,height*4+space,width*4,height*5);
			break;
		case 25:
			m_SpriteBox.Set(width*4,height*4+space,width*5,height*5);
			break;
		}
		break;

	case STATE_WALKING_ATTACK:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(0,height*5+space,width,height*6);
			break;
		case 7:
			m_SpriteBox.Set(width,height*5+space,width*2,height*6);
			break;
		case 14:
			m_SpriteBox.Set(width*2,height*5+space,width*3,height*6);
			break;
		case 20:
			m_SpriteBox.Set(width*3,height*5+space,width*4,height*6);
			break;
		}
		break;

	case STATE_JUMP_ATTACK:
		if(m_CurrentAnimationStep < 6)
		{
			m_SpriteBox.Set(width,height+space,width*2,height*2);
		} else {
			m_SpriteBox.Set(width*2,height+space,width*3,height*2);
		}
		break;
	case STATE_BLOCKING:
		if(m_CurrentAnimationStep < 5)
		{
			m_SpriteBox.Set(width*3,height*7+space,width*4,height*8);
		} else {
			m_SpriteBox.Set(width*4,height*7+space,width*5,height*8);
		}
		break;

	case STATE_HIT:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*4,height*5+space,width*5,height*6);
			break;

		case 4: 
			m_SpriteBox.Set(width*0,height*6+space,width*1,height*7);
			break;

		case 8: 
			m_SpriteBox.Set(width*1,height*6+space,width*2,height*7);
			break;
		}
		break;

	case STATE_DYING:
		switch(m_CurrentAnimationStep)
		{
		case 0:
			m_SpriteBox.Set(width*1,height*12+space,width*2,height*13);
			break;

		case 10: 
			m_SpriteBox.Set(width*2,height*12+space,width*3,height*13);
			break;
		case 20: 
			m_SpriteBox.Set(width*3,height*12+space,width*4,height*13);
			break;

		case 30: 
			m_SpriteBox.Set(width*4,height*12+space,width*5,height*13);
			break;

		case 53: 
			m_SpriteBox.Set(width*0,height*13+space,width*1,height*14);
			break;

		case 76: 
			m_SpriteBox.Set(width*1,height*13+space,width*2,height*14);
			break;

		case 99: 
			m_SpriteBox.Set(width*2,height*13+space,width*3,height*14);
			break;

		case 122: 
			m_SpriteBox.Set(width*3,height*13+space,width*4,height*14);
			break;

		case 145: 
			m_SpriteBox.Set(width*4,height*13+space,width*5,height*14);
			break;

		case 168: 
			m_SpriteBox.Set(width*0,height*14+space,width*1,height*15);
			break;

		case 191: 
			m_SpriteBox.Set(width*1,height*14+space,width*2,height*15);
			break;

		case 214: 
			m_SpriteBox.Set(width*2,height*14+space,width*3,height*15);
			break;
		}
		break;

	case STATE_PICKING_UP:
		m_SpriteBox.Set(width*3,height+space,width*4,height*2);
		break;
	case STATE_HOLDING:
		m_SpriteBox.Set(width*4,height+space,width*5,height*2);
		break;
	case STATE_THROWING:
		if(m_CurrentAnimationStep < 10)
		{
			m_SpriteBox.Set(0,height*2+space,width,height*3);
		} else {
			m_SpriteBox.Set(width,height*2+space,width*2,height*3);
		}
		break;
	}

	painterPtr->SetTransformMatrix(m_MatWorld * matView);
	painterPtr->DrawImage(m_ImagePtr,0,0,m_SpriteBox);

	//Draw the collisionMesh
	/*painterPtr->SetColor(255,0,0,127);
	painterPtr->SetTransformMatrix(matView);
	painterPtr->FillCollisionMesh(GetHCollisionMesh());
	painterPtr->FillCollisionMesh(GetVCollisionMesh());
	painterPtr->SetColor(0,255,0,127);
	painterPtr->FillCollisionMesh(GetWeaponCollisionMesh());*/

}

void Hero::Tick(InputState *inputStatePtr)
{

	if(inputStatePtr->IsKeyDown(VK_SPACE)) ++m_AttackKeyTimer;
	ChangeCurrentRage(-1);

	//When no buttons are pressed, the velocity is 0
	m_Velocity.x = 0;

	//Initialisation of the coordinates of the WeaponCollisionMesh
	double x =0;
	double y = 0;
	double width = 0;
	double height = 0;
	m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);
	//State logic
	switch(m_CurrentState)
	{
	case STATE_WAITING:
		// Animation code
		if(m_CurrentAnimationStep == 30)
		{
			m_CurrentAnimationStep = 0;
		} else {
			++m_CurrentAnimationStep;
		}

		// When m_AttackKeyTimer > 0, it means that an attack command has been given.
		if(m_AttackKeyTimer > 0)
		{
			// If the hero isn't touching an item, the hero is going to attack.
			if(!m_HitItem)
			{
				// When the attack button is released (see keyUp method) and it hasn't been pressed longer than 7 ticks,
				// the hero will do the first light attack
				if(m_AttackReleased)
				{
					if(m_AttackKeyTimer < 7)
					{
						SetCurrentState(STATE_LIGHT_ATTACK1);
					} else 	if(m_AttackKeyTimer == 7){
						// When the attack button is held for more than 7 ticks, the hero will do a heavy attack
						SetCurrentState(STATE_HEAVY_ATTACK);
					}
					m_AttackKeyTimer = 0;
				} else {
					if(m_AttackKeyTimer == 7){
						// When the attack button is held for more than 7 ticks, the hero will do a heavy attack
						SetCurrentState(STATE_HEAVY_ATTACK);
					}
				}
			} else {
				// When the hero is touching an item, he can pick it up
				SetCurrentState(STATE_PICKING_UP);
				m_AttackKeyTimer = 0;
			}
		}

		if(inputStatePtr->IsKeyDown(VK_LEFT))
		{
			if(!m_HitWall) {
				SetCurrentState(STATE_WALKING);
			}
			m_Velocity.x = -m_Speed;
			m_HeadingRight = false;
		}

		if(inputStatePtr->IsKeyDown(VK_RIGHT))
		{
			if(!m_HitWall) {
				SetCurrentState(STATE_WALKING);
			}
			m_Velocity.x = m_Speed;
			m_HeadingRight = true;
		}

		if(!m_HitGround)
		{
			SetCurrentState(STATE_FALLING);
		}

		//If the command to jump is given, the character should jump
		if(m_JumpPressed)
		{
			m_Velocity.y += -52*6;
			if(m_HeadingRight)
			{
				m_Velocity.x = m_Speed/2;
			} else {
				m_Velocity.x = -m_Speed/2;
			}
			SetCurrentState(STATE_JUMPING);
			SetHitGround(false);
			m_JumpPressed = false;
		}

		CheckDead();
		break;
	
	case STATE_WALKING:
		// When the left arrow (VK_LEFT) is pressed, the x component of the velocity is -m_Speed.
		if(inputStatePtr->IsKeyDown(VK_LEFT))
		{
				m_Velocity.x = -m_Speed;
				m_HeadingRight = false;
		}
		// When the right arrow (VK_RIGHT) is pressed, the x component of the velocity is m_Speed.
		if(inputStatePtr->IsKeyDown(VK_RIGHT))
		{
			m_Velocity.x = m_Speed;
			m_HeadingRight = true;
		}

		//If the command to jump is given, the character should jump
		if(m_JumpPressed)
		{
			m_Velocity.y += -52*6;
			if(m_HeadingRight)
			{
				m_Velocity.x = m_Speed/2;
			} else {
				m_Velocity.x = -m_Speed/2;
			}
			SetCurrentState(STATE_JUMPING);
			SetHitGround(false);
			m_JumpPressed = false;
		}
		//if the character is hitting a wall, he shouldn't move
		if(m_HitWall)
		{
			SetCurrentState(STATE_WAITING);
		} else {
			// animation code
			if(m_CurrentAnimationStep == 14)
			{
				m_CurrentAnimationStep = 0;
			} else {
				++m_CurrentAnimationStep;
			}

			//When the character is not hitting the ground, he is falling, which means he cannot jump
			if(m_Velocity.y > 120)
			{
				SetCurrentState(STATE_FALLING);
			} else {
				//When the character is walking on the ground, but there is no user input anymore, he goes into the waiting state
				if(!inputStatePtr->IsKeyDown(VK_LEFT) && !inputStatePtr->IsKeyDown(VK_RIGHT))
				{
					SetCurrentState(STATE_WAITING);
				}
			}
		}


		if(m_AttackKeyTimer > 0)
		{
			// If the hero isn't touching an item, the hero is going to attack.
			if(!m_HitItem)
			{
				if(m_AttackReleased)
				{
					if(m_AttackKeyTimer < 7)
					{
						SetCurrentState(STATE_LIGHT_ATTACK1);
					} else 	if(m_AttackKeyTimer == 7){
						// When the attack button is held for more than 7 ticks, the hero will do a walking attack
						SetCurrentState(STATE_WALKING_ATTACK);
					}
					m_AttackKeyTimer = 0;
					//m_AttackReleased = false;
				} else {
					if(m_AttackKeyTimer == 7){
						// When the attack button is held for more than 7 ticks, the hero will do a walking attack
						SetCurrentState(STATE_WALKING_ATTACK);
					}
				}
			} else {
				// When the hero is touching an item, he can pick it up
				SetCurrentState(STATE_PICKING_UP);
				//m_AttackKeyTimer = 0;
			}
		}

		CheckDead();
		break;

	case STATE_JUMPING:		
		if(m_HeadingRight)
		{
			if(inputStatePtr->IsKeyDown(VK_RIGHT))
			{
				m_Velocity.x = m_Speed;
			} else {
				m_Velocity.x = m_Speed/2;
			}
		} else {
			if(inputStatePtr->IsKeyDown(VK_LEFT))
			{
				m_Velocity.x = -m_Speed;
			} else {
				m_Velocity.x = -m_Speed/2;
			}
		}
		//When the character goes down, the falling state is activated
		if(m_Velocity.y > -100)
		{
			SetCurrentState(STATE_FALLING);
			m_AttackKeyTimer = 0;
		}
		break;
	case STATE_FALLING:
		if(m_AttackKeyTimer > 0)
		{
			if(m_AttackKeyTimer <= 7)
			{
				SetCurrentState(STATE_JUMP_ATTACK);
			}
		}

		if(m_HitGround)
		{
			SetCurrentState(STATE_WAITING);
			CheckDead();
		} else {
			if(m_HeadingRight)
			{
				if(inputStatePtr->IsKeyDown(VK_RIGHT))
				{
					m_Velocity.x = m_Speed;
				} else {
					m_Velocity.x = m_Speed/2;
				}
			} else {
				if(inputStatePtr->IsKeyDown(VK_LEFT))
				{
					m_Velocity.x = -m_Speed;
				} else {
					m_Velocity.x = -m_Speed/2;
				}
			}
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;

	case STATE_LIGHT_ATTACK1:
		//WeaponCollisionMesh coordinaten
		x = m_HCollisionMeshPtr->GetBounds().GetMaxX();
		y = m_HCollisionMeshPtr->GetBounds().GetMinY();
		width = m_HCollisionMeshPtr->GetBounds().GetWidth()/2;
		height = m_HCollisionMeshPtr->GetBounds().GetHeight();
		LightAttack(20, STATE_LIGHT_ATTACK2, x, y, width, height);
		break;

	case STATE_LIGHT_ATTACK2:
		//WeaponCollisionMesh coordinates
		x = m_HCollisionMeshPtr->GetBounds().GetMaxX();
		y = m_HCollisionMeshPtr->GetBounds().GetMinY();
		width = m_HCollisionMeshPtr->GetBounds().GetWidth()/2;
		height = m_HCollisionMeshPtr->GetBounds().GetHeight();
		LightAttack(20, STATE_LIGHT_ATTACK3, x, y, width, height);
		break;

	case STATE_LIGHT_ATTACK3:
		//WeaponCollisionMesh coordinates
		x = m_HCollisionMeshPtr->GetBounds().GetMaxX();
		y = m_HCollisionMeshPtr->GetBounds().GetMinY();
		width = m_HCollisionMeshPtr->GetBounds().GetWidth();
		height = m_HCollisionMeshPtr->GetBounds().GetHeight();
		LightAttack(20, STATE_LIGHT_ATTACK1, x, y, width, height);
		break;

	case STATE_HEAVY_ATTACK:
		m_Velocity.x = 0;
		// The heavy attack animation is finished after 16 ticks
		if(m_CurrentAnimationStep == 30)
		{
			if(m_HeadingRight)
			{
				m_Velocity.x = m_Speed;
			} else {
				m_Velocity.x = -m_Speed;
			}

			SetCurrentState(STATE_WAITING);
			//Sets amount of damage
			m_DamageAmount = -5;
			//WeaponCollisionMesh coordinaten
			x = m_HCollisionMeshPtr->GetBounds().GetMaxX();
			y = m_HCollisionMeshPtr->GetBounds().GetMinY();
			width = m_HCollisionMeshPtr->GetBounds().GetWidth();
			height = m_HCollisionMeshPtr->GetBounds().GetHeight();
			m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);
			
			CheckDead();

		} else {
			++m_CurrentAnimationStep;
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;

	case STATE_WALKING_ATTACK:
		if(m_HeadingRight)
		{
				m_Velocity.x = m_Speed;
		} else {
				m_Velocity.x = -m_Speed;
		}
		if(m_CurrentAnimationStep > 14)
		{
			m_Velocity.x = 0;
		}
		// The walking attack animation is finished after 30 ticks
		if(m_CurrentAnimationStep == 30)
		{
			SetCurrentState(STATE_WAITING);
			//Sets amount of damage
			m_DamageAmount = -5;
			//WeaponCollisionMesh coordinates
			x = m_HCollisionMeshPtr->GetBounds().GetMaxX();
			y = m_HCollisionMeshPtr->GetBounds().GetMinY();
			width = m_HCollisionMeshPtr->GetBounds().GetWidth();
			height = m_HCollisionMeshPtr->GetBounds().GetHeight();
			m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);

			CheckDead();
		} else {
			++m_CurrentAnimationStep;
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;

	case STATE_JUMP_ATTACK:
		
		//Sets amount of damage
		m_DamageAmount = -5;

		if(m_CurrentAnimationStep <= 6)
		{
			++m_CurrentAnimationStep;
		}
		if(m_HitGround)
		{
			SetCurrentState(STATE_WAITING);
			CheckDead();
		} else {
			x = m_HCollisionMeshPtr->GetBounds().GetMinX()+15;
			y = m_HCollisionMeshPtr->GetBounds().GetMaxY()-15;
			width = m_HCollisionMeshPtr->GetBounds().GetWidth()/2+15;
			height = m_HCollisionMeshPtr->GetBounds().GetHeight();
			m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);

			if(m_HeadingRight)
			{
				if(inputStatePtr->IsKeyDown(VK_RIGHT))
				{
					m_Velocity.x = m_Speed;
				} else {
					m_Velocity.x = m_Speed/2;
				}
			} else {
				if(inputStatePtr->IsKeyDown(VK_LEFT))
				{
					m_Velocity.x = -m_Speed;
				} else {
					m_Velocity.x = -m_Speed/2;
				}
			}
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;

	case STATE_BLOCKING:
		if(m_CurrentAnimationStep > 10)
		{
			SetCurrentState(STATE_WAITING);
			CheckDead();
		} else {
			++m_CurrentAnimationStep;
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;
	case STATE_HIT:
		if(m_CurrentAnimationStep > 12)
		{
			SetCurrentState(STATE_WAITING);
			CheckDead();
		} else {
			if(m_HeadingRight)
			{
				m_Velocity.x = -m_Speed;
			} else {
				m_Velocity.x = m_Speed;
			}
			++m_CurrentAnimationStep;
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;
	case STATE_DYING:
		m_Velocity.x = 0;
		if(m_CurrentAnimationStep <= 240)
		{
			++m_CurrentAnimationStep;
		}
		if(m_AttackReleased)m_AttackKeyTimer = 0;
		break;
	case STATE_PICKING_UP:
		if(inputStatePtr->IsKeyDown(VK_RIGHT))
		{
			m_HeadingRight = true;
		}
		if(inputStatePtr->IsKeyDown(VK_LEFT))
		{
			m_HeadingRight = false;
		}
		m_Velocity.x = 0;
		if(m_CurrentAnimationStep == 10)
		{
			SetCurrentState(STATE_HOLDING);
			CheckDead();
		} else {
			++m_CurrentAnimationStep;
		}
		break;
	case STATE_HOLDING:
		if(inputStatePtr->IsKeyDown(VK_RIGHT))
		{
			m_HeadingRight = true;
		}
		if(inputStatePtr->IsKeyDown(VK_LEFT))
		{
			m_HeadingRight = false;
		}
		m_Velocity.x = 0;
		if(inputStatePtr->IsKeyDown(VK_SPACE))
		{
			SetCurrentState(STATE_THROWING);
			CheckDead();
			m_AttackKeyTimer = 0;
		}
		break;
	case STATE_THROWING:
		if(inputStatePtr->IsKeyDown(VK_RIGHT))
		{
			m_HeadingRight = true;
		}
		if(inputStatePtr->IsKeyDown(VK_LEFT))
		{
			m_HeadingRight = false;
		}
		m_Velocity.x = 0;
		if(m_CurrentAnimationStep == 20)
		{
			SetCurrentState(STATE_WAITING);
			m_HitItem = false;
			CheckDead();
			m_AttackKeyTimer = 0;
		} else {
			++m_CurrentAnimationStep;
		}
		break;
	}
	m_AttackReleased = false;

	double dTime = inputStatePtr->GetDeltaTime();
	//Calculates the new position in function of the velocity and gravity.
	SetPosition(m_Position + m_Velocity * dTime + m_Gravity*dTime*dTime/2);

	//Bereken de nieuwe velocity vector die door de versnelling is gewijzigd.
	m_Velocity += m_Gravity*dTime;

	//mirrors the image
	Matrix2D matTransform, matPosition;
	// position -46 om de afbeelding op de juiste plaats te zetten
	matPosition.SetAsTranslate(m_Position.x-46,m_Position.y);
	if(!m_HeadingRight)
	{
		Matrix2D matTranslate, matMirror;
		matMirror.SetAsScale(-1,1);
		Rect2D collisionbounds = m_HCollisionMeshPtr->GetBounds();
		matTranslate.SetAsTranslate(collisionbounds.MaxX - collisionbounds.MinX+46*2,0);
		matTransform = matMirror * matTranslate;

		//flip the weapon collisionmesh
		x = -(m_WeaponCollisionMeshPtr->GetBounds().GetMinX() - m_HCollisionMeshPtr->GetBounds().GetMinX()) + m_HCollisionMeshPtr->GetBounds().GetMaxX();
		y = m_WeaponCollisionMeshPtr->GetBounds().GetMinY();
		width = -m_WeaponCollisionMeshPtr->GetBounds().GetWidth();
		height = m_WeaponCollisionMeshPtr->GetBounds().GetHeight();
		m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);
	}
	m_MatWorld = matTransform * matPosition;
}

void Hero::KeyUp(TCHAR cKey)
{
	//When the up arrow is released and the character is the waiting or walking state, the character jumps up
	if(cKey==VK_UP && (m_CurrentState == STATE_WAITING || m_CurrentState == STATE_WALKING))m_JumpPressed = true;
	if(cKey==VK_SPACE)
	{
		m_AttackReleased = true;
	}
}

void Hero::ChangeCurrentRage(int rage)
{
	rage = getCurrentRage() + rage;
	if(rage > m_Rage)
	{
		m_CurrentRage = m_Rage;
	} else if(rage < 0) {
		m_CurrentRage = 0;
	} else {
		m_CurrentRage = rage;
	}
}

int Hero::getCurrentRage() const
{
	return m_CurrentRage;
}

int Hero::getRage() const
{
	return m_Rage;
}

//Code for the LightAttack States
//maxAnimationSteps are the max amount of animation steps that should be performed during this lightAttack
//nextState is the state that should come next if the attack button was pressed again, otherwise it is just the waiting state
//double x,y,width and height are the coordinates for the weaponcollisionmesh
void Hero::LightAttack(int maxAnimationSteps, int nextState, double x, double y, double width, double height)
{
	m_Velocity.x = 0;
	// The light attack animation is finished after maxAnimationSteps ticks
	if(m_CurrentAnimationStep == maxAnimationSteps)
	{
		if(m_HeadingRight)
		{
			m_Velocity.x = m_Speed;
		} else {
			m_Velocity.x = -m_Speed;
		}
		//if the attack button has been pressed for no longer than  7 ticks 
		// during the light attack, the next light attack joins the combo
		if(m_AttackKeyTimer > 0)
		{
			SetCurrentState(m_NextState);
			m_NextState = STATE_WAITING;
			m_AttackKeyTimer = 0;
		} else {
			SetCurrentState(STATE_WAITING);
		}
		//Sets amount of damage
		m_DamageAmount = -2;

		//WeaponCollisionMesh coordinates
		m_WeaponCollisionMeshPtr->CreateRect(x,y,width,height);

		CheckDead();
	} else {
		if(m_AttackReleased)
		{
			if(m_AttackKeyTimer < 7)
			{
				m_NextState = nextState;
			} else {
				m_NextState = STATE_WAITING;
			}
		}

		++m_CurrentAnimationStep;
	}
}

//Checks if a collisionmesh of a weapon comes into contact with the hero. If it does, the hero might get damage.
void Hero::detectHealthChange(CollisionMesh *collisionMesh, int healthModifier)
{
	if(!m_dead)
	{
		//Determines whether a collisionmesh comes into contact with the hero
		if(m_HCollisionMeshPtr->HitTest(collisionMesh) || m_VCollisionMeshPtr->HitTest(collisionMesh))
		{
			Rect2D weaponBounds = collisionMesh->GetBounds();
			//Rect2D collisionRect = collisionMesh->CollisionTest(m_HCollisionMeshPtr);
			Rect2D hMeshBounds = m_HCollisionMeshPtr->GetBounds();
			bool rightHit = true;

			double difMin= fabs(weaponBounds.MinX - hMeshBounds.MinX);
			double difMax = fabs(weaponBounds.MaxX - hMeshBounds.MaxX);
			//checks whether the weapon is hitting on the left. If not, it is hitting on theright
			if( difMin < difMax)
			{
				rightHit = false;
			}
			//When the direction the hero is facing, is the same as the side on which he is hit, he will block it,
			// unless the attack was too hard.
			if((m_HeadingRight && rightHit)||(!m_HeadingRight && !rightHit))
			{
				if(healthModifier < -1)
				{
					ChangeCurrentHitPoints(healthModifier);
					ChangeCurrentRage(500);
					SetCurrentState(STATE_HIT);
				} else {
					SetCurrentState(STATE_BLOCKING);
				}
			} else {
				//When the hero gets hit in his back, he receives damage
				ChangeCurrentHitPoints(healthModifier);
				ChangeCurrentRage(500);
				SetCurrentState(STATE_HIT);
				m_HeadingRight = !m_HeadingRight;
			}
		}
	}
}