﻿/// <reference path="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.1-vsdoc.js" />

/*/  /  /  /  /  /  /  /  /  /  /  /  /  /  /  /  / */
/*  CFTruncate  /  /  /  /  /  /  /  /  /  /  /  / */
/* /  /  /  /  /  /  /  /  /  /  /  /  /  /  /  / */
/*  Use by adding the CFTruncate classname to       */
/*  any block tag or address the tags and pass      */
/*  options in lik in the following samplecode:     */
/*  $('cft').CFTruncate({subjectSelector: 'div'});  */



$(document).ready(function () {
    var v = $('.CFTruncate');
    v.CFTruncate();
});

(function ($) {
    $.fn.CFTruncate = function (options) {
        var element = $(this);

        //Set the default values, use comma to separate the settings, example: 
        var defaults = {
            subjectSelector: null,
            title: true,
            hellip: '…',
            maxItterations: 500
        }
        options = $.extend(defaults, options);

        //  Iterate over the current set of matched elements 
        return element.each(function () {
            var t = $(this);
            var subject = (options.subjectSelector ? t.find(options.subjectSelector) : t);
            var originalHTML = Trim(subject.html());
            var originalText = Trim(subject.text());
            var width = subject.width();
            var height = subject.height();
            var outerHeight = subject.height();
            var innerHeight, blowOver, i;
            subject.wrapInner('<div class="CFTruncateInner" />');
            var inner = subject.children('.CFTruncateInner');
            var lastSpace = 2147483647;

            //  Run loop to shorten the text untilil height of inner element <= hight of surrounding
            for (i = 0; i < options.maxItterations; ++i) {
                innerHeight = inner.height();
                if (inner.height() <= subject.height())
                    break;  //  Height OK! Job done.
                blowOver = innerHeight / outerHeight;
                if (blowOver > 3) {  //  Crude cut to something close to twice the target size
                    var html = inner.html();
                    inner.html(html.substring(0, html.length / blowOver * 2));
                } else {  //  Chop at last space and then clean up html
                    var html = Trim(inner.html());
                    lastSpace = html.lastIndexOf(' ', lastSpace - 1);
                    var newEnding = html.substr(1 + lastSpace);
                    if (IsHtmlBroken(newEnding)) {
                        newEnding = TrimAllExeptTags(newEnding);
                        newEnding = TrimExcessTags(newEnding);
                        var newHtml = html.substr(0, lastSpace) + '…' + newEnding;
                        inner.html(newHtml);
                    }
                }
            }

            //  Add the entire text to title-tag 
            if (options.title)
                subject.attr('title', originalText);
        });

        function Trim(text) {
            text = text.replace(/^\s+|[\s,.!?:;…]+$/g, '')          //  remove beginning space and trailing \s,.!?:;…
            return text.replace(/\s+/g, ' ');                       //  remove multiple space;
        }
        function TrimAllExeptTags(text) {
            return text.replace(/[^\<\>]+(?![^<]*>)/g, '');         //  remove all but tags
        }
        function TrimExcessTags(text) {
            text = text.replace(/<[^\/>][^>]+>$/g, '');             //  remove traling stray tags
            return text.replace(/<([^\/ >]+)[^>]*><\/\1>/g, '');    //  remove empty tags <p></p>
        }
        function IsHtmlBroken(text) {
            return !/^[^<]*>/.test(text);
        }

    };
})(jQuery);

