<!--

/*/-------------------------------------------------------/#/
|| Cross-browser Caret Control Class (Ajax)
|| --------------------
||
|| Copyright © 2008 Stephan Massin. All Rights Reserved.
|| Released under Velegant, LLC. 
|| http://www.velegant.com
|| ...Work in progress....
/#/-------------------------------------------------------/*/

/*/-------------------------------------------------------/#/
|| Notes
|| -----
||
|| Creation:
||	var foo = new CaretControl(bar);
||		- "bar" must be an input or textarea HTML element
||
|| Functions:
||	GetPosition()
||		- gets the current position of the caret relative to
||			the beginning of the text
||	SetPosition(pos)
||		- Sets the position of the caret from relative to the
||			beginning of the text
||	SetSelectionRange(start, end)
||		- Selects text between the "start" and "end"
||	InsertText(str)
||		- Inserts text at the current caret position
||	GetSelection()
||		- Returns the text currently selected
||	SetSelection(str)
||		- Replaces the currently selected text or causes an
||			insertion at the current caret position if no
||			text has been selected
||	GetSelectionStart()
||		- Alias for GetPosition()
||	GetSelectionEnd()
||		- Returns the position of the end of the selected
||			text
||	
/#/-------------------------------------------------------/*/

function CaretControl(input) { this.input = input; }

CaretControl.prototype = {
	GetPosition : function() {
		var pos;
		this.input.focus();	// Must be here. Forces the caret to be visible from the input field
		if(this.input.setSelectionRange)
		{
			pos = this.input.selectionStart;
		}
		else if(document.selection)
		{
			pos = this.input.value.replace(/\r\n/g, "\n").length + 1;
			var range = document.selection.createRange();
			// Appears to be some wacky way to get the location by moving the
			// Caret out of the input's text range and subtract the number of
			// characters it takes to go out of range
			while(range.parentElement() == this.input && range.move("character", 1) == 1 )
				pos--;
		}
		else
			return -1;
		return pos;
	},
	SetPosition : function(pos) {
		return this.SetSelectionRange(pos, pos);
	},
	SetSelectionRange : function(selectionStart, selectionEnd) {
		if (this.input.setSelectionRange) {
			this.input.focus();
			this.input.setSelectionRange(selectionStart, selectionEnd);
		}
		else if(this.input.createTextRange)
		{
			var range = this.input.createTextRange();
			range.collapse(true);
			/*var after = this.input.value.substring(0, selectionEnd + 1).split("\n").length;
			var before = this.input.value.substring(0, selectionStart + 1).split("\n").length;
			range.moveEnd('character', selectionEnd - (after > 1 ? after - 2 : 0 ));
			range.moveStart('character', selectionStart - (before > 1 ? before - 2 : 0 ));*/
			range.moveEnd('character', selectionEnd);
			range.moveStart('character', selectionStart);
			range.select();
		}
		else
			return false;
		return true;
	},
	/*MoveSelection : function(num)
	{
		if (this.input.setSelectionRange) {
			this.input.focus();
			alert(this.GetSelectionStart() +":"+this.GetSelectionEnd())
			this.input.setSelectionRange(this.GetSelectionStart() + num, this.GetSelectionEnd() + num);
		}
		else if(this.input.createTextRange)
		{
			var range = document.selection.createRange();
			range.moveEnd('character', num);
			range.moveStart('character', num);
			range.select();
		}
		else
			return false;
		return true;
	},*/
	InsertText : function(str)
	{
		var pos = this.GetPosition();
		if(pos > -1)
			this.input.value = this.input.value.replace(/\r\n/g, "\n").substring(0, pos) + str + this.input.value.replace(/\r\n/g, "\n").substring(pos);
		else
			return false;
		return this.SetPosition(pos + str.length);
	},
	GetSelection : function() {
		if(this.input.setSelectionRange)
		{
			this.input.focus();
			return this.input.value.substring(this.input.selectionStart, this.input.selectionEnd);
		}
		else if(document.selection)
		{
			var range = document.selection.createRange();
			return range.parentElement() == this.input ? range.text.replace(/\r\n/g, "\n") : '';
		}
		return false;
	},
	SetSelection : function(str) {
		if (this.input.setSelectionRange)
		{
			var pos = this.GetPosition();
			this.input.value = this.input.value.substring(0, this.input.selectionStart) + str + this.input.value.substring(this.input.selectionEnd);
			if(pos > -1)
				this.SetSelectionRange(pos, pos + str.length);
			else
				return false;
		}
		else if (document.selection) {
			var range = document.selection.createRange();
			if (range.parentElement() == this.input) {
				range.text = str;
				range.moveStart('character', -str.length);
				range.select();
			}
			else if(this.InsertText(str))
			{
				var pos = this.GetPosition();
				if(pos > -1)
					this.SetSelectionRange(pos - str.length, pos);
				else
					return false;
			}
		}
		else
			return false;
		return true;
	},
	GetSelectionStart : function() { return this.GetPosition(); },
	GetSelectionEnd : function() {
		var pos = this.GetPosition();
		if(pos > -1)
		{
			if(this.input.setSelectionRange)
			{
				return this.input.selectionEnd;
			}
			else if(document.selection)
			{
				var range = document.selection.createRange();
				return pos + range.parentElement() == this.input ? range.text.replace(/\r\n/g, "\n").length : 0;
			}
		}
		return -1;
	}
}

//-->