/**
Minimal, but extendable, implementation of a tag cloud.

Applies a relative css 'font-size' property between 50% and 150% on each tag.

Calculates percentages for each tag based on raw counts, then scales text sizes
to match.  Takes advantage of the new HTML5 data attributes to read raw counts.

Expected to work on the following HTML structure:

<ol class="tagcloud">
<li><a href="/blog/tags/biscuits.html" data-count="13">Biscuits</a></li>
<li><a href="/blog/tags/cake.html" data-count="27">Cake</a></li>
<li><a href="/blog/tags/christmas.html" data-count="143">Christmas</a></li>
...etc...
</ol>

@author    Leon Matthews <leon@lost.co.nz>
@copyright Copyright 2010 Leon Matthews. All rights reserved.
@link      http://www.lost.co.nz/
*/
(function()
{
    /**
    Start here
    */
    function main()
    {
        var divs, div, i, tag, tags;

        // Find containers with the right class
        containers = jQuery('ol.tagcloud');
        for( i=0; i<containers.length; i++)
        {
            // Find all tag links within each div
            container = containers[i];
            tags = jQuery(container).find('a');

            // Generate 0.0 to 100.0 value for each tag
            percentages = calculatePercentages(tags);

            // Apply CSS rules to tags
            for( i=0; i < tags.length; i++)
            {
                tag = tags[i];
                tag = jQuery(tag);
                percentage = percentages[i];

                // Font size from 50% to 150%
                font_size = (percentage + 50) + '%';
                tag.css('fontSize', font_size);

                // Font weight from 100 to 900
                font_weight = (percentage * 8) + 100;
                tag.css('fontWeight', font_weight);
            }
        }
    }

    function calculatePercentages(tags)
    {
        var counts, i, total, tag, count, max, min,
            raw_percentage, raw_percentages,
            scale_factor, percentage, percentages;

        // Calculate total count, build counts array
        counts = [];
        total = 0;
        for( i=0; i<tags.length; i++)
        {
            tag = tags[i];
            count = getCount(tag);
            counts[i] = count;
            total += count;
        }

        // Calculate raw percentages, incl. max/min
        max = 0.0;
        min = 100.0;
        raw_percentage = 0.0;
        raw_percentages = [];
        for( i=0; i < counts.length; i++)
        {
            count = counts[i];
            raw_percentage = count/total * 100;
            min = Math.min(min, raw_percentage);
            max = Math.max(max, raw_percentage);
            raw_percentages[i] = raw_percentage;
        }

        // Expand raw percentages to cover full 0-100 range
        scale_factor = 100 / (max-min);
        percentages = [];
        for( i=0; i < raw_percentages.length; i++)
        {
            raw_percentage = raw_percentages[i];
            percentage = ((raw_percentage - min) * scale_factor);
            percentage = Math.round(percentage);
            percentages[i] = percentage;
        }

        return percentages;
    }

    /**
    Return the count for the given tag.
    Guaranteed to return at least one, emits console warning on error.
    */
    function getCount(tag)
    {
        var count;

        count = jQuery(tag).attr('data-count');
        count = parseInt(count, 10);
        if( ! count )
        {
            count = 1;
            if('console' in window)
            {
                console.warn("Attribute 'data-count' empty, or not found on "+tag);
            }
        }
        return count;
    }

    // Run once page has finished loading
    jQuery(document).ready( main );

})();

