/*
 * trunc_elements.class.js
 */

/*
 * TruncElements
 * Duo Consulting
 * http://www.duoconsulting.com
 */
var TruncElements = function(elems, words, moreLinkText, lessLinkText, moreLinkClass, lessLinkClass) {
	this.elems = elems;
	this.truncElems = new Array();
	for (var i=0; i<elems.length; i++) {
		this.truncElems.push(new ExpandedText(this.elems[i], words, moreLinkText, lessLinkText, moreLinkClass, lessLinkClass));
	}
}

/*
 * ExpandedText
 * Duo Consulting
 * http://www.duoconsulting.com
 */
var ExpandedText = function(elem, words, moreLinkText, lessLinkText, moreLinkClass, lessLinkClass) {
	this.containerElem = elem;
	this.textElem = null;
	this.linkElem = null;
	this.words = words;
	this.moreLinkText = moreLinkText;
	this.lessLinkText = lessLinkText;
	this.moreLinkClass = moreLinkClass;
	this.lessLinkClass = lessLinkClass;
	this.expanded = false;

	// Init constructor
	this.init = function() {
		this.fullText = elem.innerHTML;
		if (this.truncText = this.truncateWords(this.fullText,this.words)) {
			this.containerElem.innerHTML = "<span></span>&nbsp; <br /><a href='#'></a>"
			this.textElem = this.containerElem.firstChild;
			this.linkElem = this.containerElem.lastChild;
			this.attachLinkBehavior();
			this.showLess();
		}
	}	

	// Utility method to truncate a string to a specific number of words
	/* This can be pulled out to a general utility function with reuse.
	   If the string contains fewer words than are called for, the method
		 will return a value of false. */
	this.truncateWords = function(str,words) {
		var output = "";
		var reWordSep = new RegExp("[\\s\\n]", "im");
		var arrWords = str.split(reWordSep);
		if (arrWords.length > words) {
			var reOutputEnd = new RegExp("(\\s*&\\S+?;)?\\W*$", "im");
			output = arrWords.slice(0,words).join(" ");
			output = output.replace(reOutputEnd, "...");
		} else {
			return false;
		}
		return output;
	}

	// Attaches toggle function to link elements
	this.attachLinkBehavior = function() {
		var self = this;
		this.linkElem.onclick = function() { self.toggleText();return false; }
	}

	// Toggle method is called by links
	this.toggleText = function() {
		if (this.expanded) {
			this.showLess();
		} else {
			this.showMore();
		}
	}
	
	this.showLess = function() {
		this.textElem.innerHTML = this.truncText;
		this.linkElem.innerHTML = this.moreLinkText;
		this.linkElem.className = this.moreLinkClass;
		this.expanded = false;
	}

	this.showMore = function() {
		this.textElem.innerHTML = this.fullText;
		this.linkElem.innerHTML = this.lessLinkText;
		this.linkElem.className = this.lessLinkClass;
		this.expanded = true;
	}

	// Call init method as the constructor
	this.init();
}
