/*
	Bounce
	Created in February 2008 by Ryan O'Dell
	Version 1.1
	
	Requires
	jquery.js
	jquery-easing.js
	
	CSS for elements that you use along with the class (bounceclass) that is being used to wrap the elements (default: mybounce)
	
	Use this script to make elements of your page include an open/close bar, along with an elasticated bounce effect

	--------------------------------------------------------------------------------------------------------------------------------------------------------
	Version notes
	1.1	- Added the ability to pass jQuery elements to bounceOpen()
		- Restricted bounce() to only apply itself once to any given element
		- Added a few extra error traps and writeConsole()
	--------------------------------------------------------------------------------------------------------------------------------------------------------
	
	Examples
	$('textarea').bounce();	// this would turn all 'textarea' elements on the page in to bouncy text areas
	
	// with config options
	$('textarea').bounce({bottom: false});	// as above, but positioning the bar at the top
	$('textarea').bounce({bottom: false, open: true});	// as above, but all are open to begin with
	$('textarea').bounce({bottom: false}).openBouncer(2);	// as above, except only open number 2 bouncer

	// all config options: min  (size), max  (size), bottom  (boolean), string  (text to click), open  (boolean), bounceclass  (string)
	
	$('textarea').bounceOpen(2);	// opens an individual bouncer
	$('textarea').bounceOpen(1,2,5);	// opens multiple bouncer's
	$('#specifictextarea').bounceOpen();	// opens a specific bounce, using the jQuery passed element list
*/
(function($) {
				// Default config options
				$.fn.bounce = function(sConfig) {
					try {
						var opts = $.fn.bounce.opts;
						// process config
						if (typeof(sConfig) != 'undefined') {
							if (typeof(sConfig.bounceclass) != 'undefined') {opts.bounceclass = sConfig.bounceclass;}
							if (typeof(sConfig.min) != 'undefined') {opts.iMin = sConfig.min;}
							if (typeof(sConfig.max) != 'undefined') {opts.iMax = sConfig.max;}
							if (typeof(sConfig.bottom) != 'undefined') {opts.bBottom = sConfig.bottom;}
							if (typeof(sConfig.string) != 'undefined') {opts.clickstring = sConfig.string;}
							if (typeof(sConfig.open) != 'undefined') {opts.bAllopen = sConfig.open;}
						}
						return this.each(function() {
							// process elements
							var temp_tfx = wrapText(this, opts.bounceclass);
							if (temp_tfx != null) {
								if (!opts.bBottom) {
									temp_tfx.innerHTML = opts.clickstring + temp_tfx.innerHTML;
								} else {
									temp_tfx.innerHTML += opts.clickstring;
								}
								var tfx = {};
								tfx.elem = temp_tfx;
								tfx.elem.running = false;
								tfx.elem.jq = $(temp_tfx);
								tfx.elem.textarea = temp_tfx.childNodes;
								if (tfx.elem.textarea.length) {
									if (!opts.bBottom) {
										tfx.elem.textarea = tfx.elem.textarea[1];
									} else {
										tfx.elem.textarea = tfx.elem.textarea[0];
									}
								} else {
									return false;
								}
								tfx.elem.textarea.jq = $(tfx.elem.textarea);
								tfx.elem.textarea.style.display = 'none';
								tfx.elem.bOpen = false;
								tfx.elem.style.height = opts.iMin + 'px';
								tfx.elem.style.display = 'block';
								tfx.elem.jq.click(BounceEvent);
								tfx.elem.textarea.jq.click(function(ev) {ev.cancelBubble = true; return false;});
								opts.aBouncers.push(tfx.elem);
								if (opts.bAllopen) {
									$.fn.bounceOpen(iTemps+1);
								}
							}
						});
					} catch(e) {
						writeConsole('Error in bounce(): ', e);
					}
				};
				// -----------------------------------------------------------------------------------------------------------
				$.fn.bounce.opts = {
					iMin: 10,
					iMax: 200,
					iDuration: 1500,
					bounceclass: 'mybounce',
					bBottom: true,
					bAllopen: false,
					aBouncers: new Array,
					clickstring: '----',
					aTop: new Array
				};
				// -----------------------------------------------------------------------------------------------------------
				function wrapText(cThis, sClass) {
					try {
						if (!cThis) {
							return false;
						}
						var oParent = cThis.parentNode;
						if (oParent) {
							if (typeof(oParent.bOpen) != 'undefined') {
								return null;
							}
						}
						var oWrap = document.createElement('div');
						if (typeof(sClass) != 'undefined') {
							oWrap.className = sClass;
						}
						oWrap.appendChild(cThis.cloneNode(true));
						oParent.insertBefore(oWrap, cThis);
						oParent.removeChild(cThis);
						cThis = oWrap;
						oWrap = null;
						oParent = null;
					} catch(e) {
						writeConsole('Error in wrapText(): ', e);
					}
					return cThis;
				};
				// -----------------------------------------------------------------------------------------------------------
				function BounceEvent() {
					var opts = $.fn.bounce.opts;
					if (this.running) {
						return false;
					}
					if (this.bOpen) {
						this.bOpen = false;
						$(this).height(opts.iMin);
						this.textarea.style.display = 'none';
						this.running = false;
					} else {
						this.running = true;
						this.bOpen = true;
						this.textarea.style.display = 'block';
						var keep_this = this;
						$(this).animate({height:opts.iMax}, {duration: opts.iDuration, easing: 'easeOutElastic'});
						window.setTimeout(function() { keep_this.running = false; }, 1500);
					}
				};
				// -----------------------------------------------------------------------------------------------------------
				$.fn.bounceOpen = function(){
					try {
						var opts = $.fn.bounce.opts;
						if (arguments.length > 1) {
						for (var iTemps=0; iTemps<arguments.length; iTemps++) {
							var iBouncer = arguments[iTemps];
							if ((iBouncer > 0) && (iBouncer <= opts.aBouncers.length)) {
								var oThis = opts.aBouncers[iBouncer-1];
								if (!oThis.bOpen) {
									oThis.textarea.style.display = 'block';
									oThis.bOpen = true;
									$(oThis).height(opts.iMax);
								}
								oThis = null;
							}
						}
							if (this) {
								return this;
							}
						} else {
							return this.each(function() {
								var oThis = this.parentNode;
								if (oThis) {
									if (typeof(oThis.bOpen) != 'undefined') {
										if (!oThis.bOpen) {
											oThis.textarea.style.display = 'block';
											oThis.bOpen = true;
											$(oThis).height(opts.iMax);
										}
									}
								}
								oThis = null;
							});
						}
					} catch(e) {
						writeConsole('Error in bounceOpen(): ', e);
					}
				};
				// -----------------------------------------------------------------------------------------------------------
				function writeConsole(sText, e) {
					if (typeof(sText) != 'undefined') {
						var bConsole = false;
						if (typeof(console) != 'undefined') {
							if (typeof(console.log) != 'undefined') {
								bConsole = true;
							}
						}
						if (bConsole) {
							var oLog = console.log;
						} else {
							var oLog = alert;
						}
						var sErrorOutput = '';
						if (typeof(e) != 'undefined') {
							if (typeof(e.message) != 'undefined') {
								sErrorOutput = e.message;
							}
						}
						oLog(sText + sErrorOutput);
					}
				};
})(jQuery);
			// -----------------------------------------------------------------------------------------------------------
