/** 
 * jsTextTools
 *
 * A toolbar for manipulating text in the currently selected form element.
 * Supported elements are text and textareas.
 * 
 * @author Tom Anderson <tom.h.anderson@gmail.com>
 */

var charmapField = null;
var tt_showshort = false;

var menuManager = {
	menus: Array(),
	menuTimer: 0,

	add: function(menu) {
		menuManager.menus[menuManager.menus.length] = menu;
	},

	reset: function() {
		menuManager.menus.each(function(menu, index) {
			if (menu.toolbar) {
				Element.remove(menu.toolbar);
				menu.toolbar = null;
			}
		});
	}

}

var jsTextTools = Class.create()
jsTextTools.prototype = {
	version: 1.0,
	author: 'tom.h.anderson@gmail.com',
	homepage: 'http://www.ludwigsghost.com/',
	
	watch: null,
	
	initialize: function(node, hideText) {
		// Exception for dynamic lookup.ihtml elements
		if (Element.hasClassName(node, 'artist_lookup')) return;
	
		this.watch = node;
		Event.observe(this.watch, 'focus', menuManager.reset);

		if (this.watch.type == 'text' && !hideText) 
			return this.initText();

		if (hideText) return this.menu();

		button1 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'Character Map'); 
		button1.onclick = this.charMap.bindAsEventListener(this);
		button2 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'Proper Case'); 
		button2.onclick = this.ucFirst.bindAsEventListener(this);

		// Show these buttons for textarea only
		if (!hideText) {
		button3 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'Tokenize Slashes'); 
		button3.onclick = this.slash2nl.bindAsEventListener(this);
		button4 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'No Track #s'); 
		button4.onclick = this.removeTracks.bindAsEventListener(this);
		button5 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'No <br>'); 
		button5.onclick = this.removeBR.bindAsEventListener(this);
		button6 = Builder.node('button', {
			className: 'dbsubmit'
		}, 'No Timings (beta!)'); 
		button6.onclick = this.removeTimings.bindAsEventListener(this);
		} else {
		button3 = button4 = button5 = button6 = ' ';
		}

		// Put the buttons on two rows
		if (tt_showshort) shortspacer = Builder.node('br');
		else shortspacer = ' ';

		toolbar = Builder.node('div', {
				style: 'position: relative; \
					text-align: left; \
					border-width: 0px; \
					'
			}, [
			Builder.node('div', {
				style: 'margin-right: 15px; \
				'}, [
				button1, ' ',
				button2, ' ',
				button3, shortspacer,
				button4, ' ',
				button5, ' ',
				button6
			])
		]);
			
		this.toolbar = toolbar;

		Element.insert(node, {before: toolbar});
		
	},

	/**
 	 * For popup menues on text elements
	 */
	menu: function() {
		// Close all other open menus
		menuManager.reset();

		// Build new menu
		link1 = Builder.node('div', {
				className: 'menudiv',
				style: 'padding: 1px; margin: 1px;'
			}, [
			Builder.node('img', {
				src: '/images/ico/text_letter_omega.png',
				style: 'border: 0;'
				}), ' Character Map'
		]);
		link1.onclick = this.charMap.bindAsEventListener(this);
		link1.onmouseover = this.hover.bindAsEventListener(this);
		link1.onmouseout = this.blur.bindAsEventListener(this);
		link2 = Builder.node('div', {
				className: 'menudiv',
				style: 'padding: 1px; margin: 1px;'
			}, [
			Builder.node('img', {
				src: '/images/ico/font.png',
				style: 'border: 0;'
				}), ' Proper Case'
		]);
		link2.onclick = this.ucFirst.bindAsEventListener(this);
		link2.onmouseover = this.hover.bindAsEventListener(this);
		link2.onmouseout = this.blur.bindAsEventListener(this);
		tools = Builder.node('div', {
			style: 'position: absolute; \
				background-color: #efd1b4; \
				padding: 3px; \
				border: solid; \
				border-color: #ef9b49; \
				border-width: 2px; \
			'
			}, [ 
			link1,
			link2
		]);	

		Element.insert(document.body, tools);
		Element.clonePosition(tools, this.icon, {
			setWidth: false,
			setHeight: false,
			offsetLeft: 16
		});
		this.toolbar = tools;

		// Set menu close timer
		this.menuTimeStart = new Date();
		window.tt_menuCheckTimer = this.menuTimeout.bind(this);
		this.menuTimer = setTimeout("tt_menuCheckTimer()", 500);

		menuManager.add(this);
	},

	blur: function(event) {
		node = Event.findElement(event);
		if (!node.hasClassName('menudiv')) return;
		node.setStyle({
			backgroundColor: 'efd1b4'
		});
	},
	hover: function(event) {
		// Reset menu close timer
		this.menuTimeStart = new Date();
		window.tt_menuCheckTimer = this.menuTimeout.bind(this);
		this.menuTimer = setTimeout("tt_menuCheckTimer()", 500);

		node = Event.findElement(event);
		if (!node.hasClassName('menudiv')) return;
		node.setStyle({
			backgroundColor: 'ef9b49'
		});
	},

	menuTimeout: function() {
		var now = new Date();
		if (now - this.menuTimeStart > 2500) {
			menuManager.reset();
			clearTimeout(this.menuTimer);
		} else {
			// Reset the timer
			this.menuTimer = setTimeout("tt_menuCheckTimer()", 500);
		}
	},

	initText: function(textarea) {

		tools = Builder.node('img', {
			src: '/images/ico/text_allcaps.png',
			title: 'Show Text Tools'
		});

		tools.onclick = this.bindText.bindAsEventListener(this);

		this.icon = tools;

		if (textarea) {
			tools = Element.wrap(tools, Builder.node('div'));
			Element.insert(this.watch, {before: tools});
		} else {
			Element.insert(this.watch, {after: tools});
		}
		return true;
	},

	bindText: function() {
		if (this.toolbar) {
			Element.remove(this.toolbar);
			this.toolbar = null;
		} else {
			this.initialize(this.watch, true);
		}
	},
	
	charMap: function() {
	        charmapField = this.watch;
	        var charmap = window.open("http://db.etree.org/charmap.html", 'charmap','toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,width=420,height=490,resizable=1');
		menuManager.reset();
		return false;
	},
	
	ucFirst: function() {
		this.watch.value = this.watch.value.ucFirst();
		menuManager.reset();
		return false;
	},
	
	removeTimings: function() {
		this.watch.value = 
	this.watch.value.replace(/[\[\(][0-9\.:]+[\)\]]$/mg, '');
		return false;
	},

	removeTracks: function() {
		this.watch.value = 
	this.watch.value.replace(/^[0-9]{1,3}[:\)-\.\t ][-:]?[ \t]*/mg, '');
		return false;
	},
	
	slash2nl: function() {
		this.watch.value = this.watch.value.replace(/[\/\\]/g,"\n");
		return false;
	},
	removeBR: function() {
		this.watch.value = this.watch.value.replace(/(\<br.?\/?\>)|(\<BR.?\/?\>)/g,"");
		return false;
	}
}

function jsTextTools_bind(event) {
	$$('textarea').each(function(node) {
		new jsTextTools(node);
	});
	if (true) {
		$$('input').each(function(node) {
			if (node.type == 'text')
				new jsTextTools(node);
		});
	}
}

Event.observe(window, 'load', jsTextTools_bind);

/**
 * http://jroller.com/rmcmahon/entry/resizingtextarea_with_prototype
 */
var ResizingTextArea = Class.create();
ResizingTextArea.prototype = {
    defaultRows: 0,
    watch: null,

    initialize: function(field)
    {
	if (field.tagName.match(/textarea/i) == null)	{
		return;
	}
 	this.watch = field;
        this.defaultRows = Math.max(field.rows, 1);
        this.watch.resizeNeeded = this.resizeNeeded.bindAsEventListener(this);
        Event.observe(this.watch, "click", this.watch.resizeNeeded);
        Event.observe(this.watch, "keyup", this.watch.resizeNeeded);
    },

    resizeNeeded: function(event)
    {
        var lines = this.watch.value.split('\n');
        var newRows = lines.length + 1;
        var oldRows = this.watch.rows;
        for (var i = 0; i < lines.length; i++)
        {
            var line = lines[i];
            if (line.length >= this.watch.cols) newRows += Math.floor(line.length / this.watch.cols);
        }
        if (newRows > this.watch.rows) this.watch.rows = newRows;
        if (newRows < this.watch.rows) this.watch.rows = Math.max(this.defaultRows, newRows);
    }
}

