/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser 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 LICENSE and COPYING files for more details.
*/

#include "RockHeaps.h"

namespace clustering
{
	namespace ROCK
	{

		void GoodnessHeap::AddOrUpdateElement(ClusteringBase::ClusterPtr cluster, 
			double goodness)
		{
			// usuwa rowniez z indeksu m_HeapData
			RemoveElement(cluster);
			m_HeapData.insert(std::pair<double,ClusteringBase::ClusterPtr>(goodness,cluster));
			m_GoodnessIndex[cluster->GetID()] = goodness;
			m_AllClusters.insert(cluster->GetID());
		}

		void GoodnessHeap::RemoveElement(ClusteringBase::ClusterPtr cluster)
		{
			size_t id = cluster->GetID();
			std::map<size_t, double>::iterator find = m_GoodnessIndex.find(id);
			if(find == m_GoodnessIndex.end())
				return;

			double goodness = find->second;

			m_GoodnessIndex.erase(find);
			m_AllClusters.erase(id);

			

			GoodnessMap::iterator iter = m_HeapData.find(goodness);

			for(; iter != m_HeapData.end() && iter->first == goodness; iter++)
			{
				if (iter->second->GetID() == id)
				{
					m_HeapData.erase(iter);
					return;
				}
			}
		}

		ClusterWithGoodness GoodnessHeap::GetMaxElement()
		{
			GoodnessMap::iterator first = m_HeapData.begin();
			if(first == m_HeapData.end())
				return ClusterWithGoodness();

			return ClusterWithGoodness(first->second, first->first);
		}
		ClusterWithGoodness GoodnessHeap::PopMaxElement()
		{
			ClusterWithGoodness get = GetMaxElement();
			RemoveElement(get.pCluster);
			return get;
		}

		std::set<size_t>& GoodnessHeap::GetAllClusterIndices()
		{
			return m_AllClusters;
		}

		size_t GoodnessHeap::Size()
		{
			return m_AllClusters.size();
		}
	}// namespace ROCK
}// namespace Clustering
