String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}

function fitTextOnOneLine(textElementId, numberOfLines) {
	var oneLiner = document.getElementById(textElementId);
	var baseText = oneLiner.innerHTML;
	var originalHeight = oneLiner.offsetHeight;
	oneLiner.innerHTML = "!";
	var baseHeight = oneLiner.offsetHeight;
	oneLiner.innerHTML = baseText;

	if (numberOfLines == null) {
		numberOfLines = 1;
	}

	if (originalHeight != baseHeight) {
		var originalText = baseText.trim();

		var closingDirectives = new Array();
		var choppedText;
		var choppedHeight;
		var previousChoppedText = "";
		var inDirective = false;
		var inCloseDirective = false;
		var removeClosingDirective = false;
		var openDirectiveIndex = -1;
		var closeDirectiveIndex = -1;
		var endDirectiveIndex = -1;
		var currentLine = 0;
		var currentIndex;
		var currentChar;

		for (currentIndex = 0; currentIndex < originalText.length; ++currentIndex) {
			currentChar = originalText.charAt(currentIndex);
			if (!inDirective && currentChar == " ") {
				choppedText = originalText.substring(0, currentIndex);
				for (var removeIndex = closingDirectives.length - 1; removeIndex >= 0; --removeIndex) {
					choppedText = choppedText + closingDirectives[removeIndex];
				}
				oneLiner.innerHTML = choppedText;
				choppedHeight = oneLiner.offsetHeight;
				if (choppedHeight != baseHeight) {
					++currentLine;
					if (currentLine == numberOfLines) {
						oneLiner.innerHTML = previousChoppedText;
						break;
					}
					else {
						baseHeight = oneLiner.offsetHeight;
						oneLiner.innerHTML = baseText;
						previousChoppedText = choppedText;
					}
				}
				else {
					oneLiner.innerHTML = baseText;
					previousChoppedText = choppedText;
				}
			}
			else if (!inDirective && currentChar == "<") {
				openDirectiveIndex = currentIndex;
				endDirectiveIndex = -1;
				closeDirectiveIndex = -1;
				inDirective = true;
				inCloseDirective = false;
				removeClosingDirective = false;
			}
			else if (inDirective && currentChar == "/") {
				closeDirectiveIndex = currentIndex;
				if (endDirectiveIndex == openDirectiveIndex + 1) {
					inCloseDirective = true;
					removeClosingDirective = true;
				}
			}
			else if (inDirective && currentChar == ">") {
				inDirective = false;
				endDirectiveIndex = currentIndex;
				if (!inCloseDirective && closeDirectiveIndex == endDirectiveIndex - 1) {
					inCloseDirective = true;
				}

				var theDirective = "</" +
					originalText.substring(openDirectiveIndex + 1, endDirectiveIndex + 1);
				var closeSpaceIndex = theDirective.indexOf(" ");
				if (closeSpaceIndex > -1) {
					theDirective = theDirective.substring(0, closeSpaceIndex) + ">";
				}

				if (!inCloseDirective) {
					closingDirectives[closingDirectives.length] = theDirective;
				}
				else if (removeClosingDirective) {
					var newClosingDirectives = new Array();
					var newRemoveIndex = 0;
					for (var removeIndex = 0; removeIndex < closingDirectives.length; ++removeIndex) {
						if (closingDirectives[removeIndex] != theDirective) {
							newClosingDirectives[newRemoveIndex++] =
								closingDirectives[removeIndex];
						}
					}
				}
			}
		}
	}
}