/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-12-20 08:43:48 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4257 $
 *
 * Version: 1.2
 *
 * Requires: jQuery 1.2+
 */
(function($){$.dimensions={version:'1.2'};$.each(['Height','Width'],function(i,name){$.fn['inner'+name]=function(){if(!this[0])return;var torl=name=='Height'?'Top':'Left',borr=name=='Height'?'Bottom':'Right';return this.is(':visible')?this[0]['client'+name]:num(this,name.toLowerCase())+num(this,'padding'+torl)+num(this,'padding'+borr);};$.fn['outer'+name]=function(options){if(!this[0])return;var torl=name=='Height'?'Top':'Left',borr=name=='Height'?'Bottom':'Right';options=$.extend({margin:false},options||{});var val=this.is(':visible')?this[0]['offset'+name]:num(this,name.toLowerCase())+num(this,'border'+torl+'Width')+num(this,'border'+borr+'Width')+num(this,'padding'+torl)+num(this,'padding'+borr);return val+(options.margin?(num(this,'margin'+torl)+num(this,'margin'+borr)):0);};});$.each(['Left','Top'],function(i,name){$.fn['scroll'+name]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(name=='Left'?val:$(window)['scrollLeft'](),name=='Top'?val:$(window)['scrollTop']()):this['scroll'+name]=val;}):this[0]==window||this[0]==document?self[(name=='Left'?'pageXOffset':'pageYOffset')]||$.boxModel&&document.documentElement['scroll'+name]||document.body['scroll'+name]:this[0]['scroll'+name];};});$.fn.extend({position:function(){var left=0,top=0,elem=this[0],offset,parentOffset,offsetParent,results;if(elem){offsetParent=this.offsetParent();offset=this.offset();parentOffset=offsetParent.offset();offset.top-=num(elem,'marginTop');offset.left-=num(elem,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&$.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return $(offsetParent);}});function num(el,prop){return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;};})(jQuery);


// add a trim function for strings
String.prototype.trim = function ()
{
	return this.replace(/^\s*?|\s*?$/gim, '');
}

// the summary class
var _summary = {
	// target word length for the summarized text
	target_length : 80,

	// the string to tack on to truncated text
	ellipsis      : '&#8230;',

	// tweak these if debugging is necessary, otherwise, don't touch
	//tokenizer  : /(<[^>]+>)|([^ \r\n<]+)/g,  //match every xhtml tag (gim = global/case insensetive)
	tokenizer  : /\s*([^ \r\n<]+)|(<[^>]+?>)/g,
	stop_token : /[\,\.\!\)\;\:\-\&\?]/, //match all punctation
	comments   : /<\!\-+[\s\S]*?\-+>/gm,

	// internal stack of html tags
	stack : [],

	// vars to store long vs short content
	original_content : '',
	short_content    : '',

	// keeps track of the toggle phase
	phase : 'short',

	// trackers for the height for animating smoothly
	long_height  : 0,
	short_height : 0,

	// animation options
	duration : 300,
	easing   : 'linear',

	// switches the element's html between long and short content
	toggle : function (e)
	{
		
		// swap it to go long
		if (this.phase == 'short') {
			this.phase = 'long';
			e.html(this.original_content);
		}

		// reel it in to be short
		else {
			
			this.phase = 'short';			
			e.html(this.short_content);
			
		}
	},

	// start up the wizard
	// outer is the selector for grabbing the heights for animation
	// selector is the selector for the swappable content
	// _more is the selector for the toggling read more/less link
	init : function (_outer, _selector, _more) { /*'#promo-text', '#promo-text-inner', '#toggle-text'*/
		if (!$(_selector)) return false;		

		// reduce code comments
		$(_selector).html($(_selector).html().replace(this.comments, ''));

		// set original vars
		this.long_height      = $(_outer).outerHeight({ margin: true });
		this.original_content = $(_selector).html();

		// break apart the content into countable tokens
		var tokens     = this.original_content.match(this.tokenizer);
		var word_count = 0;
		var ret_str    = '';

		// if it's too short, don't bother, and take away the more link
		var c = 0;
		for (var i = 0; i < tokens.length; i++) {
			// don't match empty tokens or html tags
			var tt = tokens[i].trim();
			if (tt != '' && tt.substring(0, 1) != '<') c++;
		}
		
		if (c <= this.target_length) {
			$(_more).hide();

			return false;
		}
		
		
		// iterate over tokens
		for (var i = 0; i < tokens.length; i++) {
			var token = tokens[i].trim();

			if (!token.length) continue;

			// if we've hit the max, break out
			if (word_count >= this.target_length) {
				break;
			}

			// if it's a closing tag, take it out of the stack
			if (token.substring(0, 2) == '</') {
				this.stack.pop();
			}
			// if it's an opening tag, add it to the stack
			else if (token.substring(0, 1) == '<') {
				this.stack.push(token);
				
			}
			// if it's not html or an attribute, add to the word count
			else if (!token.match(/href=|title=/)) {
				word_count++;
			}

			// add the token to the return string
			ret_str += token + ' ';
		}

		// attempt to make the last token pretty if it contains punctuation
		// don't want to do something like "however,..."
		if (ret_str.substr(ret_str.length - 2, 1).match(this.stop_token) != null) {
			ret_str = ret_str.substr(0, ret_str.length - 2);
		}

		// add on the ellipsis
		ret_str += this.ellipsis;
		

		// go through the html tags still on the stack
		// and add them to the return string as closing tags

		/*for (var s = 0; s < this.stack.length; s++) {
			var soken = this.stack[s].trim();

			if (soken.substring(0, 2) != '</') {				
				ret_str += '</' + soken.substring(1);
				alert(ret_str);
				
			}
		}*/
		
		for (var s = this.stack.length -1; s >= 0; s --) {
			var soken = this.stack[s].trim();

			if (soken.substring(0, 2) != '</') {				
				ret_str += '</' + soken.substring(1);				
				
			}
		}

		//ret_str +='</DIV></LI></UL></BR>';

		// populate our new condensed values and heights
		//alert(ret_str);
		//ret_str="<b>Test</b>";
		//ret_str="<P> Combine two powerful forms of business intelligence (BI) to achieve 'pervasive'.&nbsp;</P><BR> <UL><LI><DIV><strong> Strageic: </STRONG>&nbsp; Back - use inventory, products and </DIV></LI></UL></BR>";
		this.short_content = ret_str;
		
		$(_selector).html(ret_str);
		
		
		this.short_height = $(_outer).outerHeight({ margin: true })
	}
};


$(document).ready(function () {

	// summarize promo text to 90 words
	_summary.target_length = 89;
	_summary.init('#promo-text', '#promo-text-inner', '#toggle-text');
	$('#promo-text').css('height', ((!_summary.short_height) ? _summary.long_height : _summary.short_height));
	
	// the toggle link
	$('#toggle-text').click(function () {
		if (_summary.phase == 'short') {
			_summary.toggle($('#promo-text-inner'));
			$('#promo-text').animate({height: _summary.long_height}, _summary.duration, _summary.easing, function () {
				$('#toggle-text').text('Less');
			});
		}
		else {
			$('#promo-text').animate({height: _summary.short_height}, _summary.duration, _summary.easing, function () {
				_summary.toggle($('#promo-text-inner'));
				$('#toggle-text').text('More');
			});
		}
	});
	
	//add a hidden div for the printed page
	$('#promo-text-inner').after('<div id="promo-text-inner-print" style="display:none;">' + _summary.original_content + '</div>');

});
