// grsortsubs.user.js
//
// ==UserScript==
// @name          Google Reader Sort Subs
// @namespace     http://www.devoresoftware.com/gm/grss
// @description	  Adds sorts to Google Reader subscriptions view
// @include       http://www.google.com/reader/*
// @include       https://www.google.com/reader/*
// ==/UserScript==
//


var tries = 0;
var item0, treeHeader;
var ascendingCounts;

function ascendingSort()
{
	ascendingCounts = true;
	processSort();
}

function descendingSort()
{
	ascendingCounts = false;
	processSort();
}

function main()
{
	waitForReader();
}

function waitForReader()
{
	// check every fifth of a second for 30 seconds
	var secFract = 5;
	var maxTry = 30 * secFract;
	var waitInterval = 1000 / secFract;

	item0 = document.getElementById("sub-tree-item-0-main");
	treeHeader = document.getElementById("sub-tree-header");
	if (item0 && treeHeader)
	{
		setup();
	}
	else if (tries++ < maxTry)
	{
		setTimeout(waitForReader, waitInterval);
	}
}

function setup()
{
	var upSort = document.createElement('button');
	upSort.appendChild(document.createTextNode("Up"));
	var downSort = document.createElement('button');
	downSort.appendChild(document.createTextNode("Down"));
	var theParent = treeHeader.parentNode;
	var textNode = document.createTextNode("\u00a0\u00a0");
	theParent.insertBefore(textNode, treeHeader.nextSibling);
	theParent.insertBefore(upSort, textNode.nextSibling);
	textNode = document.createTextNode("\u00a0");
	theParent.insertBefore(textNode, upSort.nextSibling);
	theParent.insertBefore(downSort, textNode.nextSibling);
	upSort.addEventListener('click', ascendingSort, true);
	downSort.addEventListener('click', descendingSort, true);
}

function processSort()
{
	var ulList = item0.getElementsByTagName("ul");
	var parentArray = new Array();
	var parentArrayChildren = new Array();
	var parentArrayChildCount = new Array();
	if (ulList)
	{
		for (var i = 0; i < ulList.length; i++)
		{
			var child = ulList[i].firstChild;
			while (child)
			{
				if (child.tagName.toUpperCase() == "LI")
				{
					var results = child.id.match(/sub-tree-item-(\d+)-main/);
					if (results)
					{
						var childIndex = parseInt(results[1]);
						var unreadId = "sub-tree-item-" + childIndex + "-unread-count";
						var spanId = document.getElementById(unreadId);
						if (spanId && spanId.firstChild && spanId.firstChild.nodeName == "#text")
						{
							var nodeVal = spanId.firstChild.nodeValue;
							results = nodeVal.match(/\((\d+)\)/);
							if (results)
							{
								var unreadCount = parseInt(results[1]);
								var found = false;
								var childArrayIndex = 0;
								for (var j = 0; j < parentArray.length; j++)
								{
									if (parentArray[j] == ulList[i])
									{
										childArrayIndex = j;
										found = true;
										break;
									}
								}
								if (!found)
								{
									parentArray.push(ulList[i]);
									childArrayIndex = parentArrayChildren.length;
									var childArray = new Array();
									parentArrayChildren.push(childArray);
									var countArray = new Array();
									parentArrayChildCount.push(countArray);
								}
								var childArray = parentArrayChildren[childArrayIndex];
								childArray.push(child);
								var countArray = parentArrayChildCount[childArrayIndex];
								countArray.push(unreadCount);
							}
						}
					}
				}
				child = child.nextSibling;
			}
		}
	}
	for (var i = 0; i < parentArrayChildren.length; i++)
	{
		var childArray = parentArrayChildren[i];
		var countArray = parentArrayChildCount[i];
		if (countArray.length)
		{
			var theParent = childArray[0].parentNode;
			var childIndexAscend = new Array();
			var childIndexDescend = new Array();
			for (var j = 0; j < childArray.length; j++)
			{
				childIndexAscend[j] = j;
				childIndexDescend[j] = j;
			}
			childIndexAscend.sort(
				function(x,y)
				{
					var a = countArray[x];
					var b = countArray[y];
					return a - b;
				}
			);
			childIndexDescend.sort(
				function(x,y)
				{
					var a = countArray[x];
					var b = countArray[y];
					return b - a;
				}
			);

			if (ascendingCounts)
			{
				// sort ascending by placing each array element as end node
				for (var j = 0; j < childArray.length; j++)
				{
					theParent.insertBefore(childArray[childIndexAscend[j]], null);
				}
			}
			else
			{
				// sort descending
				for (var j = 0; j < childArray.length; j++)
				{
					theParent.insertBefore(childArray[childIndexDescend[j]], null);
				}
			}
		}
	}
}

main();
//window.addEventListener("load", main, false);
/*
GM_registerMenuCommand("Google Reader sort subs ascending", aStart, "", "", "a");
GM_registerMenuCommand("Google Reader sort subs descending", dStart, "", "", "d");
*/

