/* Dan Rouw : RichTextEditor_1.0.0.js : 6/16/09 3:30 PM */

/*
public interface RichTextEditor(
	private editorWindow:Object;
	private selectedRange:Object;
	
	public getSelectedRange():Object;
	public insertAroundCursor(tag:string,defaultText:string):void;
	public insertAtCursor(text:string):void;
	public registerEditorEvents():void;
	public selectText(text:string):void;
)
*/

var RichTextEditor = new Class({
	initialize: function(){
		this.editorWindow = ($type(arguments[0].editorWindow) == "string") ? $(arguments[0].editorWindow) : arguments[0].editorWindow;
		this.selectedRange = this.editorWindow.getSelectedRange();
		this.registerEditorEvents();
	}
}).implement({
	getSelectedRange: function(){
		return this.selectedRange;
	},
	setSelectedRange: function(){
		this.selectedRange = this.editorWindow.getSelectedRange();
	},
	insertAroundCursor: function(tag,defaultText){
		// SAVE THE CURRENT SCROLL POSITION
		var windowScroll = this.editorWindow.getScroll();
		
		// MAKE SURE THE SELECTED RANGE IS SET. THIS IS MOSTLY FOR IE
		this.editorWindow.selectRange(this.selectedRange.start,this.selectedRange.end);
		
		// USE INSERTAROUNDCURSOR TO WRAP THE TAG AROUND THE SELECTED TEXT
		this.editorWindow.insertAroundCursor({
			before: '<' + tag + '>'
			,after: '</' + tag + '>'
			,defaultMiddle: defaultText
		});
		
		// RESET THE SCROLL POSITION, OTHERWISE THE WINDOW SCROLL CAN BE UNPREDICTABLE
		this.editorWindow.scrollTo(windowScroll.x,windowScroll.y);
		
		// UPDATE THE SELECTED RANGE SINCE WE JUST ADDED NEW TEXT
		this.selectedRange = this.editorWindow.getSelectedRange();
	},
	insertAtCursor: function(text){
		// SAVE THE CURRENT SCROLL POSITION
		var windowScroll = this.editorWindow.getScroll();
		
		// MAKE SURE THE SELECTED RANGE IS SET. THIS IS MOSTLY FOR IE
		this.editorWindow.selectRange(this.selectedRange.start,this.selectedRange.end);
		
		// INSERT THE TEXT AT THE CURSOR, BUT DON'T SELECT THE TEXT AFTERWARDS
		this.editorWindow.insertAtCursor(text,false);
		
		// UPDATE THE SELECTED RANGE SINCE WE JUST ADDED NEW TEXT
		this.editorWindow.scrollTo(windowScroll.x,windowScroll.y);
	},
	registerEditorEvents: function(){
		// IN THE EVENTS BELOW, YOU MUST USE THE BIND(THIS) IN ORDER FOR THE EVENT TO USE THIS TO
		// REFER TO THE CLASS INSTEAD OF THE DOM ELEMENT (the editor window)
		// FOR SOME REASON ONBLUR DOESN'T UPDATE THE SELECTED RANGE PROPERLY, SO WE HAVE TO USE ONKEYUP AND ONMOUSEOUT
		this.editorWindow.addEvents({
			'keyup': function(){
				this.setSelectedRange();
			}.bind(this),
			'mouseout': function(){
				this.setSelectedRange();
			}.bind(this)
		});
	},
	selectText: function(text){
		// SEARCH THE VALUE OF THE EDITORWINDOW FOR THE PASSED IN TEXT
		var text_pos = this.editorWindow.get('value').indexOf(text);
		
		// IF WE FOUND A MATCH, SELECT THE TEXT
		if(text_pos >= 0){
			this.editorWindow.setCaretPosition(text_pos);
			this.editorWindow.fireEvent('keyup');
			this.editorWindow.selectRange(text_pos,text_pos + text.length);
		}
	},selectRows: function(startRow,rowCount){
		var content = this.editorWindow.get('value');
		var startPos = 0;
		var endPos = 0;
		for(var i=0; i < startRow; i++){
			if(content.indexOf('\n',startPos) >= 0){
				startPos = content.indexOf('\n',startPos) + 1;
			} else {
				startPos = content.length;
			}
		}
		endPos = startPos;
		for(var j=0; j < rowCount; j++){
			if(content.indexOf('\n',endPos) >= 0){
				endPos = content.indexOf('\n',endPos) + 1;
			} else {
				endPos = content.length;
			}
		}
		this.editorWindow.selectRange(startPos,endPos);
	}
});
