//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Implementation of CWhoKilledWho
//
// $Workfile:     $
// $Date:         $
//
//------------------------------------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "WhoKilledWho.h"

//------------------------------------------------------------------------------------------------------
// Function:	CWhoKilledWho::init
// Purpose:	initializes the object
//------------------------------------------------------------------------------------------------------
void CWhoKilledWho::init()
{
	nextbid=0;
	if (kills) delete [] kills;
	if (deaths) delete [] deaths;
	deaths=kills=NULL;
}


void CWhoKilledWho::makeBidMap()
{
	int nextbid=0;
	for (int t=0;t<MAX_TEAMS;t++)
	{
		CPlayerListIterator it=g_pMatchInfo->playerBegin();
		for (it;it!=g_pMatchInfo->playerEnd();++it)
		{
			const PID& pid=(*it).first;
			CPlayer& p=(*it).second;

			if (!p.teams.contains(t))
				continue;

			pair<int,PID> pr(t,pid);

			bidMap[pr]=nextbid;
			bidMap2[nextbid]=pr;
			nextbid++;
		}
	}
	size=nextbid;
}


//------------------------------------------------------------------------------------------------------
// Function:	CWhoKilledWho::generate
// Purpose:	generates intermediate data from the match info
//------------------------------------------------------------------------------------------------------
void CWhoKilledWho::generate()
{
	init();
	

	makeBidMap();

	if (size==0)
		return;

	kills=new int[size*size];
	memset(kills,0,sizeof(int)*size*size);

	deaths=new int[size];
	memset(deaths,0,sizeof(int)*size);
	//now the pids table is all full of pids and you index it using Board IDs (bids)
	//also there is a bids table so you know which pid each board entry has.

	CEventListIterator it;
	for (it=g_pMatchInfo->eventList()->begin(); it != g_pMatchInfo->eventList()->end(); ++it)
	{
		if ((*it)->getType()==CLogEvent::SUICIDE || (*it)->getType()==CLogEvent::KILLED_BY_WORLD)
		{
			
			PID plr=(*it)->getArgument(0)->asPlayerGetPID();
			int plrTeam=g_pMatchInfo->playerList()[plr].teams.atTime((*it)->getTime());
			
			pair<int,PID> plrpr(plrTeam,plr);
			
			int plrbid=bidMap[plrpr];
			kills[plrbid*size+plrbid]++;

			deaths[plrbid]++;
			
		}
		else if ((*it)->getType()==CLogEvent::FRAG || (*it)->getType()==CLogEvent::TEAM_FRAG)
		{
			PID killer=(*it)->getArgument(0)->asPlayerGetPID();
			PID killee=(*it)->getArgument(1)->asPlayerGetPID();
			
			int killerTeam=g_pMatchInfo->playerList()[killer].teams.atTime((*it)->getTime());
			int killeeTeam=g_pMatchInfo->playerList()[killee].teams.atTime((*it)->getTime());

			pair<int,PID> killerpr(killerTeam,killer);
			pair<int,PID> killeepr(killeeTeam,killee);
			
			int killerbid=bidMap[killerpr];
			int killeebid=bidMap[killeepr];
			
			kills[killerbid*size+killeebid]++;
			deaths[killeebid]++;
		}
	}
}

//------------------------------------------------------------------------------------------------------
// Function:	CWhoKilledWho::getCellClass
// Purpose:	 Helper function that returns the class of a cell on the board depending
//		on where it occurs in the board. 
// Input:	u - the x position of the cell
//				v - the y position of the cell
// Output:	const char*
//------------------------------------------------------------------------------------------------------
const char* CWhoKilledWho::getCellClass(int u,int v)
{
	char* tdclass;
	if (u == v+1)
		tdclass="class=boardcell_br";
	else if (u>v)
		tdclass="class=boardcell_r";
	if (u == v-1)
		tdclass="class=boardcell_br";
	else if (u<v)
		tdclass="class=boardcell_b";
	else if (u == v)
		tdclass="class=boardcell_br";

	return tdclass;
}

//------------------------------------------------------------------------------------------------------
// Function:	CWhoKilledWho::writeHTML
// Purpose:	takes the intermediate data generated by generate() and writes out
//		HTML to the specified HTML file object
// Input:	html - the object to write the output to
//------------------------------------------------------------------------------------------------------
void CWhoKilledWho::writeHTML(CHTMLFile& html)
{
	if (size==0)
		return;

	int numcols=size+2;
	int numrows=size+4;
	int i=0,j=0;
	
	int playerNameWid=120;
	int cellWid=20;
	int lastColWid=30;
	int tableWid=playerNameWid+size*cellWid+lastColWid;
	
	html.write("<img src=\"%s/detailed.gif\">",g_pApp->supportHTTPPath.c_str());

	string jshttppath(g_pApp->supportHTTPPath);
	jshttppath+="/support.js";

	html.write("<script language=\"JavaScript\" src=\"%s\"></script>\n",jshttppath.c_str());
	html.write("<script language=\"JavaScript\">\n<!--\nthisBrowser = new BrowserType();\nthisBrowser.VerifyIE5()//-->\n</script>\n");
	
	html.write("<script language=\"JavaScript\"> thisBrowser.writeDetailTableTag(%li,%li,%li); </script>\n",tableWid,numrows,numcols);
	
	
	//print columns
	html.write("<tr class=header align=center> <td width=%li align =left><font class=boardtext>Player</font></td>\n",playerNameWid);
	for (i=0;i<size;i++)
	{
		//int tid= g_pMatchInfo->playerTeamID(pids[i]);
		//int tid=3;
		int tid=bidMap2[i].first;
		html.write("<td width=%li><font class=player%s>%2d</font></th>\n",cellWid,Util::teamcolormap[tid],i);
	}
	html.write("<td align=left width=%li><font class=boardtext>Kills</font></th>\n",lastColWid);
	html.write("</tr>\n");
	

	int totalkills=0;
	int killerbid;
	for (killerbid=0;killerbid<size;++killerbid)
	{
		int tot=0;
		char truncatedPlayerName[21];
		strncpy(truncatedPlayerName, g_pMatchInfo->playerName(bidMap2[killerbid].second).c_str(),20);
		truncatedPlayerName[20]=0;
		//int tid=g_pMatchInfo->playerTeamID(pids[killerbid]);
		int tid=bidMap2[killerbid].first;
		html.write("<tr><td class=boardcell_b align=left width=%li><font class=player%s><nobr>%d. %s</nobr></font></th>\n",playerNameWid,Util::teamcolormap[tid], killerbid,truncatedPlayerName);
		
		int killeebid;
		for (killeebid=0;killeebid<size;++killeebid)
		{
			const char* tdclass=getCellClass(killeebid,killerbid);
			html.write("<td align=center width=%li %s><font class=boardtext>%i</font></td>\n",cellWid,tdclass,kills[killerbid*size+killeebid]);
			
			if (killeebid != killerbid)
				tot+=kills[killerbid*size+killeebid];
			else
				tot-=kills[killerbid*size+killeebid];
		}

		totalkills+=tot;
		html.write("<td align=center width=%li><font class=boardtext>%i</font></td>\n",lastColWid,tot);
		html.write("</tr>\n");
	}
	
	html.write("<tr align=left> <td><font class=boardtext>Deaths</font></th>\n");

	int totaldeaths=0;
	for (i=0;i<size;i++)
	{
		html.write("<td align=center><font class=boardtext>%i</font></td>\n",deaths[i]);
		totaldeaths+=deaths[i];
	}
	
	//html.write("<td align=left ><font class=boardtext>%3i\\%3i</font></td>\n",totaldeaths,totalkills);
	html.write("<td></td>\n");
	html.write("</tr>\n");
	html.write("</table>\n");

}
	
//------------------------------------------------------------------------------------------------------
// Function:	CWhoKilledWho::~CWhoKilledWho
// Purpose:	 destructor
//------------------------------------------------------------------------------------------------------
CWhoKilledWho::~CWhoKilledWho()
{
	if (kills) delete [] kills;
	if (deaths) delete [] deaths;
}