// ==UserScript==
// @name        Hackszine, Makezine and Craftzine Category Viewer
// @namespace   http://blogs.sun.com/richb
// @description Generate a list of Hackszine, Makezine or Craftzine posts by category
// @include     http://www.hackszine.com/
// @include     http://www.makeszine.com/blog/
// @include     http://www.craftszine.com/blog/
// ==/UserScript==

// Version: 0.3 - 7th November 2007.
// Author:  Rich Burridge - Sun Microsystems Inc.
//          with help from Tyler Trafford for multi-page category support.

if (typeof GM_xmlhttpRequest != 'function') {
    // do nothing
} else {
    if (window == top) {

        // Find all the "plain" class entries.
        var allPlains = document.evaluate(
            "//ul[@class='plain']",
            document,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null);

        // Extract out all the category links. from the first "plain" class
        // entry.
        firstPlain = allPlains.snapshotItem(0);
        var allCategories = document.evaluate(
            ".//*[@href]",
            firstPlain,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null);

        // Clear out the original body of the web page.
        document.body = document.createElement("body");

        // Process each of the categories and append the generated HTML
        // to the new body of the web page.
        for (var i = 0; i < allCategories.snapshotLength; i++) {
            thisLink = allCategories.snapshotItem(i);

            newH2 = document.createElement("h2");
            newH2.innerHTML = '<a href="' + thisLink.href + '">' + 
                                            thisLink.textContent + '</a>\n'
            document.body.appendChild(newH2);

            newDiv = document.createElement("div");
            document.body.appendChild(newDiv);

            process_url(newDiv, thisLink.href);
        }
    }
}

function process_url(newDiv, pageUrl) {
    GM_xmlhttpRequest({
        method:'GET',
        url:pageUrl,
        onload:function(responseDetails){
            thisPage = document.createElement("div");
            thisPage.innerHTML = responseDetails.responseText

            // Find out the H2 headers on the page with an href attribute.
            var allEntries = document.evaluate(
            ".//h2",
            thisPage,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null);

            var newHTML = '<ul>\n';

            for (var k = 0; k < allEntries.snapshotLength; k++) {
                thisEntry = allEntries.snapshotItem(k);
                newHTML = newHTML + '  <li>' + thisEntry.innerHTML + '</li>\n';
            }

            newHTML = newHTML + '</ul>\n';
            newDiv.innerHTML = newHTML;

            // Check to see if this category has multiple pages. If they do,
            // process the new category sub-page, and append the generated
            // HTML to the div element for this category.
            var pageString = document.evaluate(
                './/p[starts-with(text(),"Page 1 of")]/text()',
                thisPage,
                null,
                XPathResult.STRING_TYPE,
                null).stringValue;
            if (pageString) {
                var maxPageNum = pageString.match(/\d+/g)[1];

                for (var i = 2; i <= maxPageNum; i++) {
                    var catSubDiv = document.createElement("div");
                    newDiv.appendChild(catSubDiv);
                    process_url(catSubDiv, pageUrl + "/" + i + ".html");
                }
            }
        }
    });
}

// ChangeLog
// 8th Nov 2007 - 0.3 - richb - handle categories with multiple sub-pages.
// 7th Nov 2007 - 0.2 - richb - handle categories with multiple sub-pages.
// 6th Nov 2007 - 0.1 - richb - Initial version posted to blog.
