////////////////////////////////////////////////////////////////////////////////
// MissionGoals.h
// Track mission goals
// Copyright Bjoern Ganster
// Developed since 2020
////////////////////////////////////////////////////////////////////////////////

#ifndef MissionGoals__H
#define MissionGoals__H

#include "BGBase.h"
#include "BGCPString.h"
#include "XMLTree.h"

#include <vector>

class MechShell;

ENUM_CLASS SubObjectiveType {
	sleep,
	attack,
	defend,
	inspect,
	visit,
	//wait, // use "sleep, above
	event,
	joinFormation,
	checkDistance // Event triggers when the player enters an area
};

ENUM_CLASS ObjectiveStatus {
	inProgress,
	failed,
	success
};

struct SubObjective {
	SubObjectiveType type;
	BGCPString objectName;
	int score;
	ObjectiveStatus status;
	//BGCPString trigger;// no, should be part of the parent, Objective
	Point3D checkDistanceP;
	float checkedDistance;
};

struct Objective {
	int currentScore, requiredScore;
	BGCPString type;
	BGCPString text;
	BGCPString trigger;
	int careerScore;
	ObjectiveStatus status;
	BGCPString bettySpeech;
	BGCPString setVarsOnCompletion;
	std::vector<SubObjective> subObjectives;
	bool mTerminateMission, mMaySucceedOnlyAtMissionEnd;

	// Count sub objectives that have been successfully solved
	size_t countSuccessfulSubObjectives() const;
};

class MissionGoals FINAL {
public:
	// Constructor
	MissionGoals();

	// Destructor
	~MissionGoals();

	// Parse data from XML
	void parseFromXml(XMLTreeConstIterator& iter, MechShell* mechShell);

	// Notify class of a destroyed object (Vehicle or GameObject)
	void updateObjectStatus(const BGCPString& id, SubObjectiveType newStatus, bool missionEnd);

	// Build a string about the mission goals, returns current score
	int showMissionGoals(BGCPString& str, bool showScore, const BGCPString& scoreUnit, bool missionEnd) const;

	// Set star weight for calculating the underweight bonus
	void setTonnage(int newVal);

	// Check if the player's position triggers distance-based sub objectives (gra3, mcc1, cyan)
	void checkDistanceSubObjectives(const Point3D& playerPos);

private:
	std::vector<Objective> mObjectives;
	int mTonnageSum, mUnderweightBonusFactor, mWeightLimit;
	bool mAnnouncedMissionOutcome;
	size_t mPrimaryGoalsRequired;

	// Parse XML for sub objective
	void addSubObjective(Objective& objective, SubObjectiveType type, XMLTreeConstIterator& iter);

	// Parse XML for objective
	void addObjective(MechShell* mechShell, XMLTreeConstIterator& iter);
};

#endif
