//	GameCounter.cpp - Singleton used to count all sorts of things.
//	----------------------------------------------------------------------------
//	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/>.
//	----------------------------------------------------------------------------

#include "GameCounter.h"

#include <algorithm>

using namespace std;

//------------------------------------------------------------------------------
GameCounter::GameCounter()
{
	
}

//------------------------------------------------------------------------------
GameCounter::~GameCounter()
{
	
}

//------------------------------------------------------------------------------
void GameCounter::incrementCount(const wstring& counter, int val)
{
	unsigned int i;
	map<wstring, CounterPtr>::iterator it = counters.find(counter);

	if(it == counters.end())
		createCounter(counter);

	counters[counter]->value += val;
	for(i=0;i<counters[counter]->noteCounts.size();++i)
	{
		CounterPtr& c = counters[counter];

		if((c->value % c->noteCounts[i]) == 0)
			c->noteDests[i]->countReached(counter, c->value);
	}
}

//------------------------------------------------------------------------------
int GameCounter::getCount(const wstring& counter) const
{
	int retval = 0;
	map<wstring, CounterPtr>::const_iterator it = counters.find(counter);

	if(it != counters.end())
		retval = it->second->value;

	return retval;
}

//------------------------------------------------------------------------------
int GameCounter::getScore() const
{
	int retval = 0;
	map<wstring, CounterPtr>::const_iterator it;

	for(it=counters.begin();it!=counters.end();++it)
		retval += it->second->value;

	return retval;
}

//------------------------------------------------------------------------------
void GameCounter::reset()
{
	map<wstring, CounterPtr>::const_iterator it;

	for(it=counters.begin();it!=counters.end();++it)
		it->second->value = 0;
}

//------------------------------------------------------------------------------
void GameCounter::registerNotification(const wstring& counter,
									   int value,
									   CounterNotification *notification)
{
	map<wstring, CounterPtr>::iterator it = counters.find(counter);

	if(it == counters.end())
		createCounter(counter);

	counters[counter]->noteCounts.push_back(value);
	counters[counter]->noteDests.push_back(notification);
}

//------------------------------------------------------------------------------
void GameCounter::unregisterNotification(const std::wstring& counter,
										 int value,
										 CounterNotification *notification)
{
	map<wstring, CounterPtr>::iterator it = counters.find(counter);

	if(it != counters.end())
	{
		counters[counter]->noteCounts.erase(find(counters[counter]->noteCounts.begin(),
												 counters[counter]->noteCounts.end(),
												 value));
		counters[counter]->noteDests.erase(find(counters[counter]->noteDests.begin(),
												counters[counter]->noteDests.end(),
												notification));
	}
}

//------------------------------------------------------------------------------
void GameCounter::createCounter(const wstring& name)
{
	counters.insert(make_pair(name, CounterPtr(new Counter)));
}
