////////////////////////////////////////////////////////////////////////////////
// VTOLAI.h
// AI for vehicles that have control over their altitude (helicopters, vector-thrust vehicles, submarines)
// Copyright Bjoern Ganster
// Developed since 2021
////////////////////////////////////////////////////////////////////////////////

#ifndef VTOLAI__h
#define VTOLAI__h

#include "VehicleAI.h"

class VTOLAI: public AbstractVehicleAI {
public:
	// Constructor
	VTOLAI(const char* className, Vehicle* vehicle);

	// Destructor
	~VTOLAI() OVERRIDE;

	void setAim(double dx, double dy) OVERRIDE;

	bool weaponActive(int i, bool groupFire) const OVERRIDE;

	// Set vehicle name
	//void setName(const BGCPString& str) OVERRIDE;

	virtual void planMovement(DWORD now);

	// Set range where AI triggers
	void setTriggerRange(double newVal) OVERRIDE;

	// Add single goal to attack (possibly after sleep goal)
	void addAttackGoal(const BGCPString& target) OVERRIDE;

	// Add goals for AI
	void addGoals(const std::vector<AIGoal>& goals, bool clearExisting) OVERRIDE;

	// Notify AI of an event, like a destroyed object
	void updateObjectStatus(const BGCPString& id, SubObjectiveType newStatus) OVERRIDE;

protected:

	// The AI will wait with shooting until the aim is better than aimAccuracy
	double aimAccuracy;

	double mTriggerSpeed, mAimingAccuracy;

	// When an enemy enters this range, this vehicle will attack it
	double mTriggerRange;

	// Find GameObject with given id in scene recursively
	GameObject* findGameObject(RenderableObject* ro, const BGCPString& id);

	// When was the last weapon fired?
	DWORD mLastFired;

	// Goals for the AI
	size_t mCurrentGoal;
	std::vector<AIGoal> mGoals;

	// Collision handlers
	void treatVehicleCollision(Vehicle* collider);
	void treatCollisionWithImmobile(RenderableObject* collider, double moveUp);

	// Choose heading and speed to walk towards a target
	void moveTowards(const Point3D& aimGoal);

	// Aim at target
	void aimAndFire(const Point3D& aimGoal, DWORD now);

	// Fight mTarget
	void fight(DWORD now);

	// Handle goal types
	void checkWakeUp();
	void doAttack();
	void doDefend();
	void doInspect();
	void doVisit();

	// Calculate distance from ground 
	void calcDistFromGround(const Point3D& p, const RenderableObject* obj, double& value);
};

#endif