/**
 * @author Ryan Johnson <http://saucytiger.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/control/textarea
 * @require prototype.js, livepipe.js
 */

if(typeof(Prototype) == "undefined")
	throw "Control.TextArea requires Prototype to be loaded.";
if(typeof(Object.Event) == "undefined")
	throw "Control.TextArea requires Object.Event to be loaded.";

Control.TextArea = Class.create({
	initialize: function(textarea){
		this.onChangeTimeout = false;
		this.element = $(textarea);
		$(this.element).observe('keyup',this.doOnChange.bindAsEventListener(this));
		$(this.element).observe('paste',this.doOnChange.bindAsEventListener(this));
		$(this.element).observe('input',this.doOnChange.bindAsEventListener(this));
		if(!!document.selection){
			$(this.element).observe('mouseup',this.saveRange.bindAsEventListener(this));  
			$(this.element).observe('keyup',this.saveRange.bindAsEventListener(this));
		}
	},
	doOnChange: function(event){
		if(this.onChangeTimeout)
			window.clearTimeout(this.onChangeTimeout);
		this.onChangeTimeout = window.setTimeout(function(){
			this.notify('change',this.getValue());
		}.bind(this),Control.TextArea.onChangeTimeoutLength);
	},
	saveRange: function(){
		this.range = document.selection.createRange();  
	},
	getValue: function(){
		return this.element.value;
	},
	getSelection: function(){
		if(!!document.selection)
			return document.selection.createRange().text;
		else if(!!this.element.setSelectionRange)
			return this.element.value.substring(this.element.selectionStart,this.element.selectionEnd);
		else
			return false;
	},
	replaceSelection: function(text){
		var scroll_top = this.element.scrollTop;
		if(!!document.selection){
			this.element.focus();
			var range = (this.range) ? this.range : document.selection.createRange();
			range.text = text;
			range.select();
		}else if(!!this.element.setSelectionRange){
			var selection_start = this.element.selectionStart;
			this.element.value = this.element.value.substring(0,selection_start) + text + this.element.value.substring(this.element.selectionEnd);
			this.element.setSelectionRange(selection_start + text.length,selection_start + text.length);
		}
		this.doOnChange();
		this.element.focus();
		this.element.scrollTop = scroll_top;
	},
	wrapSelection: function(before,after){
		this.replaceSelection(before + this.getSelection() + after);
	},
	insertBeforeSelection: function(text){
		this.replaceSelection(text + this.getSelection());
	},
	insertAfterSelection: function(text){
		this.replaceSelection(this.getSelection() + text);
	},
	collectFromEachSelectedLine: function(callback,before,after){
		this.replaceSelection((before || '') + $A(this.getSelection().split("\n")).collect(callback).join("\n") + (after || ''));
	},
	insertBeforeEachSelectedLine: function(text,before,after){
		this.collectFromEachSelectedLine(function(line){
		},before,after);
	}
});
Object.extend(Control.TextArea,{
	onChangeTimeoutLength: 500
});
Object.Event.extend(Control.TextArea);

Control.TextArea.ToolBar = Class.create(	{
	initialize: function(textarea,toolbar){
		this.textarea = textarea;
		if(toolbar)
			this.container = $(toolbar);
		else{
			this.container = $(document.createElement('ul'));
			this.textarea.element.parentNode.insertBefore(this.container,this.textarea.element);
		}
	},
	attachButton: function(node,callback){
		node.onclick = function(){return false;}
		$(node).observe('click',callback.bindAsEventListener(this.textarea));
	},
	addButton: function(link_text,callback,attrs){
		var li = document.createElement('li');
		var a = document.createElement('a');
		a.href = '#';
		this.attachButton(a,callback);
		li.appendChild(a);
		Object.extend(a,attrs || {});
		if(link_text){
			var span = document.createElement('span');
			span.innerHTML = link_text;
			a.appendChild(span);
		}
		this.container.appendChild(li);
	}
});

function textAreaView(textWrite,textPreview){

return (function(){			
	//setup

	var textarea = new Control.TextArea(textWrite);

	var toolbar = new Control.TextArea.ToolBar(textarea);
	toolbar.container.id = 'markdown_toolbar'; //for css styles
	
	//preview of markdown text
	var converter = new Showdown.converter;
	var converter_callback = function(value){
		$(textPreview).update(converter.makeHtml(value));
	}
	converter_callback(textarea.getValue());
	textarea.observe('change',converter_callback);
	
	//buttons
	toolbar.addButton('Italics',function(){
		this.wrapSelection('*','*');
	},{
		id: 'markdown_italics_button'
	});
	
	toolbar.addButton('Bold',function(){
		this.wrapSelection('**','**');
	},{
		id: 'markdown_bold_button'
	});
	
	toolbar.addButton('Link',function(){
		var selection = this.getSelection();
		var response = prompt('Enter Link URL','');
		if(response == null)
			return;
		this.replaceSelection('[' + (selection == '' ? 'Link Text' : selection) + '](' + (response == '' ? 'http://link_url/' : response).replace(/^(?!(f|ht)tps?:\/\/)/,'http://') + ')');
	},{
		id: 'markdown_link_button'
	});
	
	toolbar.addButton('Image',function(){
		var selection = this.getSelection();
		var response = prompt('Enter Image URL','');
		if(response == null)
			return;
		this.replaceSelection('![' + (selection == '' ? 'Image Alt Text' : selection) + '](' + (response == '' ? 'http://image_url/' : response).replace(/^(?!(f|ht)tps?:\/\/)/,'http://') + ')');
	},{
		id: 'markdown_image_button'
	});
	
	toolbar.addButton('Heading',function(){
		var selection = this.getSelection();
		if(selection == '')
			selection = 'Heading';
		this.replaceSelection("\n" + selection + "\n" + $R(0,Math.max(5,selection.length)).collect(function(){'-'}).join('') + "\n");
	},{
		id: 'markdown_heading_button'
	});
	
	toolbar.addButton('Unordered List',function(event){
		this.collectFromEachSelectedLine(function(line){
			return event.shiftKey ? (line.match(/^\*{2,}/) ? line.replace(/^\*/,'') : line.replace(/^\*\s/,'')) : (line.match(/\*+\s/) ? '*' : '* ') + line;
		});
	},{
		id: 'markdown_unordered_list_button'
	});
	
	toolbar.addButton('Ordered List',function(event){
		var i = 0;
		this.collectFromEachSelectedLine(function(line){
			if(!line.match(/^\s+$/)){
				++i;
				return event.shiftKey ? line.replace(/^\d+\.\s/,'') : (line.match(/\d+\.\s/) ? '' : i + '. ') + line;
			}
		});
	},{
		id: 'markdown_ordered_list_button'
	});
	
	toolbar.addButton('Block Quote',function(event){
		this.collectFromEachSelectedLine(function(line){
			return event.shiftKey ? line.replace(/^\> /,'') : '> ' + line;
		});
	},{
		id: 'markdown_quote_button'
	});
	
	toolbar.addButton('Code Block',function(event){
		this.collectFromEachSelectedLine(function(line){
			return event.shiftKey ? line.replace(/    /,'') : '    ' + line;
		});
	},{
		id: 'markdown_code_button'
	});
	
	toolbar.addButton('Help',function(){
		window.open('http://daringfireball.net/projects/markdown/dingus');
	},{
		id: 'markdown_help_button'
	});
});
};


function textView(textWrite,textPreview){

return (function(){			
	//setup
	var textarea = new Control.TextArea(textWrite);
	
	//preview of markdown text
	var converter = new Showdown.converter;
	var converter_callback = function(value){
		$(textPreview).update(converter.makeHtml(value));
	}
	converter_callback(textarea.getValue());
	textarea.observe('change',converter_callback);
	
});
};

function clearForm(inputValue) {
	document.getElementById(inputValue).value = "";
}
