﻿(function() {
	Hover = function(t, txt) {
		this.t = $(t);
		this.hideHover = function() {
			this.hvr.hide();
			this.t.css('position', 'static');
		};
		this.hvr = $('<div>' + txt + '</div>')
            .addClass('abridged-hover')
            .css({ 'position': 'absolute', 'z-index': '20' })
            .hide()
            .mouseout(Function.createDelegate(this, this.hideHover));
		this.t
            .before(this.hvr)
            .mouseover(Function.createDelegate(this, function() {
            	this.t.css('position', 'static');
            	this.hvr.show();
            }));
	}

	StringAbridger = function(items, o) {
		var defaults = {
			ellipsis: '(...)'
		};
		this.opt = $.extend({}, defaults, o || {});
		this.STOP_CHARS = ['(', '"'];
		this.CLOSE_CHARS = new Array();
		this.CLOSE_CHARS['('] = ')';
		this.CLOSE_CHARS['"'] = '"';
		this.cleanReg = /( )+/g;
		this.lineFeed = /\n/g;
		this.quot = /\"/g;

		if (!$.isArray(items)) {
			return;
		}
		var md = $('div#strMes:first');
		if (md.size() == 0) {
			md = $('<div id="strMes"></div>').css({ 'position': 'absolute', 'left': '-25000px' });
			$('body').prepend(md);
		}
		this.measureDiv = md;
		var j;
		for (j in items) {
			this.suffix = null;
			this.abridgeString(items[j]);
		}
	}
	$.extend(StringAbridger.prototype, {
		abridgeString: function(i) {
			if (typeof (i) == 'undefined'
                || typeof (i.id) == 'undefined'
                || typeof (i.width) == 'undefined') {
				return;
			}
			this.ellipsis = (typeof (i.ellipsis) == 'undefined' ? this.opt.ellipsis : i.ellipsis);
			this.node = $('#' + i.id + ':first');
			if (this.node.size() == 0) {
				return;
			}
			var lbl = this.node.clone().removeAttr('id');
			this.measureDiv.empty().append(lbl);
			this.lbl = lbl;
			this.text = lbl.html()
							.replace(this.cleanReg, ' ')
							//.replace(this.lineFeed, "<br />")
							.replace(this.quot, "&quot;");

			var words = this.text.split(' ');
			if (typeof (i.preserveLast) != 'undefined' && i.preserveLast > 0) {
				this.suffix = this.wrapSuffix(words.slice(words.length - i.preserveLast, words.length).join(' '));
				words.splice(words.length - i.preserveLast, i.preserveLast);
			}
			if (lbl.width() <= i.width) {
				this.node.html(words.join(' ') + ' ').append(this.suffix);
				return;
			}
			var word = '', abr = '';
			while (word = words.shift()) {
				var ch1 = word.substr(0, 1);
				if ($.inArray(ch1, this.STOP_CHARS) != -1 && (abr + word).length == lbl.length) {
					var procRes = this.processStopChar(ch1, $.merge(new Array(word), words), abr, i.width);
					if (!procRes.cont) {
						return;
					}
					abr = procRes.abr;
					continue;
				}
				if (this.strIsShorter(abr + word, i.width) == false) {
					break;
				}
				abr += word + ' ';
			}
			this.setAbridgedText(abr);
		},
		wrapSuffix: function(s) {
			return $('<span class="abridged-suffix">' + s + '</span>');
		},
		processStopChar: function(sCh, words, base, width) {
			var abr = base;
			var cCh = this.CLOSE_CHARS[sCh];
			while (word = words.shift()) {
				abr += word + ' ';
				if (word.substr(word.length - 1, 1) == cCh) {
					break;
				}
			}
			var isShorter = this.strIsShorter(abr, width);
			if (!isShorter) {
				this.setAbridgedText(base + ' ');
			}
			return { cont: isShorter, abr: abr };
		},
		setAbridgedText: function(txt) {
			this.node.html(txt).append('<span class="ellipsis">' + this.ellipsis + '</span>');
			if (this.suffix != null) {
				this.node.text(this.node.text() + ' ').append(this.suffix);
			}
			this.createHover();
		},
		strIsShorter: function(str, maxWidth) {
			this.lbl.html(str).append('<span class="ellipsis">' + this.ellipsis + '</span>');
			if (this.suffix != null) {
				this.lbl.html(this.lbl.text() + ' ').append(this.suffix);
			}
			return (this.lbl.width() <= maxWidth);
		},
		createHover: function() {
			new Hover(this.node, this.text);
		}
	});
})();