/* NPCAction.cpp
Copyright (c) 2023 by Amazinite

Endless Sky is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.

Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "NPCAction.h"

#include "DataNode.h"
#include "DataWriter.h"
#include "PlayerInfo.h"
#include "System.h"
#include "UI.h"

using namespace std;



// Construct and Load() at the same time.
NPCAction::NPCAction(const DataNode &node)
{
	Load(node);
}



void NPCAction::Load(const DataNode &node)
{
	if(node.Size() >= 2)
		trigger = node.Token(1);

	for(const DataNode &child : node)
	{
		const string &key = child.Token(0);

		if(key == "triggered")
			triggered = true;
		else
			action.LoadSingle(child);
	}
}



// Note: the Save() function can assume this is an instantiated action, not
// a template, so it only has to save a subset of the data.
void NPCAction::Save(DataWriter &out) const
{
	out.Write("on", trigger);
	out.BeginChild();
	{
		if(triggered)
			out.Write("triggered");

		action.SaveBody(out);
	}
	out.EndChild();
}



// Check this template or instantiated NPCAction to see if any used content
// is not fully defined (e.g. plugin removal, typos in names, etc.).
string NPCAction::Validate() const
{
	return action.Validate();
}



void NPCAction::Do(PlayerInfo &player, UI *ui, const Mission *caller)
{
	// All actions are currently one-time-use. Actions that are used
	// are marked as triggered, and cannot be used again.
	if(triggered)
		return;
	triggered = true;
	action.Do(player, ui, caller);
}



// Convert this validated template into a populated action.
NPCAction NPCAction::Instantiate(map<string, string> &subs, const System *origin,
	int jumps, int64_t payload) const
{
	NPCAction result;
	result.trigger = trigger;
	result.action = action.Instantiate(subs, origin, jumps, payload);
	return result;
}
