 function fcode(el,do_focus) { // where el is a textarea

	if (!do_focus) {
		var do_focus = 0;
	}

// soup-up the text area
var t = el;
	$(t).attr('wrap','off');
 t.last_range = [0,0];
 t.is_focused = 0;
t.getVal = function() {
	return this.happy_newlines(this.value);
}
t.setVal = function(str) {
	this.value = str;
}
t.getRange = function() {
	var pos = 0;
	var _end = 0;
	if (document.selection) { // IE Support
		var range = document.selection.createRange();
		var stored_range = range.duplicate();
		stored_range.moveToElementText( this );
		stored_range.setEndPoint( 'EndToEnd', range );
		pos = this.happy_newlines(stored_range.text).length - this.happy_newlines(range.text).length;
		_end = pos + this.happy_newlines(range.text).length;
	}
	else if (this.selectionStart || this.selectionStart == '0') { // Firefox support
		pos = this.selectionStart;
		_end = this.selectionEnd;
	}
	var _arr = [pos,_end];
	this.last_range = _arr;
	return _arr;
}
t.setRange = function(selectionStart, selectionEnd) {
	if (typeof selectionStart == 'undefined') {
		var selectionStart = this.last_range[0];
		var selectionEnd = this.last_range[1];
	}
	else if (typeof selectionEnd == 'undefined') {
		var selectionEnd = selectionStart; 
	}
	if (this.setSelectionRange) {
		this.focus();
		this.setSelectionRange(selectionStart, selectionEnd);
	}
	else if (this.createTextRange) {
		var range = this.createTextRange();
		range.collapse(true);
		range.moveEnd('character', selectionEnd);
		range.moveStart('character', selectionStart);
		range.select();
	}
}
t.getScroll = function() {
	var _arr = [this.scrollLeft,this.scrollTop];
	this.last_scroll = _arr;
	return _arr;
}
t.setScroll = function(x,y) {
	if (typeof x == 'undefined' || typeof y == 'undefined') {
		var x = this.last_scroll[0];
		var y = this.last_scroll[1];
	}
	this.scrollLeft = x;
	this.scrollTop = y;
	var _arr = [x,y];
	this.last_scroll = _arr;
	return _arr;
}
$(t).blur(function() {
	this.is_focused = 0;
	try {
		this.last_range = this.getRange();
	} catch(err) { this.last_range = [0,0]; }
});
$(t).focus(function() {
	this.is_focused = 1;
});


$(t).keydown(function(e) {
	if (e.keyCode == 9) { // tab key
		if (e.ctrlKey) { return false; } // control tab is supposed to be a browser move!
		var _r = this.getRange();
		 var a = _r[0];
		 var b = _r[1];
		var _s = this.getScroll();
		 var x = _s[0];
		 var y = _s[1];
		var v = this.getVal()
		if (a == b) { // insert tab char
			var _pre = v.substring(0,a);
			var _post = v.substring(a);
			if (BROWSER_TYPE == 'IE') {
				var _first_post_char = _post.substr(0,1);
				if (_first_post_char == '\n') {
					this.setVal(_pre + '\n\t' + _post.substring(1));
					this.setRange(a+2);
				}
				else {
					this.setVal(_pre + '\t' + _post);
					this.setRange(a+1);
				}
			}
			else {
				this.setVal(_pre + '\t' + _post);
				this.setRange(a+1);
			}
		}
		else { // indent/outdent code
			var _a = v.lastIndexOf('\n',a);
			 if (_a == -1) { var _a = 0; }
			var _b = v.indexOf('\n',b);
			 if (_b == -1) { var _b = this.getVal().length; }
			var _pre = v.substring(0,_a);
			var _mid = v.substring(_a,_b);
			var _post = v.substring(_b);
			if (e.shiftKey) { // outdent
				var _mid = _mid.replace(/\n( {1,7}|\t)/g,'\n');
				  if (_a == 0) { var _mid = _mid.replace(/^( {1,7}|\t)/g,''); }
				this.setVal(_pre + _mid + _post);
			}
			else { // indent
				var _mid = _mid.replace(/\n/g,'\n\t');
				  if (_a == 0) { var _mid = '\t' + _mid; }
				this.setVal(_pre + _mid + _post);
			}
			this.setRange(_a,_a+_mid.length);
		}
		this.setScroll(x,y);
		return false;
	}
	else if (e.keyCode == 13) { // enter
		var _r = this.getRange();
		 var a = _r[0];
		 var b = _r[1];
		var _s = this.getScroll();
		 var x = _s[0];
		 var y = _s[1];
		var v = this.getVal()
		var _pre = v.substring(0,a);
		var _post = v.substring(a);
		var _last_nl = _pre.lastIndexOf('\n',a);
		 if (_last_nl == -1) { var _last_nl = 0; }
		var _line = v.substring(_last_nl,a);
		if (_last_nl == 0) {
			var _spaces = _line.match(/^([ \t]+)/);
		}
		else {
			var _spaces = _line.replace('\n','').match(/^([ \t]+)/);
		}
		if (_spaces) {
			var _txt = _spaces[0];
			if (BROWSER_TYPE == 'IE') {
				var _first_post_char = _post.substr(0,1);
				if (_first_post_char == '\n') {
					this.setVal(_pre + '\n\r' + _txt + _post.substring(1));
					this.setRange(a+_txt.length+1);
				}
				else {
					this.setVal(_pre + '\n\r' + _txt + _post);
					this.setRange(a+_txt.length+1);
				}
			}
			else {
				this.setVal(_pre + '\n' + _txt + _post);
				this.setRange(a+_txt.length+1);
			}
			this.setScroll(x,y+16);
			return false;
		}
	}
});
$(t).keyup(function(e) {
	if (e.keyCode == 9) { // tab key
		return false;
	}
	else if (e.keyCode == 13) { // enter
		return false;
	}
});

t.happy_newlines = function(str) {
	return str.replace(/(\r\n|\r|\n)/g,'\n');
}

if (do_focus == 1) {
	el.focus();
}

} 
