#include "MW4Headers.hpp"
#include "hudcomp.hpp"
#include "HUDscore.hpp"
#include "hudcomm.hpp"
#include "bucket.hpp"
#include "mwguimanager.hpp"
#include "mwmission.hpp"
#include "mwapplication.hpp"
#include "..\missionlang\resource.h"

using namespace MechWarrior4;

int __cdecl CHudScoreInfo_qsort(const void *elem1, const void *elem2)
{
    return ((const CHudScoreInfo*)elem1)->Compare(*(CHudScoreInfo*)elem2);
}

CHudScoreInfo::CHudScoreInfo()
{
    m_pREP = NULL;
    m_bBOT = FALSE;
    m_nScore = m_nKills = m_nDeaths = 0;
}

int CHudScoreInfo::Compare(const CHudScoreInfo& that) const
{
    if (m_bBOT == that.m_bBOT) {
        int nRet;

        nRet = m_nScore - that.m_nScore;
        if (nRet == 0) {
            nRet = m_nKills - that.m_nKills;
            if (nRet == 0) {
                nRet = m_nDeaths - that.m_nDeaths;
                if (nRet == 0) {
                    nRet = (int)(unsigned)connectionID - (int)(unsigned)that.connectionID;
                    if (nRet == 0) {
                        nRet = (int)(unsigned)localID - (int)(unsigned)that.localID;
                    }
                }
            }
        }

        return -nRet;
    } else {
        if (!m_bBOT)
            return -1;
        return +1;
    }
}

int GetScore4Player(int& nKills, int& nDeaths)
{
    VehicleInterface* pvi = VehicleInterface::GetInstance();
    if (pvi) {
        Vehicle* pv = pvi->vehicle;
        if (pv) {
            ReplicatorID id;

            if (pv->IsDerivedFrom(Mech::DefaultData)) {
                id = pv->GetReplicatorID();
get_score:
	            MWGUIManager *manager = MWGUIManager::GetInstance ();
	        if (manager)
	        {
		        if (manager->Component(MWGUIManager::HUD_SCORE))
		        {
			        HUDScore *hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
                    return hud->GetScore4Player(id, nKills, nDeaths);
                    }
                }
            } else {
                Entity* pFollow = pvi->observingEntity.GetCurrent();
		        if (pFollow)
		        {
                    if (pFollow->IsDerivedFrom (Mech::DefaultData)) {
			            id = pFollow->GetReplicatorID();
                        goto get_score;
                    }
                }
            }
        }
    }
    nKills = 0;
    nDeaths = 0;

    return 0;
}

HUDScore::HUDScore()
{
	m_AnimTime = 0;
	//sanghoon
	Location (Point3D (0,0,0.9f));
//	Location (Point3D (200,100,0.9f));
	Size (Point3D (310,300,0.9f));
	Color (0,150,0,255);
	MWApplication *app;
	app = MWApplication::GetInstance ();

	m_PlayerTitle = new HUDText ();
	m_PlayerTitle->SetAsAlt();

	m_PlayerTitle->Justification (HUDText::LEFT_ALIGN);
	m_PlayerTitle->UpdateText (app->GetLocString (IDS_PLAYERHUD));
//	m_PlayerTitle->UpdateText ("Player------------");
	m_PlayerTitle->Color (MakeColor (255,255,255,255));
	m_PlayerTitle->SetSize (HUDText::LARGE_SIZE);
	m_ScoreTitle = new HUDText ();
	m_ScoreTitle ->SetAsAlt();
	m_ScoreTitle->Justification (HUDText::LEFT_ALIGN);
	m_ScoreTitle->UpdateText (app->GetLocString (IDS_SCOREHUD));
	m_ScoreTitle->Color (MakeColor (255,255,255,255));
	m_ScoreTitle->SetSize (HUDText::LARGE_SIZE);
	
	m_KillHeader = new HUDText ();
	m_KillHeader ->SetAsAlt();
	m_KillHeader->Justification (HUDText::LEFT_ALIGN);
	m_KillHeader->UpdateText (app->GetLocString (IDS_KILLHEADER));
	m_KillHeader->Color (MakeColor (255,255,255,255));
	m_KillHeader->SetSize (HUDText::LARGE_SIZE);
	m_DeathHeader = new HUDText ();
	m_DeathHeader ->SetAsAlt();
	m_DeathHeader->Justification (HUDText::LEFT_ALIGN);
	m_DeathHeader->UpdateText (app->GetLocString (IDS_DEATHHEADER));
	m_DeathHeader->Color (MakeColor (255,255,255,255));
	m_DeathHeader->SetSize (HUDText::LARGE_SIZE);
	
	m_PingHeader = new HUDText ();
	m_PingHeader ->SetAsAlt();
	//sanghoon
	/*
	m_PingHeader->Justification (HUDText::LEFT_ALIGN);
	m_PingHeader->UpdateText (app->GetLocString (IDS_PINGHEADER));
	m_PingHeader->Color (MakeColor (255,255,255,255));
	m_PingHeader->SetSize (HUDText::LARGE_SIZE);
	*/
	
	m_GameType = new HUDText ();
	m_GameType ->SetAsAlt();
	m_GameType->Justification (HUDText::LEFT_ALIGN);
	m_GameType->Color (MakeColor (255,255,255,255));
	m_GameType->SetSize (HUDText::LARGE_SIZE);
	m_TimeLeftText = new HUDText ();
	m_TimeLeftText ->SetAsAlt();
	m_TimeLeftText->Justification (HUDText::LEFT_ALIGN);
	m_TimeLeftText->Color (MakeColor (255,255,255,255));
	m_TimeLeftText->SetSize (HUDText::LARGE_SIZE);
	m_TimeLeft = -1;

	m_GameType->TopLeft (0,0);
	m_GameType->BottomRight (800,600);
	m_TimeLeftText->TopLeft (0,0);
	m_TimeLeftText->BottomRight (800,600);
	m_ScoreTitle->TopLeft (0,0);
	m_ScoreTitle->BottomRight (800,600);
	m_PlayerTitle->TopLeft (0,0);
	m_PlayerTitle->BottomRight (800,600);
	
/*
	m_KillText = new HUDText ();
	m_KillText->TopLeft (0,0);
	m_KillText->BottomRight (800,600);
	m_KillText->Justification (HUDText::LEFT_ALIGN);
	m_KillText->UpdateText ("");
	m_KillText->Color (MakeColor (255,255,255,255));
	m_KillText->SetSize (HUDText::LARGE_SIZE);

	m_DeathText = new HUDText ();
	m_DeathText->TopLeft (0,0);
	m_DeathText->BottomRight (800,600);
	m_DeathText->Justification (HUDText::LEFT_ALIGN);
	m_DeathText->UpdateText ("");
	m_DeathText->Color (MakeColor (255,255,255,255));
	m_DeathText->SetSize (HUDText::LARGE_SIZE);
	
	m_PingText = new HUDText ();
	m_PingText->TopLeft (0,0);
	m_PingText->BottomRight (800,600);
	m_PingText->Justification (HUDText::LEFT_ALIGN);
	m_PingText->UpdateText ("");
	m_PingText->Color (MakeColor (255,255,255,255));
	m_PingText->SetSize (HUDText::LARGE_SIZE);
*/
}

HUDScore::~HUDScore()
{
//	delete m_DeathText;
	//delete m_KillText;
	delete m_KillHeader;
	delete m_DeathHeader;
	delete m_PlayerTitle;
	delete m_ScoreTitle;
	delete m_GameType;
	delete m_TimeLeftText;
	delete m_PingHeader;
//	delete m_PingText;
	KillData ();
}

void HUDScore::KillData (void)
{
	stlport::vector<BucketData>::iterator iter;
	
	for (iter = m_Buckets.begin ();iter != m_Buckets.end ();iter++)
	{
		delete iter->text;
		delete iter->score;
		delete iter->kill;
		delete iter->death;
		delete iter->ping;
	}

	m_Buckets.clear ();
}

void HUDScore::Reset (void)
{
	KillData ();
//	comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
	MWMission *mission = Cast_Object (MWMission *,MWMission::GetInstance ());
	mission->m_BucketManager->RescanBucketsForHUD ();
	m_TimeLeftText->UpdateText ("");
	m_GameType->UpdateText ("");
}

void HUDScore::AddBucket (CBucket *bucket)
{
	HUDText *text;
	HUDNumberText *score,*kill,*death,*ping;
	stlport::vector<BucketData>::iterator iter;
	
	for (iter = m_Buckets.begin ();iter != m_Buckets.end ();iter++)
	{
		if (iter->bucket == bucket)
			return;
	}

	text = new HUDText ();
	text->SetAsAlt();
	text->Color (255,255,255,255);
	text->Justification (HUDText::LEFT_ALIGN);
	text->SetSize (HUDText::LARGE_SIZE);
	score = new HUDNumberText ();
	score->SetAsAlt();
	score->Color (255,255,255,255);
	score->Justification (HUDText::LEFT_ALIGN);
	score->SetSize (HUDText::LARGE_SIZE);

	kill = new HUDNumberText ();
	kill->SetAsAlt();
	kill->TopLeft (0,0);
	kill->BottomRight (800,600);
	kill->Justification (HUDText::LEFT_ALIGN);
	kill->UpdateText ("");
	kill->Color (MakeColor (255,255,255,255));
	kill->SetSize (HUDText::LARGE_SIZE);

	death = new HUDNumberText ();
	death->SetAsAlt();
	death->TopLeft (0,0);
	death->BottomRight (800,600);
	death->Justification (HUDText::LEFT_ALIGN);
	death->UpdateText ("");
	death->Color (MakeColor (255,255,255,255));
	death->SetSize (HUDText::LARGE_SIZE);
	
	ping = new HUDNumberText ();
	ping->SetAsAlt();
	ping->TopLeft (0,0);
	ping->BottomRight (800,600);
	ping->Justification (HUDText::LEFT_ALIGN);
	ping->UpdateText ("");
	ping->Color (MakeColor (255,255,255,255));
	ping->SetSize (HUDText::LARGE_SIZE);
	
	m_Buckets.push_back (BucketData (bucket,text,score,kill,death,ping));
}

void HUDScore::KillBucket (CBucket *bucket)
{
	stlport::vector<BucketData>::iterator iter;
	
	for (iter = m_Buckets.begin ();iter != m_Buckets.end ();iter++)
	{
		if (iter->bucket == bucket)
		{
			delete iter->text;
			delete iter->score;
			m_Buckets.erase (iter);
			return;
		}
	}
}

void HUDScore::Update (Stuff::Time till)
{
	if (m_AnimTime == 0)
		m_AnimTime = till;

	while (m_AnimTime <= till)
	{
		m_AnimTime += 1.0/26.0;
	}

	inherited::Update (till);
}

int HUDScore::Kills (const Adept::ReplicatorID& me, const Adept::ReplicatorID& whom)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::KILLS)
			continue;
        CBucket * ppp = m_Buckets[i].bucket;
		if (ppp->RepID() == me)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

int HUDScore::Deaths (const Adept::ReplicatorID& me, const Adept::ReplicatorID& whom)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::DEATHS)
			continue;
        CBucket * ppp = m_Buckets[i].bucket;
		if (ppp->RepID() == me)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

int HUDScore::Kills (const Adept::ReplicatorID& who)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::KILLS)
			continue;
		if (m_Buckets[i].bucket->RepID() == who)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

int HUDScore::Deaths (const Adept::ReplicatorID& who)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::DEATHS)
			continue;
		if (m_Buckets[i].bucket->RepID() == who)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

int HUDScore::Kills (int teamid)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::KILLS)
			continue;
		if (m_Buckets[i].bucket->Affects() == teamid)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

int HUDScore::Deaths (int teamid)
{
	int i,toret;

	toret = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		if (m_Buckets[i].bucket->Type () != CBucketManager::DEATHS)
			continue;
		if (m_Buckets[i].bucket->Affects() == teamid)
			toret += m_Buckets[i].bucket->Value ();
	}
	return toret;
}

void HUDScore::DrawImplementation(void)
{
	int count,i;
	Point3D loc,size;
	Scalar yvalue;
	int curteam;
	const int LINE_HEIGHT = 26;
//	int team_score[8];
	int kills,deaths;
	float killx,deathx,scorex,pingx;
	DWORD killwidth,deathwidth,scorewidth;
    //DWORD pingwidth;

	count = 0;
	for (i=0;i<m_Buckets.size();i++)
	{
		switch (m_Buckets[i].bucket->Type ())
		{
		case CBucketManager::KILLS:
		case CBucketManager::DEATHS:
			break;
		default:
			count++;
		break;
		}
	}
	if (count == 0)
		return;
	
	Scalar oldheatlevel;
	oldheatlevel = g_HUDHeatLevel;
	g_HUDHeatLevel = 0;

	if (m_TimeLeft != -1)
	{
		char text[256];
		int time;
		time = (int) m_TimeLeft;
		WORD min,sec;
		sec = (WORD) (time % 60);
		min = (WORD) (time / 60);
		sprintf (text,"%d:%02d",min,sec);
		m_TimeLeftText->UpdateText (text);
	}

	//sanghoon
	count+=1;
	loc = Location ();
	loc.y=600-count*LINE_HEIGHT;

	size = Size ();
	Size (Point3D (size.x,(Scalar) (count*LINE_HEIGHT),0.9f));
	size = Size ();

	DWORD bcolor = BrighterColor (Color ());

	//sanghoon
	{
		Stuff::Point3D loc2(800-size.x,600-LINE_HEIGHT-1,0.9f);
		LDrawRect (loc2,0,0,size.x,LINE_HEIGHT,MakeColor (0,150,0,128));
		//LDrawRect (loc2,0,LINE_HEIGHT,250,LINE_HEIGHT*2,MakeColor (50,50,150,255));
		LDrawFrame (loc2,0,0,size.x,LINE_HEIGHT+1,bcolor);
		m_GameType->Draw (Point3D (loc2.x+10,loc2.y,0.9f));
		DWORD textw,texth;
		m_TimeLeftText->DrawSize (textw,texth);
		m_TimeLeftText->Draw (Point3D (loc2.x + size.x - textw - 10,loc2.y,0.9f));
	}

	LDrawRect (loc,0,0,(int) size.x,LINE_HEIGHT+1,MakeColor (0,150,0,255));
//	LDrawRect (loc,0,LINE_HEIGHT,(int) size.x,(LINE_HEIGHT*2)+1,MakeColor (0,150,0,255));
//	DrawRect (loc,size,MakeColor (5,15,5,200));
	LDrawFrame (loc,0,0,(int) size.x,(int)size.y+1,bcolor);
//	m_GameType->Draw (Point3D (loc.x+10,loc.y,0.9f));
	DWORD textw,texth;
	m_TimeLeftText->DrawSize (textw,texth);
	//m_TimeLeftText->Draw (Point3D (loc.x + size.x - textw - 10,loc.y,0.9f));
	
//	DrawRect (loc,size,MakeColor (5,15,5,200));
	yvalue = loc.y;
	m_PlayerTitle->Draw (Point3D (loc.x+10,yvalue,0.9f));

	DWORD h;
	//sanghoon
	//m_PingHeader->DrawSize (pingwidth,h);
	//pingx = loc.x + size.x - pingwidth - 10;
	pingx = loc.x + size.x ;
	m_DeathHeader->DrawSize (deathwidth,h);
	deathx = pingx - deathwidth - 5;
	m_KillHeader->DrawSize (killwidth,h);
	killx = deathx - killwidth - 10;

	//m_PingHeader->Draw (Point3D (pingx,yvalue,0.9f));
	m_DeathHeader->Draw (Point3D (deathx,yvalue,0.9f));
	m_KillHeader->Draw (Point3D (killx,yvalue,0.9f));

	m_ScoreTitle->DrawSize (scorewidth,texth);
	scorex = killx - scorewidth - 15;
	m_ScoreTitle->Draw (Point3D (scorex,yvalue,0.9f));
	scorewidth >>= 1;

	deathwidth >>=1;
	killwidth >>= 1;
	//pingwidth >>= 1;


	curteam = -1;

	loc.y += 2;
	loc.x += 2;
	yvalue = loc.y + LINE_HEIGHT;
	size.x -= 4;
	Point3D r,s;
	r.z = 0.0f;
	DWORD curcolor,curbcolor;
	curcolor = MakeColor (50,50,150,255);
	curbcolor = MakeColor (50,50,150,150);
	for (i=0;i<m_Buckets.size();i++)
	{
		char buf[25];
		r.x = loc.x;
		r.y = yvalue;
		s.x = size.x;
		s.y = 11;

		if (m_Buckets[i].bucket->Affects () < 0)
		{
			switch (m_Buckets[i].bucket->Affects ())
			{
			case -1:
				curcolor = MakeColor (50,50,150,255);
				curbcolor = MakeColor (50,50,150,150);
				break;
			case -2:
				curcolor = MakeColor (100,50,50,255);
				curbcolor = MakeColor (100,50,50,150);
				break;
			case -3:
				curcolor = MakeColor (200,200,50,255);
				curbcolor = MakeColor (200,200,50,150);
				break;
			case -4:
				curcolor = MakeColor (50,150,50,255);
				curbcolor = MakeColor (50,150,50,150);
				break;
			case -5:
				curcolor = MakeColor (150,50,150,255);
				curbcolor = MakeColor (150,50,150,150);
				break;
			case -6:
				curcolor = MakeColor (50,100,150,255);
				curbcolor = MakeColor (50,100,150,150);
				break;
			case -7:
				curcolor = MakeColor (100,50,100,255);
				curbcolor = MakeColor (100,50,100,150);
				break;
			case -8:
				curcolor = MakeColor (0,200,100,255);
				curbcolor = MakeColor (0,200,100,150);
				break;
			default:
				STOP (("more than 8 team scores"));
				break;
			}
			switch (m_Buckets[i].bucket->Type ())
			{
			case CBucketManager::KILLS:
			case CBucketManager::DEATHS:
				break;
			default:
				kills = Kills (m_Buckets[i].bucket->Affects ());
				deaths = Deaths (m_Buckets[i].bucket->Affects ());
				itoa (kills,buf,10);
				m_Buckets[i].kill->UpdateText (buf);
				itoa (deaths,buf,10);
				m_Buckets[i].death->UpdateText (buf);

				my_DrawRect ((int) (r.x),(int) (r.y),(int) (r.x+size.x+2),(int) (r.y+LINE_HEIGHT-1),curcolor);
				m_Buckets[i].text->UpdateText (m_Buckets[i].bucket->Text());
				m_Buckets[i].text->TopLeft (loc.x,loc.y);
				m_Buckets[i].text->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].text->Draw (r);
				
				itoa (m_Buckets[i].bucket->Value (),buf,10);
				m_Buckets[i].score->UpdateText (buf);
				m_Buckets[i].score->TopLeft (loc.x,loc.y);
				m_Buckets[i].score->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].score->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].score->Draw (Point3D (scorex + scorewidth - textw -10,r.y,0.9f));
				
				m_Buckets[i].kill->TopLeft (loc.x,loc.y);
				m_Buckets[i].kill->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].kill->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].kill->Draw (Point3D (killx + killwidth - textw,r.y,0.9f));
				
				m_Buckets[i].death->TopLeft (loc.x,loc.y);
				m_Buckets[i].death->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].death->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].death->Draw (Point3D (deathx + deathwidth - textw,r.y,0.9f));
				yvalue += LINE_HEIGHT;
			}
		}
		else
		{
			switch (m_Buckets[i].bucket->Type ())
			{
			case CBucketManager::KILLS:
			case CBucketManager::DEATHS:
				break;
			default:
				kills = Kills (m_Buckets[i].bucket->RepID ());
				deaths = Deaths (m_Buckets[i].bucket->RepID ());
				itoa (kills,buf,10);

				m_Buckets[i].kill->UpdateText (buf);
				itoa (deaths,buf,10);
				m_Buckets[i].death->UpdateText (buf);
				
				Vehicle *obj = 0;
				Connection	*connection = Network::GetInstance()->GetConnection(m_Buckets[i].bucket->RepID ().connectionID);
				if (connection != NULL)
				{
					Check_Object(connection);

					Replicator* rep = connection->FindReplicator(m_Buckets[i].bucket->RepID ());
					if (rep != NULL)
					{
						Entity *ent = Cast_Object(Entity *, rep);
						if (ent->IsDerivedFrom (Vehicle::DefaultData))
						{
							obj = Cast_Object (Vehicle *,ent);
						}
					}
				}
				if ((obj) && (obj->isPlayerVehicle))
				{
					int value = (int) MWApplication::GetInstance()->servedConnectionData[ connection->GetID() ].effectivePing;
					Clamp (value,0,10000);
					sprintf (buf,"%d",value);
					m_Buckets[i].ping->UpdateText (buf);
				}
				else
					m_Buckets[i].ping->UpdateText ("-");
			

				my_DrawRect ((int) (r.x),(int) (r.y),(int) (r.x+size.x+2),(int) (r.y+LINE_HEIGHT-1),curbcolor);
				m_Buckets[i].text->UpdateText (m_Buckets[i].bucket->Text());
				m_Buckets[i].text->TopLeft (loc.x,loc.y);
				m_Buckets[i].text->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].text->Draw (Point3D (r.x+10,r.y,0.9f));

				itoa (m_Buckets[i].bucket->Value (),buf,10);
				m_Buckets[i].score->UpdateText (buf);
				m_Buckets[i].score->TopLeft (loc.x,loc.y);
				m_Buckets[i].score->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].score->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].score->Draw (Point3D (scorex + scorewidth - textw,r.y,0.9f));
				
				/*
				m_Buckets[i].ping->TopLeft (loc.x,loc.y);
				m_Buckets[i].ping->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].ping->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].ping->Draw (Point3D (pingx + pingwidth - textw,r.y,0.9f));
				*/

				m_Buckets[i].kill->TopLeft (loc.x,loc.y);
				m_Buckets[i].kill->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].kill->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].kill->Draw (Point3D (killx + killwidth - textw,r.y,0.9f));
				
				m_Buckets[i].death->TopLeft (loc.x,loc.y);
				m_Buckets[i].death->BottomRight (r.x+size.x,r.y+size.y);
				m_Buckets[i].death->DrawSize (textw,texth);
				textw>>=1;
				m_Buckets[i].death->Draw (Point3D (deathx + deathwidth - textw,r.y,0.9f));
				yvalue += LINE_HEIGHT;
				break;
			}
		}
	}
	g_HUDHeatLevel = oldheatlevel;
}

bool HUDScore::BucketData::operator<(const BucketData& p) const
{
	if ((bucket != 0) &&
		(p.bucket != 0))
	{
        int v1;
        int v2;
        v1 = bucket->Value();
        v2 = p.bucket->Value();
        if (v1 != v2)
		    return (v1 > v2);
        const Adept::ReplicatorID& id1 = bucket->RepID();
        const Adept::ReplicatorID& id2 = p.bucket->RepID();
        v1 = id1.connectionID;
        v2 = id2.connectionID;
        if (v1 != v2)
		    return (v1 > v2);
        v1 = id1.localID;
        v2 = id2.localID;
        if (v1 != v2)
		    return (v1 > v2);
    }

	return (false);
}

void HUDScore::SortByTeam()
{
	typedef stlport::vector<BucketData> bucketlist;

	bucketlist all_team_buckets;
	bucketlist team_bucket_bins[9];
	bucketlist player_bucket_bins[9];

	{for (bucketlist::const_iterator i = m_Buckets.begin();
		  i != m_Buckets.end();
		  ++i)
	{
		if ((*i).bucket != 0)
		{
			if ((*i).bucket->Affects() < 0)
			{
				team_bucket_bins[(- (*i).bucket->Affects()) - 1].push_back(*i);
				all_team_buckets.push_back(*i);
			}
			else
			{
				player_bucket_bins[(*i).bucket->Team()].push_back(*i);
			}
		}
	}}

	m_Buckets.clear();

	std::sort(all_team_buckets.begin(),all_team_buckets.end());

	std::vector<int> sorted_team_numbers;

	{for (bucketlist::const_iterator i = all_team_buckets.begin();
		  i != all_team_buckets.end();
		  ++i)
	{
		int index = (- (*i).bucket->Affects()) - 1;

		if (std::find(sorted_team_numbers.begin(),sorted_team_numbers.end(),index) == sorted_team_numbers.end())
		{
			sorted_team_numbers.push_back((- (*i).bucket->Affects()) - 1);
		}
	}}
	sorted_team_numbers.push_back(8);

	{for (std::vector<int>::const_iterator i = sorted_team_numbers.begin();
		  i != sorted_team_numbers.end();
		  ++i)
	{
		int index = *i;

		{for (bucketlist::iterator j = team_bucket_bins[index].begin();
			  j != team_bucket_bins[index].end();
			  ++j)
		{
			m_Buckets.push_back(*j);
		}}

		std::sort(player_bucket_bins[index].begin(),player_bucket_bins[index].end());

		{for (bucketlist::iterator j = player_bucket_bins[index].begin();
			  j != player_bucket_bins[index].end();
			  ++j)
		{
			m_Buckets.push_back(*j);
		}}
	}}
}

int HUDScore::GetScore4Player(const ReplicatorID& who, int& nKills, int& nDeaths)
{
	int i, nSize = m_Buckets.size();
	for (i=0;i<nSize;i++)
	{
        CBucket* pb = m_Buckets[i].bucket;
		if (pb->Type() == CBucketManager::CUSTOM) // !(pb->Type() == CBucketManager::KILLS && pb->Type() == CBucketManager::DEATHS)
		{
            if (pb->Affects () >= 0) {
                if (pb->RepID() == who) {
                    nKills = Kills(who);
                    nDeaths = Deaths(who);
                    return pb->Value();
                }
            }
		}
	}
    nKills = 0;
    nDeaths = 0;

	return 0;
}

int HUDScore::GetScoreArray(CHudScoreInfo aScores[16], const ReplicatorID& idRoExlcude, int nMode/* = 0*/)
{
	int i, nSize = m_Buckets.size();
    CHudScoreInfo* pScores = &aScores[0];

	for (i=0;i<nSize;i++)
	{
        CBucket* pb = m_Buckets[i].bucket;
		if (pb->Type() == CBucketManager::CUSTOM) // !(pb->Type() == CBucketManager::KILLS && pb->Type() == CBucketManager::DEATHS)
		{
            if (pb->Affects () >= 0) {
                const ReplicatorID& who = pb->RepID();
                if (!&idRoExlcude || (idRoExlcude != who)) {
                    pScores->connectionID = who.connectionID;
                    pScores->m_bBOT = FALSE;
					if (nMode != 1) {
						Connection* conn = Network::GetInstance()->GetConnection(who.connectionID);
						if (conn) {
							Replicator* r = conn->FindReplicator(who);
                            pScores->m_pREP = r;
							if (r && r->GetClassID() == MechClassID) {
								Mech* pMech = Cast_Object(Mech*, r);

								if (pMech && pMech->IsLanceMate()) {
									pScores->m_bBOT = TRUE;
								}
							}
						}
					}
                    pScores->localID = who.localID;
                    pScores->m_nScore = pb->Value();
                    pScores->m_nKills = Kills(who);
                    pScores->m_nDeaths = Deaths(who);
                    pScores++;
                }
            }
		}
	}
    int nCount = pScores - &aScores[0];
    qsort(&aScores[0], nCount, sizeof(CHudScoreInfo), CHudScoreInfo_qsort);

	return nCount;
}

int HUDScore::GetTeamScore(int nTeam, int& nKills, int& nDeaths)
{
    if ((0 <= nTeam) && (nTeam < 8)) {
        nTeam++;
        nTeam = -nTeam;
	    for(int i = 0; i < m_Buckets.size(); i++)
	    {
            CBucket* pBucket = m_Buckets[i].bucket;
            if (pBucket->Affects() == nTeam)
		    {
			    switch(pBucket->Type())
			    {
			    case CBucketManager::KILLS:
			    case CBucketManager::DEATHS:
				    break;
			    default:
                    if (&nKills)
                        nKills = Kills(nTeam);
                    if (&nDeaths)
                        nDeaths = Deaths(nTeam);
				    return pBucket->Value();
			    }
		    }
	    }
    }

    if (&nKills)
        nKills = 0;
    if (&nDeaths)
        nDeaths = 0;

    return 0;
}
