/***********************************************************************
**                        TextAreaResizer (tar)                       **
**                   - A TEXTAREA resizing script -                   **
************************************************************************
**  Script has changed immensely since original. The resize bar       **
**  attached to the bottom of the TEXTAREA has been improved.         **
**  Now is has rollover effect to give the control a more tactile     **
**  feel. It also has a tooltip with usage instructions. Double-left  **
**  click will maximise the TEXTAREA to fit in all text,              **
**  while right-clicking the bar will maximise the TEXTAREA depending **
**  on the screen height.                                             **
**                                                                    **
**  Apart from the resize bar, there are also four new buttons        **
**  situated on the top corner of the TEXTAREA. These buttons allow   **
**  you to minimise, restore, maximise to screen content height and   **
**  maximise to screen height.                                        **
**                                                                    **
**  All these features are now applied to every TEXTAREA on the page. **
************************************************************************
**  Enhanced by John Ha 2005, 2006 (http://ink.bur.st)                **
************************************************************************
**  Based on TextAreaResizer script by Jason Johnston (jj@lojjic.net) **
**  Created August 2003.  Use freely, but give us credit.             **
***********************************************************************/

function TextAreaResizer(elt) {
	this.element = elt;
	this.create();
}
TextAreaResizer.prototype = {
	minHeight: 16,
	
	create: function() {
		var elt = this.element;
		if (elt.title != 'true') {
			var thisRef = this;

			var div = this.buttons = document.createElement('div');
			div.id = 'control-buttons';
			elt.parentNode.insertBefore(div, elt);

			var l = document.createElement('a');
			l.className = 'textarea-button';
			l.innerHTML = '#';
			l.title = 'Maximise to textarea content height';
			l.onmouseover = function() { this.className = 'textarea-button-hover'; };
			l.onmouseout = function() { this.className = 'textarea-button-normal'; };
			l.onclick = function() { thisRef.max(1); return false; };
			div.appendChild(l);


			var l = document.createElement('a');
			l.className = 'textarea-button';
			l.innerHTML = '+';
			l.title = 'Resize to textarea content height that best-fits window';
			l.onmouseover = function() { this.className = 'textarea-button-hover'; };
			l.onmouseout = function() { this.className = 'textarea-button-normal'; };
			l.onclick = function() { thisRef.max(2); return false; };
			div.appendChild(l);


			var l = document.createElement('a');
			l.className = 'textarea-button';
			l.innerHTML = '=';
			l.title = 'Restore to original textarea height';
			l.onmouseover = function() { this.className = 'textarea-button-hover'; };
			l.onmouseout = function() { this.className = 'textarea-button-normal'; };
			l.onclick = function() { thisRef.max(3); return false; };
			div.appendChild(l);

			var l = document.createElement('a');
			l.className = 'textarea-button';
			l.innerHTML = '-';
			l.title = 'Minimise textarea';
			l.onmouseover = function() { this.className = 'textarea-button-hover'; };
			l.onmouseout = function() { this.className = 'textarea-button-normal'; };
			l.onclick = function() { thisRef.max(4); return false; };
			div.appendChild(l);


			this.handle = document.createElement("hr");
			this.handle.className = 'handle-normal';

			if (typeof(dtt) != 'undefined')
				this.handle.title = '<ul><li>Click & drag to resize</li><li>Double-left-click to maximise</li><li>Right-click best-fit to window</li></ul>';
			else
				this.handle.title = '- Click & drag to resize\n- Double-left-click to maximise\n- Right-click best-fit to window';
			evt.add(this.handle, 'dblclick', function(e){ thisRef.max(1); });
			evt.add(this.handle, 'mousedown', function(e){


/*
// http://www.quirksmode.org/js/improt.html
	var rightclick;
	if (!e) var e = window.event;
	if (e.which) rightclick = (e.which == 3);
	else if (e.button) rightclick = (e.button == 2);
	if (rightclick) {
		if (e.preventDefault && e.stopPropagation) {
			// Mozilla
			e.preventDefault();
			e.stopPropagation();
		} else {
			// IE
			e.cancelBubble = true;
			e.returnValue = false;
		}
	}
*/

					if (e.button == 2) thisRef.max(2);
					else thisRef.dragStart(e);
				});
			var that = this;
			evt.add(this.handle, 'mouseover', function(e){ that.handle.className = 'handle-highlight'; });
			evt.add(this.handle, 'mouseout', this.handleHigh = function(e){ that.handle.className = 'handle-normal'; });
//			evt.add(this.handle, 'contextmenu', function(){ return false; });
			elt.parentNode.insertBefore(this.handle, elt.nextSibling);

			// Does not work if textarea has "display: none"
			// if (detect('ie')) thisRef.init();
			thisRef.init();
		}
	},

	init: function() {
		// Control buttons & handle size and position
		var offsetX = findPosX(this.element) - findPosX(this.handle) + 'px';
		var offsetW = this.element.offsetWidth ? this.element.offsetWidth + 'px' : this.buttons.style.width;
		this.buttons.style.width = offsetW
		this.buttons.style.marginLeft = offsetX;
		this.handle.style.width = offsetW;
		this.handle.style.marginLeft = offsetX;
	},
	
	dragStart: function(e) {
		var thisRef = this;

		// lock cursor shape
		document.getElementsByTagName('body')[0].style.cursor = 'se-resize';

		if (typeof(this.handle.mouseoverHandler) == 'function' &&
			typeof(this.handle.mouseoutHandler) == 'function') {
			// save mouseover handler from dtt
			this.mouseoverHandler = this.handle.mouseoverHandler;

			// disable mouseover for tooltips - tooltips should be "off" while dragging
			evt.remove(this.handle, 'mouseover', this.handle.mouseoverHandler);

			// turn off tooltip
			this.handle.mouseoutHandler();
		}

		// highlight should remain on
		evt.remove(this.handle, 'mouseout', this.handleHigh);

		this.element.style.borderStyle = 'dashed';
		this.dragStartY = e.clientY + 8;
		this.dragStartH = this.element.offsetHeight;

		evt.add(document, 'mousemove', this.dragMoveHdlr = function(e){ thisRef.dragMove(e); });
		evt.add(document, 'mouseup', this.dragStopHdlr = function(e){
				thisRef.dragStop(e);

				// restore default cursor shape
				document.getElementsByTagName('body')[0].style.cursor = 'default';

				// restore mouseover for tooltips after drag stop
				if (typeof(thisRef.mouseoverHandler) == 'function')
					evt.add(thisRef.handle, 'mouseover', thisRef.mouseoverHandler);
		
				// restore highlight handler
				thisRef.handle.className = 'handle-normal';
				evt.add(thisRef.handle, 'mouseout', thisRef.handleHigh = function(e){ thisRef.handle.className = 'handle-normal'; });
			});
	},
	
	dragMove: function(e) {
		var height = this.dragStartH + e.clientY - this.dragStartY;
		this.element.style.height = (height > this.minHeight ? height : this.minHeight) + 'px';
	},
	
	dragStop: function(e) {
		this.element.style.borderStyle = '';
		evt.remove(document, 'mousemove', this.dragMoveHdlr);
		evt.remove(document, 'mouseup', this.dragStopHdlr);
	},

	destroy: function() {
		var elt = this.element;
		elt.parentNode.removeChild(this.handle);
		elt.style.height = '';
	},

	max: function(mode) {
		if (!this.defHeight) this.defHeight = this.element.offsetHeight;
		if (!this.defWidth) this.defWidth = this.handle.offsetWidth;

		this.element.style.height = '1px';

		if (mode == 4) {
			this.element.style.height = this.minHeight + 'px';
			return false;
		}

		if (mode == 3) {
			this.element.style.height = this.defHeight + 'px';
			return false;
		}

		str = '';
		for (i = 0; i < parseInt(this.element.scrollWidth / 10); i++) str += '		';
		this.element.value += str;

		// IE Bug? Need to retrieve scrollWidth first to init it!
		var dummy = this.element.scrollWidth;
		if (this.element.scrollWidth == this.element.clientWidth)
			wrap = 1;
		else
			wrap = 0;
		this.element.value = this.element.value.replace(str,'');


		// IE Bug? Need to retrieve scrollHeight first to init it!
		var dummy = this.element.scrollHeight;
		var maxHeight = this.element.scrollHeight +
			(checkIt('msie') ?
				wrap ?
					-6
				:	-4
			: 	wrap ?
					0
				:	this.element.scrollWidth > this.element.clientWidth ?
						20
					:	0
			);


		if (mode == 2 && maxHeight > winSize()[1]) maxHeight = winSize()[1] - (checkIt('msie') ? 60 : 90);
		// For some reason Netscape won't accept style.height greater than 10000px
		this.element.style.height = maxHeight + (checkIt('msie') ? 2 : 0) + 'px';
/*
		if (checkIt('msie')) {
			this.handle.style.width = this.defWidth - 4 + 'px';
			this.element.style.width = this.defWidth - 20 + 'px';
		}
		scrollTo(0, findPosY(this.element) - (checkIt('msie') ? 60 : 70));
*/
		return false;
	}
};

function findPosX(obj) {
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	} else if (obj.x) curleft += obj.x;
	return curleft;
}

function findPosY(obj) {
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	} else if (obj.y) curtop += obj.y;
	return curtop;
}

function winSize() {
	var myWidth = 0, myHeight = 0;
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		myWidth = window.innerWidth - 16;
		myHeight = window.innerHeight - 16;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth - 20;
		myHeight = document.documentElement.clientHeight - 20;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		myWidth = document.body.clientWidth - 20;
		myHeight = document.body.clientHeight - 20;
	}
	return new Array(myWidth, myHeight);
}

// safari, omniweb, opera, webtv, icab, msie
function checkIt(string) {
	var detect = navigator.userAgent.toLowerCase();
	place = detect.indexOf(string) + 1;
	thestring = string;
	return place;
}

function textarea_init() {
	var textareas = document.getElementsByTagName('textarea');
	for (var i = 0; i < textareas.length; i++) {
		new TextAreaResizer(textareas[i]);
	}
	// Re-init dtt (if available), so tooltips are shown for handles
	if (typeof(dtt) != 'undefined') dtt.scanTags(['hr', 'a']);
}

if (typeof(evt) == 'undefined') {
	var evt = {
		unloadEvents: '',
		domloadEvents: '',
		domloadDone: 0,
	
		init: function() {
			if (!this.unloadEvents) {
				this.unloadEvents = [];
				var that = this;
				this.add(window, 'unload', function() { that.cleanup(that); });
			}
		},
	
		cleanup: function(that) {
			for (var i = 0; i < that.unloadEvents.length; i++)
				with (that.unloadEvents[i])
					that.remove(obj, type, fn, useCapture);
	
			that.unloadEvents = '';
		},
	
		add: function(obj, type, fn, useCapture) {
			if (type == 'domload') {
				this.initDomload();
				this.domloadEvents.push(fn);
				return 1;
			}
	
			this.init();

			if (obj.addEventListener)
				obj.addEventListener(type, fn, useCapture);
			else if (obj.attachEvent)
				obj.attachEvent('on' + type, fn);
			else return 0;
			this.unloadEvents.push({ obj: obj, type: type, fn: fn, useCapture: useCapture });
			return 1;
		},
	
		remove: function(obj, type, fn, useCapture) {
			if (obj.removeEventListener) obj.removeEventListener(type, fn, useCapture);
			else if (obj.detachEvent) obj.detachEvent('on' + type, fn);
			else return 0;
	
			// Event references will all be removed on page unload
			return 1;
		},
	
		src: function(e) {
			e = e || window.event;
			var elm;
			if (e.target)
				elm = e.target.nodeType == 3 ?
						e.target.parentNode
					:	e.target;
			else elm = e.srcElement;
			return elm;
		},
	
		initDomload: function() {
			if (this.domloadEvents) return;
			this.domloadEvents = [];
	
			if (document.addEventListener)
				document.addEventListener('DOMContentLoaded', this.ondomload, 0);
			else if (!document.getElementById('ondomload')) {
				document.write('<script id="ondomload" defer src="javascript:void(0)"></script>');
				document.getElementById("ondomload").onreadystatechange =
					function() {
						if (this.readyState == "complete") {
							evt.ondomload();
						}
					};
				this.add(window,'load', this.ondomload);
			}
		},
	
		ondomload: function() {
			if(evt.domloadDone) return;
			evt.domloadDone = 1;
			
			for (var i = 0; i < evt.domloadEvents.length; i++)
				evt.domloadEvents[i]();
		}
	};
}

evt.add(window, 'domload', textarea_init);

