#include "Monster.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "MonsterStrategyHelpers.h"

INCLUDE_BULLET_LIST
INCLUDE_game

void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumber){
	m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
	m.attackCooldownTimer=std::max(0.f,m.attackCooldownTimer-fElapsedTime);
	if(m.queueShotTimer>0){
		m.queueShotTimer-=fElapsedTime;
		if(m.queueShotTimer<0){
			m.queueShotTimer=0;
			{
				BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24 * ConfigInt("BulletSpeed")/100.f, 12.f*ConfigInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,false, { uint8_t(ConfigIntArr("BulletColor",0)),uint8_t(ConfigIntArr("BulletColor",1)),uint8_t(ConfigIntArr("BulletColor",2)),uint8_t(ConfigIntArr("BulletColor",3) )},{ConfigInt("BulletSize")/100.f*8,ConfigInt("BulletSize")/100.f*8})));
			}
		}
	}
	geom2d::line line(m.pos,game->GetPlayer()->GetPos());
	if(m.targetAcquireTimer==0&&m.queueShotTimer==0){
		m.targetAcquireTimer=1;
		if(line.length()<24.f*ConfigInt("Range")/100.f){
			m.target=line.upoint(-1.2);
			if(m.canMove){
				m.SetState(State::MOVE_AWAY);
			} else {
				m.SetState(State::NORMAL);
			}
		} else
			if(line.length()>24.f*ConfigInt("CloseInRange")/100.0f){
				m.target=line.upoint(1.2);
				m.SetState(State::MOVE_TOWARDS);
			} else {
				m.SetState(State::NORMAL);
			}
	}
	m.canMove=true;
	geom2d::line moveTowardsLine=geom2d::line(m.pos,m.target);
	bool pathfindingDecision=false;
	switch(m.state){
	case State::MOVE_TOWARDS:{
		if(moveTowardsLine.length()>1){
			vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
			bool movedX=m.SetX(newPos.x);
			bool movedY=m.SetY(newPos.y);
			pathfindingDecision=movedX|movedY;
			m.canMove=movedX&&movedY;
		}
		if(!pathfindingDecision){
			m.StartPathfinding(2.5);
		}else
			if(line.length()<=24.f*ConfigInt("CloseInRange")/100.0f){
				m.SetState(State::NORMAL);
			}
		if(moveTowardsLine.vector().x>0){
			m.facingDirection=RIGHT;
		} else {
			m.facingDirection=LEFT;
		}
		m.PerformJumpAnimation();
	}break;
	case State::MOVE_AWAY:{
		if(moveTowardsLine.length()>1){
			vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
			bool movedX=m.SetX(newPos.x);
			bool movedY=m.SetY(newPos.y);
			pathfindingDecision=movedX|movedY;
			m.canMove=movedX&&movedY;
		}
		if(!pathfindingDecision){
			m.StartPathfinding(2.5);
		}else
			if(line.length()>=24.f*ConfigInt("Range")/100.f){
				m.SetState(State::NORMAL);
			}
		if(moveTowardsLine.vector().x>0){
			m.facingDirection=RIGHT;
		} else {
			m.facingDirection=LEFT;
		}
		m.PerformJumpAnimation();
	}break;
	case State::PATH_AROUND:{
		m.PathAroundBehavior(fElapsedTime);
	}break;
	default:{
		if(m.attackCooldownTimer==0){
			m.attackCooldownTimer=ConfigFloat("ShootingSpeed");
			m.queueShotTimer=std::min(m.attackCooldownTimer-0.001,0.7);
			m.PerformShootAnimation();
		}
	}
	}
}