// mondo_statme.user.js
//
// Copyright 2007, Michael Devore
// This file is licensed under the terms of the Artistic License.
// See http://www.opensource.org/licenses/artistic-license.php for the license itself.
//
// This is a Greasemonkey script.
// See http://greasemonkey.mozdev.org/ for more information on Greasemonkey.
//
// ==UserScript==
// @name          Mondo StatMe
// @namespace     http://www.devoresoftware.com/gm/ms
// @description	Slightly silly statistics on post comments
// @include       http://*.metafilter.com/*
// ==/UserScript==
//
// Based on Mondo Meta script
// Work begun, January 2007
// Version 1.0, released January 2007
// Version 1.1, released January 2007
// Version 1.2, released mid-February 2007
//

function kickit()
{
	if (window.location.href.match(/metafilter.com\/$/) != null)
	{
		// don't do stats on a main screen
		return;
	}

	var xpath = "//div[@class='copy' or @class='comments' or @class='comments best']";
	var divNodes = document.evaluate(
		xpath,
		document,
		null,
		XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
		null
	);


	var aUsers = new Array();
	var aUserLink = new Array();
	var aUserLastLink = new Array();
	var aUserLastTime = new Array();
	var veryLastUser = null;
	var startNode = null;
	for (var i = 0; i < divNodes.snapshotLength; i++)
	{
		var aNode = divNodes.snapshotItem(i);
		if (startNode == null && aNode.getAttribute('class') === "copy")
		{
			// main post
			startNode = aNode;
		}
		else if (startNode != null &&
			(aNode.getAttribute('class') === "comments" || aNode.getAttribute('class') === "comments best"))
		{
			var cNode = aNode.firstChild;
			while (cNode && (cNode.nodeName != "SPAN" || cNode.getAttribute('class') != "smallcopy"))
			{
				cNode = cNode.nextSibling;
			}
			if (cNode)
			{
				// new comment footer info
				// do some minimal qualification in case of extensions
				var c2Node = cNode.firstChild;
				var userHrefText = null;
				while (c2Node && (c2Node.nodeName != "A" ||
					userHrefText.match("http://www\.metafilter\.com/user/[0-9]+") === null))
				{
					c2Node = c2Node.nextSibling;
					if (c2Node.nodeName === "A")
					{
						userHrefText = c2Node.getAttribute('href');
					}
				}

				// get the user, update the count
				var tNode = null;
				if (c2Node)
				{
					// got our "A", get the text
					tNode = c2Node.firstChild;
					while (tNode && tNode.nodeName != "#text")
					{
						tNode = tNode.nextSibling;
					}
					var bFound = false;
					if (tNode)
					{
						var userName = tNode.nodeValue;
						if (userName != null)
						{
							bFound = true;
							if (aUsers[userName] === undefined)
							{
								aUsers[userName] = 0;
								aUserLink[userName] = userHrefText;
							}
							aUsers[userName]++;
							veryLastUser = userName;
						}
					}

					// grab the link to the last comment
					var aNode = null;
					if (bFound)
					{
						var commentHrefText = null;
//						var matchString = "/mefi/[0-9]+#[0-9]+";
						var matchString = "/[0-9]+";
						aNode = c2Node.nextSibling;
						while (aNode && (aNode.nodeName != "A" ||
							commentHrefText.match(matchString) === null))
						{
							aNode = aNode.nextSibling;
							if (aNode && aNode.nodeName === "A")
							{
								commentHrefText = aNode.getAttribute('href');
							}
						}
						if (aNode)
						{
							aUserLastLink[userName] = commentHrefText;
						}
					}
					
					// grab the last time
					if (bFound && aNode)
					{
						aUserLastTime[userName] = null;
						tNode = aNode.firstChild;
						if (tNode != null)
						{
							aUserLastTime[userName] = tNode.nodeValue;
						}
						tNode = aNode.nextSibling;
						if (tNode)
						{
							aUserLastTime[userName] += tNode.nodeValue;
						}
						// kill the weird linefeeds
						aUserLastTime[userName] = aUserLastTime[userName].replace(/\n/g,"");
					}
				}
			}
		}
	}

	var uniqueCount = 0;
	var totalCount = 0;
	var aSortInfo = new Array();
	for (storedUser in aUsers)
	{
		aSortInfo[uniqueCount++] = storedUser;
		totalCount += aUsers[storedUser];
	}
	aSortInfo.sort( function(a,b) {
		if (aUsers[b] != aUsers[a])
		{
			return aUsers[b] - aUsers[a];
		}
		else
		{
			return a.toLowerCase() > b.toLowerCase() ? 1 : (a.toLowerCase() < b.toLowerCase() ? -1 : 0);
		}
	 } );

	// get our style in there
	var addHeader =
		'DIV.mondo_statme { align: right; float: right; margin-left: 10px; margin-right: 10px; font-size: smaller; }';
	var msStyle = document.createElement("style");
	msStyle.setAttribute('type', 'text/css');
	msStyle.innerHTML = addHeader;
	document.getElementsByTagName('head')[0].appendChild(msStyle);

	// give all the new info its own DIV
	var newDiv = document.createElement("DIV");
	newDiv.setAttribute("class", "mondo_statme");

	// last comment by
	var newBR = document.createElement("BR");
	newDiv.appendChild(newBR);

	if (totalCount > 0)
	{
		var newAnchor = document.createElement("A");
		newAnchor.setAttribute("href", aUserLastLink[veryLastUser]);
		var newText = document.createTextNode("Latest comment");
		newAnchor.appendChild(newText);
		newDiv.appendChild(newAnchor);
		newText = document.createTextNode(" by: ");
		newDiv.appendChild(newText);
		newAnchor = document.createElement("A");
		newAnchor.setAttribute("href", aUserLink[veryLastUser]);
		newText = document.createTextNode(veryLastUser);
		newAnchor.appendChild(newText);
		newDiv.appendChild(newAnchor);
		newBR = document.createElement("BR");
		newDiv.appendChild(newBR);	// whack the long line into two
		newText = document.createTextNode("at " + aUserLastTime[veryLastUser]);
		newDiv.appendChild(newText);
	}
	else
	{
		newText = document.createTextNode("No one has commented yet.");
		newDiv.appendChild(newText);
	}


	// contributors
	newBR = document.createElement("BR");
	newDiv.appendChild(newBR);
	newText = document.createTextNode("Contributors (" + totalCount + " total, " + uniqueCount + " unique):");
	newDiv.appendChild(newText);

	// and the stats, please...
	for (var i = 0; i < aSortInfo.length; i++)
	{
		newBR = document.createElement("BR");
		newDiv.appendChild(newBR);
		newAnchor = document.createElement("A");
		newAnchor.setAttribute("href", aUserLink[aSortInfo[i]]);
		newText = document.createTextNode(aSortInfo[i]);
		newAnchor.appendChild(newText);
		newDiv.appendChild(newAnchor);

//		newText = document.createTextNode(" (" + aUsers[aSortInfo[i]] + ")");
		var linkAnchor = document.createElement("A");
		linkAnchor.setAttribute("href", aUserLastLink[aSortInfo[i]]);
		var lastText = document.createTextNode(aUsers[aSortInfo[i]]);
		linkAnchor.appendChild(lastText);
		var newTextLParen = document.createTextNode(" (");
		var newTextRParen = document.createTextNode(")");
		newDiv.appendChild(newTextLParen);
		newDiv.appendChild(linkAnchor);
		newDiv.appendChild(newTextRParen);
	}

	// separator afterwards
	newBR = document.createElement("BR");
	newDiv.appendChild(newBR);

	// stick it in there
	startNode.appendChild(newDiv);
}

function main()
{
	kickit();
}

window.addEventListener( "load", main, false );
