//	ModifierFactory.h - Class which handles which modifiers to apply when a
//						player collects a pickup.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	This program 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.
//
//	This program 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 <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef MODIFIERFACTORY_H_
#define MODIFIERFACTORY_H_

#include "c0xHeaders.h"

#include <vector>
#include <map>

class ModifierCreator;
class GamePlayState;
class Tank;

///	Class which handles which modifiers to apply when a player collects a pickup.
class ModifierFactory
{
  public:
	///	Constructor.
	ModifierFactory();
	///	Destructor.
	~ModifierFactory();

	///	Called when a pickup is collected by a tank.
	/*!
		\return The text to display describing the modifier.

		This will choose a random modifier from the available modifiers, and
		apply it. If it was a single-use modifier, that modifier will be removed
		from the available modifiers. If any modifiers depend on the chosen
		modifier being active, they will now be added to the list of available
		modifiers.
	 */
	const std::wstring pickupCollectedRandom(GamePlayState& state);
	///	Called when the named pickup is collected by a tank.
	/*!
		\return The text to display describing the modifier.
	 */
	const std::wstring pickupCollected(GamePlayState& state,
									   const std::wstring& pickupType);
	///	Returns the name of a random available pickup.
	const std::wstring getRandomAvailablePickup();
	///	Returns the name of a random pickup at (no more than) the passed-in grade.
	const std::wstring getGradedPickup(int grade);
	///	Returns the number of available modifiers remaining.
	int getModifiersRemaining() const {return available.size();};
	///	Returns the number of modifiers at the passed-in grade.
	int getNumGradedModifiers(int val) const {return availableGrades.count(val);};

#ifdef OSX
	///	Registers a ModifierCreator with the factory.
	void registerCreator(shared_ptr<ModifierCreator> creator);
#else
	///	Registers a ModifierCreator with the factory.
	void registerCreator(shared_ptr<ModifierCreator>& creator);
#endif

	///	Resets all creators to their original lists (call at the start of GamePlayState).
	void reset();
  private:
	//--When using random generation--------------------------------------------
	///	The currently-available modifiers.
	std::vector<std::wstring> available;
	///	Any modifiers waiting on other modifiers being activated.
	std::vector<std::wstring> pending;
	///	Any modifiers which have been removed from the available list.
	std::vector<std::wstring> removed;

	//--When using graded generation--------------------------------------------
	///	The available modifiers, sorted by grade.
	std::multimap<int, std::wstring> availableGrades;
	///	Any modifiers which have been removed from the availableGrades list.
	std::multimap<int, std::wstring> removedGrades;

	///	All the available modifiers.
	std::map<std::wstring, shared_ptr<ModifierCreator> > modifiers;
};

#endif
