// Node Javascript for Logician(tm)
//  Copyright (c) 2007-2008 by Micah Ferrill

function maxlength(e){
	if (e.target.value.length > 75){
		e.target.value = e.target.value.slice(0,75);
	}
	e.target.value = e.target.value.replace(/\n/g,'');
	e.target.innerHTML = e.target.value;
}

// creates a node
function createNode(title,description){
	
	// content defaults
	if (title == null){
		title = 'Put Your Title Here';
	}
	if (description == null){
		description = 'Put your description here.';
	}

	return DIV({'class':'node-wrap','style':'display:none;'},
	   DIV({'class':'node'},
			TEXTAREA({'class':'title','rows':1,'onclick':firstClick,'onkeydown':maxlength,'onkeyup':maxlength},title),
			A({'href':'#','class':'showHide','onclick':toggleElem},'Hide'),
			P(null,
				HR(),
				TEXTAREA({'class':'description','rows':'1','onclick':firstClick,'onkeydown':resize,'onkeyup':resize},description),
				A({'onclick':addNode,'class':'new','href':'#'},'New')
			)
		)
	);
}

// inserts a new node into the document above the link that caused it
function addNode(e,node,parent,noEffect){
	
	if (e != null) {
		e.preventDefault();
	}

	// differentiate between a button-click insert, and an explicit parent
	if (parent == null && e != null){
		var before = e.target;
	}
	else {
		var nodes = getElementsByTagAndClassName('a','new',parent);
		var before = nodes[nodes.length-1];
	}
	
	// create the node
	if (node == null){
		node = createNode();
	}
	
	// resize the textarea to its proper size
	resize(null,getFirstElementByTagAndClassName('textarea','description',node));
	
	// insert the node in its proper place
	if (e == null && parent == null || e == null && parent == 'top'){
	
		// the first element just gets appended to the "top" <div> and has no border
		//node.firstChild.style.border = 'none';
		appendChildNodes('top',node);
	}
	else {
	
		// all others need an extra control (a delete link) and get added to
		//  the node conaining the clicked add button
		appendChildNodes(node.lastChild.lastChild,A({'href':'#','class':'delete','onclick':remove},'Delete'));
		insertSiblingNodesBefore(before,node);
	}
	
	if (noEffect == null){
		// use a cool effect to reveal the new node
		blindDown(node, {'duration':0.5});
	}
	
	MochiKit.Sortable.Sortable.destroy('top');
	MochiKit.Sortable.Sortable.create('top', {'tree':true,'tag':'div','treeTag':'div'});
}

// selects the whole text first time, then ignores after
function firstClick(e){
	
	// select the whole text
	e.target.select();
	
	// then disconnect ourselves to ensure we don't do it twice
	e.target.onclick = noop;
}

// removes a node from the tree
function remove(e){
	
	e.preventDefault();
	// find the node
	var node = e.target.parentNode.parentNode;
	node.className = node.className + ' dying';

	// first ensure the user really meant to delete it
	confirm('Delete "' + node.firstChild.value + '"?',
	
			// and then do it
			partial(blindUp,node,{'duration':0.5,'afterFinish':function(){
				try {
					removeElement(getFirstElementByTagAndClassName('div','dying'));
				}
				catch (Exception){}
			}})
	);
}

// automatically resizes the textarea to eliminate the need for scrollbars
function resize(e,what){
	
	// find the text object
	if (what != null){
		var text = getElement(what);
	}
	else {
		var text = e.target;
	}
	
	// get the number of lines in the textarea
	var lineCount = text.value.split('\n').length + 1;
	
	// and resize the container to fit
	text.style.height = lineCount * 16 + 'px';
	
	// update the innerHTML for saving the document
	text.innerHTML = text.value;
}

// show or hide a node
function toggleElem(e){

	// the operation to execute
	var mode = e.target.innerHTML;
	e.preventDefault();

	// this ensures the Show / Hide button won't be clicked during the operation
	e.target.innerHTML = '';
	e.target.blur();

	// hide a node
	if (mode == 'Hide'){
		blindUp(e.target.nextSibling,{'duration':0.5,'afterFinish':function(){e.target.innerHTML = 'Show'}});
	}
	
	// or show it
	else {
		blindDown(e.target.nextSibling,{'duration':0.5,'afterFinish':function(){e.target.innerHTML = 'Hide'}});
	}
}

addLoadEvent(function(){

	if (getElement('frame').childNodes[1].id == 'top'){
		// create the root element
		addNode();
	}
	else {
		forEach($$('a.showHide'),function(elem){
			elem.onclick = toggleElem;
		});
		forEach(getElementsByTagAndClassName('a','new'),function(elem){
			elem.onclick = addNode;
		});
		forEach(getElementsByTagAndClassName('a','delete'),function(elem){
			elem.onclick = remove;
		});
		forEach(getElementsByTagAndClassName('textarea','title'),function(elem){
			elem.onkeydown = maxlength;
			elem.onkeyup = maxlength;
		});
		forEach(getElementsByTagAndClassName('textarea','description'),function(elem){
			elem.onkeydown = resize;
			elem.onkeyup = resize;
		});
	}
});