#include "out_formats.h"
#include "out_xhtmlgen.h"
#include <time.h>
#include <math.h>

#define SET_MAX_IMAGES	(4)
#define SET_MAX_HAPPY	(6)
#define SET_MAX_PER_ROW	(5)


int FUNCTION_NAME(FILE *outFile, t_stats *pStats, t_fisgconfig *pCfg)
{
 char *hBarImages[SET_MAX_IMAGES] = { "blue-h.png", "green-h.png", "yellow-h.png", "red-h.png" };
 char *vBarImages[SET_MAX_IMAGES] = { "blue-v.png", "green-v.png", "yellow-v.png", "red-v.png" };
 t_ulint j, iRank;
 int i, iHour;
 t_float graphScale, happyScale, sadScale;
 t_user_entry *tmpUser;
 time_t tmpTime;
 struct tm *tmpLocalTime;
 char tmpTimeStr[SET_MAX_BUF];
 t_str_index *tmpI;
 t_str_node *tmpS;

 /* Get time/date string */
 time(&tmpTime);
 tmpLocalTime = localtime(&tmpTime); 
 if (strftime(tmpTimeStr, sizeof(tmpTimeStr), pCfg->dateFormat, tmpLocalTime) == 0)
 	{
	/* Unable to create string, make it empty */
 	tmpTimeStr[0] = 0;
 	}
    
 /* Output stats as XHTML */
 fprintf(outFile,
	HTML_DOCTYPE
	HTML_TAG
	"<head>\n"
	" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n"
	" <meta http-equiv=\"Cache-Control\" content=\"no-cache\" />\n"
	);

 fprintf(outFile,
	" <link rel=\"stylesheet\" title=\"Default\" href=\"%s\" type=\"text/css\" />\n"
	" <meta name=\"Author\" content=\"" FISG_NAME " v" FISG_VERSION " (" FISG_FULLNAME ")\" />\n"
	" <title>" FISG_NAME " Statistics for %s%s%s</title>\n"
	"</head>\n"
	"<body>\n",
	xhtml_cfg.cssPath,
	pCfg->ircChannel,
	(pCfg->ircNetwork) ? " @ " : "",
	(pCfg->ircNetwork) ? pCfg->ircNetwork : ""
	);

 fprintf(outFile,
	"<div class=\"ibodydiv\"" HTML_DIV_PARAMS ">\n"
	"<div class=\"icontents\">\n"
	" <div class=\"iinfo\">\n"
	"  <h1>%s%s%s</h1>\n"
	"  <p class=\"idate\">Statistics generated on <b>%s</b></p>\n"
/*
	"  <p class=\"ivisitors\">During this <b>%ld</b>-day reporting period, a total of <b>%ld</b> different nicks/users were represented on <b>%s</b>.</p>\n"
*/
	"  <p class=\"ivisitors\">A total of <b>%ld</b> different nicks/users were represented on <b>%s</b>.</p>\n"
	"%s%s%s"
	" </div>\n",

	pCfg->ircChannel,
	(pCfg->ircNetwork) ? " @ " : "",
	(pCfg->ircNetwork) ? pCfg->ircNetwork : "",

	tmpTimeStr,
/*	pStats->nDays, */
	pStats->usersList->n,
	pCfg->ircChannel,
	(pCfg->message) ? "  <p class=\"imessage\">" : "",
	(pCfg->message) ? pCfg->message : "",
	(pCfg->message) ? "</p>\n" : ""
	);

 /*
  * DAILY ACTIVITY
  */
 if (pCfg->statActiveTimes)
 {
 if (pStats->activityPeak >= 0)
 if (pStats->fActivityPerHour[pStats->activityPeak] > 0)
 {
 fprintf(outFile,
	"<!-- ============================================= -->\n"
	" <div class=\"ihourly\">\n"
	"  <h2>Most active times</h2>\n"
	"  <table" HTML_TABLE_PARAMS " class=\"ihourly\">\n"
	"   <tr>\n"
	);
 
 graphScale = (100 / pStats->fActivityPerHour[pStats->activityPeak]);
 for (iHour = 0; iHour < SET_HOURS_DAY; iHour++)
	{
	fprintf(outFile,
	"    <th valign=\"bottom\">%1.1f%%<br />"
	"<img src=\"%s/%s\" width=\"15\" height=\"%d\" alt=\"%1.1f%%\" /></th>\n",

	pStats->fActivityPerHour[iHour],
	xhtml_cfg.dataPath, vBarImages[iHour / SET_DAY_DIVISOR],
	(int) (pStats->fActivityPerHour[iHour] * graphScale),
	pStats->fActivityPerHour[iHour]);
	}

 fprintf(outFile,
 	"   </tr>\n"
 	"   <tr>\n"
 	);

 for (iHour = 0; iHour < SET_HOURS_DAY; iHour++)
	{
	fprintf(outFile,
	"    <td class=\"%s\">%i</td>\n",
	(iHour == pStats->activityPeak) ? "hirank" : "rank", iHour);
	}

 fprintf(outFile,
 	"   </tr>\n"
 	"  </table>\n"
 	"\n"
 	"  <table" HTML_TABLE_PARAMS " class=\"ihourbars\">\n"
 	"   <tr>\n"
 	);
 	
 for (iHour = 0; iHour < SET_HOURS_DAY; iHour += SET_DAY_DIVISOR)
 	{
 	fprintf(outFile,
	"    <td class=\"asmall\"><img src=\"%s/%s\" width=\"40\" height=\"15\" alt=\"%i-%i\" /> = %i-%i</td>\n",
	xhtml_cfg.dataPath, hBarImages[iHour / SET_DAY_DIVISOR],
	iHour, (iHour+SET_DAY_DIVISOR-1),
	iHour, (iHour+SET_DAY_DIVISOR-1));
	}

 fprintf(outFile,
 	"   </tr>\n"
 	"  </table>\n"
 	" </div>\n"
	);
 }
 
 } /* if (CFG_GEN_STAT_ACTIVE) */


 /*
  * TOP TALKERS
  */
 if (pCfg->statTopUsers)
 {
 fprintf(outFile,
	"<!-- ============================================= -->\n"
	" <div class=\"itoptalkers\">\n"
	"  <h2>Most active users</h2>\n"
 	"  <table" HTML_TABLE_PARAMS " class=\"itoptalkers\">\n"
 	"   <tr>\n"
 	"    <th width=\"2%%\" class=\"nrank\">#</th>\n"
	);

 fprintf(outFile,
	"%s"
 	"    <th width=\"10%%\" class=\"nhandle\">Nickname</th>\n"
 	"    <th width=\"6%%\" class=\"npublics\">Lines</th>\n"
 	"    <th width=\"15%%\" class=\"nactivity\">Activity</th>\n"
 	"    <th width=\"5%%\" class=\"nwords\">Words</th>\n"
 	"    <th width=\"2%%\" class=\"nwpp\">W/P</th>\n"
 	"    <th width=\"2%%\" class=\"ncpw\">C/W</th>\n"
	"%s"
	"%s"
	"   </tr>\n",
	(pCfg->showHappy) ? "    <th width=\"2%%\" class=\"nhappiness\">?</th>\n" : "",
 	(pCfg->showComment) ? "    <th width=\"50%%\" class=\"ncomment\">Comment</th>\n" : "",
 	(pCfg->showPicture) ? "    <th width=\"5%%\" class=\"npicture\">Picture</th>\n" : ""
	);
 
 if (fabs(pStats->mostHappy->fHappiness) > 0)
 	happyScale = fabs(pStats->mostHappy->fHappiness);
 	else
 	happyScale = 1.0f;

 if (fabs(pStats->mostSad->fHappiness) > 0)
	sadScale = fabs(pStats->mostSad->fHappiness);
	else
	sadScale = 1.0f;

 for (iRank = 0;
	iRank < ((pStats->usersList->n >= pCfg->showTopUserMax) ?
	pCfg->showTopUserMax : pStats->usersList->n);
	iRank++)
 	{
	/* Get user */
	tmpUser = pStats->usersList->ppIndex[iRank];
	if (!tmpUser) break;

	/* Print one line */ 	
 	fprintf(outFile,
 	"   <tr>\n"
 	"    <td class=\"nrank\">%ld</td>\n",
 	(iRank + 1)
	);

	if (pCfg->showHappy)
		{
		if (tmpUser->fHappiness > 0)
			j = 3 + (int) ((tmpUser->fHappiness * 3.0f) / happyScale);
			else
			j = 3 + (int) ((tmpUser->fHappiness * 2.0f) / sadScale);

	 	fprintf(outFile,
		"    <td class=\"nhappiness\"><img src=\"%s/happy%ld.gif\" alt=\"%ld\" /></td>\n",
		xhtml_cfg.dataPath, j, j);
		}

	/* Print user handle with link URL, if specified */
	if (tmpUser->linkURL && pCfg->showURL)
		{
		fprintf(outFile,
 		"    <td class=\"nhandle\"><a href=\"");
		
		xml_fprintf_urlencode(outFile, tmpUser->linkURL);

		fprintf(outFile, "\">");

		xml_fprintf_entitize(outFile, tmpUser->userHandle);

		fprintf(outFile, "</a></td>\n");
		} else {
		fprintf(outFile,
 		"    <td class=\"nhandle\">");

		xml_fprintf_entitize(outFile, tmpUser->userHandle);

		fprintf(outFile, "</td>\n");
		}
	
	
 	fprintf(outFile,
 	"    <td class=\"npublics\">%ld</td>\n"
 	"    <td class=\"nactivity\">",
 	tmpUser->nPublics
 	);

	for (iHour = 0; iHour < SET_HOURS_DAY; iHour += SET_DAY_DIVISOR)
	 	{
	 	graphScale = 0;
	 	for (j = 0; j < SET_DAY_DIVISOR; j++)
	 		graphScale += (tmpUser->fActivityPerHour[iHour + j] / 1.5f);

		if (graphScale >= 1.0f)
			{
		 	fprintf(outFile,
		 	"<img src=\"%s/%s\" width=\"%i\" height=\"15\" alt=\"\" />",
		 	xhtml_cfg.dataPath, hBarImages[iHour / SET_DAY_DIVISOR],
		 	(int) (graphScale));
		 	}
		}	

 	fprintf(outFile,
 	"</td>\n"
 	"    <td class=\"nwords\">%ld</td>\n"
 	"    <td class=\"nwpp\">%1.2f</td>\n"
 	"    <td class=\"ncpw\">%1.2f</td>\n",
 	tmpUser->nWords,
 	tmpUser->fWordsPerPublic,
 	tmpUser->fCharsPerWord
 	);

	if (pCfg->showComment)
		{
 		fprintf(outFile,
 		"    <td class=\"ncomment\">");

		if (tmpUser->sComment)
			xml_fprintf_entitize(outFile, tmpUser->sComment);

		fprintf(outFile, "</td>\n");
		}

	if (pCfg->showPicture)
		{
 		fprintf(outFile,
 		"    <td class=\"npicture\">");

		if (tmpUser->picPath)
			{
			fprintf(outFile, "<img src=\"");
			xml_fprintf_urlencode(outFile, xhtml_cfg.dataPath);
			fprintf(outFile, "/");
			xml_fprintf_urlencode(outFile, tmpUser->picPath);
			fprintf(outFile, "\">");
			}

		fprintf(outFile, "</td>\n");
		}

 	fprintf(outFile,
 	"   </tr>\n");
 	}

 fprintf(outFile,
 	"  </table>\n"
	"<!-- ============================================= -->\n"
	);

 /*
  * ALMOST MADE IT...
  */
 if (pCfg->statAlmostTop)
 {
 if (iRank < pStats->usersList->n)
 {
 fprintf(outFile,
 	" <h3>These didn't make it to the top:</h3>\n"
 	" <table" HTML_TABLE_PARAMS " class=\"ialmosttop\">\n"
 	);

 j = (pStats->usersList->n >= (iRank + pCfg->showAlmostMax)) ? (iRank + pCfg->showAlmostMax) : pStats->usersList->n;
 for (i = -1; iRank < j; iRank++)
 	{
	/* Get user */
	tmpUser = pStats->usersList->ppIndex[iRank];
	if (!tmpUser) break;

 	if (i < 1)
 		{
 		if (i >= 0)
 		fprintf(outFile, "  </tr>\n");

 		if ((j - iRank) >= SET_MAX_PER_ROW)
 		fprintf(outFile, "  <tr>\n");

 		i = SET_MAX_PER_ROW;
 		}

	/* Print user handle with link URL, if specified */
	if (tmpUser->linkURL && pCfg->showURL)
		{
		fprintf(outFile,
 		"    <td><a href=\"");
		
		xml_fprintf_urlencode(outFile, tmpUser->linkURL);

		fprintf(outFile, "\">");

		xml_fprintf_entitize(outFile, tmpUser->userHandle);

		fprintf(outFile, "</a> (%ld)</td>\n",
		tmpUser->nPublics);
		} else {
		fprintf(outFile,
 		"    <td>");

		xml_fprintf_entitize(outFile, tmpUser->userHandle);

		fprintf(outFile, " (%ld)</td>\n",
		tmpUser->nPublics);
		}

	i--; 		
	}

 if (i >= 0)
 	fprintf(outFile, "  </tr>\n");

 fprintf(outFile,
 	" </table>\n"
	);
	
 /* Rest of nicks */
 if (iRank < pStats->usersList->n)
 	{
 	fprintf(outFile,
 		" <h3>There were also <b>%ld</b> other nicks</h3>\n",
 		(pStats->usersList->n - iRank)
 		);
 	}
 }
 
 } /* if (CFG_GEN_STAT_ALMOST)  */

 fprintf(outFile,
 	" </div>\n"
	"<!-- ============================================= -->\n"
	);

 } /* if (CFG_GEN_STAT_TOP) */


 /*
  * MOST REFERENCED URLS
  */
 tmpI = pStats->urlIndex;
 if (pCfg->statURLs && tmpI)
 {
 fprintf(outFile,
	"<div class=\"iurls\">\n"
	" <h2>Most referenced URLs</h2>\n"
 	" <table" HTML_TABLE_PARAMS " class=\"iurls\">\n"
 	"  <tr>\n"
 	"   <th width=\"2%%\" class=\"nrank\">#</th>\n"
 	"   <th width=\"96%%\" class=\"nurl\">URL</th>\n"
 	"   <th width=\"2%%\" class=\"nrefs\">References</th>\n"
	"  </tr>\n"
	);

 for (iRank = 0; iRank < ((tmpI->n >= pCfg->showURLsMax) ? pCfg->showURLsMax : tmpI->n); iRank++)
 	{
	tmpS = tmpI->ppIndex[iRank];
	fprintf(outFile,
	"  <tr><td class=\"nrank\">%ld</td>"
	"<td class=\"nurl\"><a href=\"http://",
	(iRank + 1));

	xml_fprintf_urlencode(outFile, tmpS->pcStr);

	fprintf(outFile, "\">http://");

	xml_fprintf_entitize(outFile, tmpS->pcStr);

	fprintf(outFile,
	"</a></td><td class=\"nrefs\">%ld</td></tr>\n",
	tmpS->nUsed);
	}

 fprintf(outFile,
	" </table>\n"
 	"</div>\n"
	"<!-- ============================================= -->\n"
	);
 }


 /*
  * BIG NUMBERS
  */
 if (pCfg->statBigNumbers)
 {
 fprintf(outFile,
 	"<div class=\"ibignumbers\">\n"
 	" <h2>Big Numbers</h2>\n");

 if (pStats->mostStupid && (pStats->mostStupid->nQuestions > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  Is <b>%s</b> stupid or just asking too many questions? <b>%1.1f%%</b> of his lines contained a question!\n"
 	" </p>\n",
	pStats->mostStupid->userHandle,
	((t_float) pStats->mostStupid->nQuestions / (t_float) pStats->mostStupid->nPublics) * 100.0f);
	}

 if (pStats->mostLoud && (pStats->mostLoud->nYelling > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  The loudest one was <b>%s</b>, who yelled <b>%1.1f%%</b> of the time."
 	" </p>\n",
	pStats->mostLoud->userHandle,
	((t_float) pStats->mostLoud->nYelling / (t_float) pStats->mostLoud->nPublics) * 100.0f);
	}

 if (pStats->mostURLs && (pStats->mostURLs->nURLs > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  Total of <b>%ld</b> URLs were pasted by <b>%s</b>!!\n"
 	" </p>\n",
 	pStats->mostURLs->nURLs, pStats->mostURLs->userHandle);
	}
 
 if (pStats->mostJoins && (pStats->mostJoins->nJoins > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  <b>%s</b> didn't know whether to stay. He/she joined the channel <b>%ld</b> times!\n"
 	" </p>\n",
 	pStats->mostJoins->userHandle, pStats->mostJoins->nJoins);
	}
 
 if (pStats->mostKicks && (pStats->mostKicks->nKicks > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  <b>%s</b> kicked the ass most, <b>%ld</b> times to be exact!\n"
 	" </p>\n",
 	pStats->mostKicks->userHandle, pStats->mostKicks->nKicks);
	}

 if (pStats->mostKicked && (pStats->mostKicked->nGotKicked > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  Obviously someone does not like <b>%s</b>, he/she was kicked <b>%ld</b> times!\n"
 	" </p>\n",
 	pStats->mostKicked->userHandle, pStats->mostKicked->nGotKicked);
	}
 
 if (pStats->mostCaps && (pStats->mostCaps->fCapsPercent > 0.1f))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  <b>%s</b> is a clear caps-abuser, <b>%1.1f%%</b> of time he/she wrote in CAPS."
 	" </p>\n",
	pStats->mostCaps->userHandle, pStats->mostCaps->fCapsPercent);
	}

 if (pStats->mostHappy)
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  <b>%s</b> is either using drugs or is otherwise very <b>happy</b> person <b>;D</b>"
 	" </p>\n",
	pStats->mostHappy->userHandle);
	}

 if (pStats->mostSad)
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  On the other hand <b>%s</b> seems to be quite <b>sad</b> <b>:(</b>"
 	" </p>\n",
	pStats->mostSad->userHandle);
	}

 if (pStats->mostTopics && (pStats->mostTopics->nTopics > 0))
	{
	fprintf(outFile,
 	" <p class=\"isection\">\n"
 	"  <b>%s</b> changed the topic <b>%ld</b> times!\n"
 	" </p>\n",
 	pStats->mostTopics->userHandle, pStats->mostTopics->nTopics);
	}

 fprintf(outFile,
 	"</div>\n"
	"<!-- ============================================= -->\n"
	);
 }


 /*
  * LATEST TOPICS
  */
 tmpI = pStats->topicIndex;
 if (pCfg->statTopics && tmpI)
 {
 fprintf(outFile,
 	"<div class=\"itopics\">\n"
 	" <h2>Latest topics</h2>\n"
 	" <table" HTML_TABLE_PARAMS " class=\"itopics\">\n"
 	"  <tr>\n"
 	"   <th width=\"90%%\" class=\"ntopic\">Topic</th>\n"
 	"   <th width=\"10%%\" class=\"nsetby\">Set by</th>\n"
	"  </tr>\n"
	);

 for (iRank = 0; iRank < ((tmpI->n >= pCfg->showTopicsMax) ? pCfg->showTopicsMax : tmpI->n); iRank++)
 	{
	tmpS = tmpI->ppIndex[iRank];
	fprintf(outFile, "  <tr><td class=\"ntopic\">");

	xml_fprintf_entitize(outFile, tmpS->pcStr);

	fprintf(outFile, "</td><td class=\"nsetby\">");

	if (tmpS->pData)
		{
		xml_fprintf_entitize(outFile,
			((t_user_entry *) tmpS->pData)->userHandle);
		}

	fprintf(outFile, "</td></tr>\n");
	}

 fprintf(outFile,
	" </table>\n"
 	"</div>\n"
	"<!-- ============================================= -->\n"
	);
 }


 /*
  * INFO footer
  */
 fprintf(outFile,
	" <div class=\"irestinfo\">\n"
	"  <p class=\"ilines\">Totals analyzed: <b>%ld</b> lines in <b>%ld</b> logfiles"
	"  summing to appr. <b>%1.2f</b> MB.</p>\n"
	"  <p class=\"iauthor\">Statistics generated by "
	"<a href=\"http://www.tnsp.org/fisg.php\">" FISG_NAME
	" (" FISG_FULLNAME ") v" FISG_VERSION "</a> " FISG_COPYRIGHT "</p>\n"
	"  <p class=\"itime\">Stats generated in <b>%ld hours, %ld minutes and %ld seconds</b>.</p>\n"
	" </div>\n",
	pStats->nLines, pStats->nLogFiles, ((t_float) pStats->nChars) / (1024.0f*1024.0f),
	(pStats->nTimeElapsed / (60*60)),
	(pStats->nTimeElapsed % (60*60)) / 60, 
	(pStats->nTimeElapsed % (60*60)) % 60
	);

 /* Output HTML footer */
 fprintf(outFile,
	"<!-- ============================================= -->\n"
	"</div>\n"
	"</div>\n"
	"</body>\n"
	"</html>\n");

 return 0;
}




syntax highlighted by Code2HTML, v. 0.9.1