jQuery.fn.truncate = function(options) {  

    var defaults = {showFullText:false,  // true if you want to show full text on mouseover
                    fullTextBackground: "#aa0", // background color if showFullText popup is done
                    clickExpand: false, // true if you want to expand the text when ellipses clicked
                    clickUrl: null,               // set if ellipses click should go to url
                    ellipses: "..."     // text to add at the end
    };
    
    var opts = $.extend({}, defaults, options);
    
    function removeText(text)
    {    
        var e = text.length-1;
        while(e > 0 && text[e] != ' ' && text[e] != '\n' && text[e] != '\t')
        {
            e--;
        }
        var newtext = text.slice(0,e);
        return newtext;
    }
    function removeEnd(html, keepLast)
    {   
         
        var children = html.childNodes;
        var cnt = children.length;
        var lastIdx = keepLast ? cnt-2 : cnt-1;
        if (lastIdx >=0)
        {
            var last = children[lastIdx]; // leave the last node "..."
            if (last.nodeType == 3 && last.nodeValue.length > 1)
            {
                last.nodeValue = removeText(last.nodeValue);
            }
            else
            {
                removeEnd(last,false);
                if (last.childNodes == null || last.childNodes.length == 0)
                {
                    html.removeChild(last);
                }
            }
            return;
        }
    }
      
    function ellipsesHover(e,full,w)
    {
        if (opts.showFullText)
        {
            full.css("position","absolute");
            full.css("left",(e.clientX-5)+"px");
            full.css("top",(e.clientY-50)+"px");
           // full.css("background-color",opts.fullTextBackground);
            full.css("width",full.parent().width()+"px");
            full.show();
        }
    }      
    function ellipsesClick(e,f,w)
    {
        w.hide();
        f.show();
        f.parent().css("overflow","visible");
        f.parent().height(f.height());
    }      
   return this.each(function() {  
    
        var orig = this.innerHTML;
        //var height = $(this).height();
        var height = 50;
		$(this).wrapInner("<div class='sizer'></div>");
        var wrap = $('.sizer',this);
        
		if (wrap.height() > height) {
        	var origClone = wrap.clone();
            var ellipses;

            if (opts.clickUrl){
                ellipses = jQuery("<a href='"+opts.clickUrl+"' class='ellipses'>"+opts.ellipses+"</a>");
            }
            else{
                ellipses = jQuery("<span class='ellipses'>"+opts.ellipses+"</span>");
            }

            if (opts.showFullText) {
                ellipses.mouseover(function(e){ellipsesHover(e,origClone,wrap);})
                origClone.mouseout(function() { origClone.hide();});
            }

            if (opts.clickExpand) {
                ellipses.click(function(e){ellipsesClick(e,origClone,wrap);})
            }

            wrap.append(ellipses);

            var cnt = 0;
            while(wrap.height() > height && cnt++ < 1000){
                removeEnd(wrap[0],true);
            }
            //var origText = jQuery(orig); //document.createElement("div");
            //origText.innerHTML = orig;
            origClone.hide();
            origClone.addClass('fullText');
            $(this).append(origClone);
        }
   });  
};  


