/*!
* jQuery slabtext plugin v1
*
* Copyright 2011, Brian McAllister
* Website: http://www.frequency-decoder.com
* 
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function( $ ){   

        $.fn.slabText = function(options) {
        
                var settings = {
                        // The ratio used when calculating the characters per line (parent width / (font-size * fontRatio))
                        // You may wish to tweak this to suit your choosen font
                        "fontRatio"             : 0.78,
                        // Always recalculate the characters per line, not just when the font-size changes?
                        // Defaults to true (CPU intensive)
                        "forceNewCharCount"     : true,
                        // Do we wrap ampersands in <span class="amp"> ?
                        "wrapAmpersand"         : true
                };
                
                return this.each(function(){
                   
                        // Extend options if necessary
                        if(options) { 
                                $.extend(settings, options);
                        };
                        
                        var $this               = $(this),                              // Cache a reference to the parent container
                            words               = String($this.text()).split(" "),      // Cache the word list                              
                            origFontSize        = null,                                 // parent containers font-size
                            idealCharPerLine    = null,                                 // the # chars per line
                            fontRatio           = settings.fontRatio,                   
                            forceNewCharCount   = settings.forceNewCharCount,
                            resizeThrottle      = null;                                   
                                                                   
                        // Most of this function is a (very) stripped down AS3 to JS port of the slabtype
                        // algorithm by Eric Loyer with the original comments left intact
                        // http://erikloyer.com/index.php/blog/the_slabtype_algorithm_part_1_background/                         
                        var resizeSlabs = function resizeSlabs() {
                                // Cache the parent containers width       
                                var parentWidth = $this.width();
                                 
                                // If the parent containers font-size has changed or the "forceNewCharCount" option is true (the default),
                                // then recalculate the "characters per line" count and rerender the inner spans
                                // Setting "forceNewCharCount" to false will save CPU cycles...                                                                                           
                                if(forceNewCharCount || parseFloat($this.css('font-size')) != origFontSize) {
                                        
                                        origFontSize = parseFloat($this.css('font-size'));                                        
                                        
                                        var newCharPerLine      = Math.min(60, Math.floor(parentWidth / (origFontSize * fontRatio))),
                                            wordIndex           = 0,
                                            lineText            = [],
                                            counter             = 0,                                                                        
                                            preText             = "",
                                            postText            = "",
                                            finalText           = "",
                                            preDiff,
                                            postDiff;
                                
                                        if(newCharPerLine != idealCharPerLine) {
                                                idealCharPerLine = newCharPerLine;
                                                                                        
                                                while (wordIndex < words.length) {
                                               
                                                        postText = "";
                            
                                                        // build two strings (preText and postText) word by word, with one
                                                        // string always one word behind the other, until
                                                        // the length of one string is less than the ideal number of characters
                                                        // per line, while the length of the other is greater than that ideal
                                                        while (postText.length < idealCharPerLine) {
                                                                preText   = postText;
                                                                postText += words[wordIndex] + " ";
                                                                if(++wordIndex >= words.length) {
                                                                        break;
                                                                };
                                                        };
                            
                                                        // calculate the character difference between the two strings and the
                                                        // ideal number of characters per line
                                                        preDiff  = idealCharPerLine - preText.length;
                                                        postDiff = postText.length - idealCharPerLine;
                            
                                                        // if the smaller string is closer to the length of the ideal than
                                                        // the longer string, and doesnâ€™t contain just a single space, then
                                                        // use that one for the line
                                                        if((preDiff < postDiff) && (preText.length > 2)) {
                                                                finalText = preText;
                                                                wordIndex--;              
                                                        // otherwise, use the longer string for the line
                                                        } else {
                                                                finalText = postText;
                                                        };
                            
                                                        lineText.push('<span class="slabtext">' + (settings.wrapAmpersand ? finalText.substr(0, finalText.length-1).replace("&", '<span class="amp">&amp;</span>') : finalText.substr(0, finalText.length-1)) + "</span>");
                                                };
                                                
                                                $this.html(lineText.join(""));
                                        };        
                                };
                                                                     
                                // Loop through the spans changing font-size accordingly
                                $("span.slabtext", $this).each(function() {                               
                                        var ratio    = parentWidth / $(this).width(),
                                            fontSize = parseFloat($(this).css('font-size')) || origFontSize;
                                               
                                        $(this).css('font-size', Math.floor(fontSize * ratio));               
                                });
                        };
           
                        resizeSlabs();
               
                        // Call on resize. Opera debounces their resize by default.
                        $(window).resize(function() {
                                clearTimeout(resizeThrottle);                                
                                resizeThrottle = setTimeout(resizeSlabs, 500);
                        });         
                });
    };
})( jQuery );
