// --- Annotation stuff --- //
var noteObj = null;
var noteDiv = null;
var editorOpen = false;
var editID;
var OnInsert = "submitNote( document.getElementById('note').value )";
var OnEdit = "updateNote( document.getElementById('note').value, EditID )";

// --- Scripture popup stuff --- //
var verseURL = '/cgi-bin/verse.cgi';
var req = null;
var reqTimer = null;
var popupTimer = null;
var hideTimer = null;
var requestedVerse = '';
var verseObj = null;
var popupDiv = null;
var gotFullText = false;

/* Send a request for the passage to the server */
function requestVerse( passage )
{
	popupDiv.innerHTML = buildPopup( '<b>Please wait</b>', 'Looking up verse...' );	

	// First expand squashed book names (i.e. 'iiCor' = '2 Cor')
//	bookNum = passage.match( 'i*' );
//	if ( bookNum[0].length > 0 )
//		passage = bookNum[0].length + ' ' + passage.slice( bookNum[0].length );
	
	requestURL = verseURL + '?passage=' + passage + '&translation=' + preferences['popup'];

	req = newXHR();
	req.onreadystatechange = xhrStateChange;
	req.open( "GET", requestURL, true );
	req.send( null );
}

/* When the result comes back, fill the popup and position it */
function xhrStateChange()
{
	if ( req.readyState == 4 )
	{
		if ( req.status == 200 )
			popupDiv.innerHTML = parseXML( req.responseXML );
		else
			popupDiv.innerHTML = buildPopup( '<b>Error</b>',
				'An error has occured (status ' + req.status + ')' );

		gotFullText = true;
		positionPopup( verseObj, popupDiv );
		document.getElementById('boxTop').style.cursor = 'default';

		req = null;
	}
}

/* If the popup DIV has not yet been created, do so now and hide it */
function createPopupDiv()
{
	if ( popupDiv == null )
	{
		popupDiv = document.createElement( 'div' );
		popupDiv.style.visibility = 'hidden';
		popupDiv.style.position = 'absolute';
		popupDiv.innerHTML = buildPopup( '<b>Please wait</b>', 'Looking up verse...' );
		popupDiv.onmouseover = retainPopup;
		popupDiv.onmouseout = leaveVerse;

		document.body.appendChild( popupDiv );
	}
}

/* Construct the HTML for the popup using the given title and body text */
function buildPopup( title, body )
{
	html = '<div class="boxPopup">';
	html += '<div class="boxBottom">';
	html += '<div id="boxTop"><div class="boxTitle">' + title + '</div></div>';
	html += '<div class="boxMiddle">';
	html += '<div class="boxContent">' + body;
	html += '</div></div></div></div>';

	return html;
}

/* Read the title and body text from the XML and use it to build the popup */
function parseXML( xml )
{
	var title, body;

	title = unescape( xml.getElementsByTagName( 'title' )[0].firstChild.nodeValue );

	// Some browsers dice up long text nodes, so we must put them back together
	body = '';
	bodyNodes = xml.getElementsByTagName( 'body' )[0].childNodes;
	for( i = 0; i < bodyNodes.length; i++ )
	{
		body += unescape( bodyNodes[i].nodeValue );
	}

	return buildPopup( title, body );
}

/* Called on mouseover for verse references
	referenceObj	the DOM object representing the verse link
	passage			the scripure reference text
*/
function popupVerse( referenceObj, passage )
{
	if ( preferences['popup'] != '')
	{
		createPopupDiv();

		resetHideTimer();

		// Request new verse only if the mouse actually pointed to a different one
		if ( passage != requestedVerse )
		{
			hideVerse();

			verseObj = referenceObj;
			requestedVerse = passage;

			resetPopupTimer();
			popupTimer = setTimeout( onPopupTimer, 500 );

			resetReqTimer();
			reqTimer = setTimeout( onReqTimer, 100 );
		}
	}
}

/* Called on mouseout for verse references and the popup */
function leaveVerse()
{
//	if ( preferences['popup'] != '' )
//	{
		// If we moved off the verse before the balloon popped up, just cancel it
		if ( popupTimer != null || !gotFullText )
		{
			resetReqTimer();
			resetPopupTimer();
			hideVerse();
		}
		else
		{
			// Hide the popup shortly after leaving the verse
			resetHideTimer();
			hideTimer = setTimeout( onHideTimer, 100 );
		}

		// Abort any uncompleted request
		if ( req != null )
		{
			req.onreadystatechange = function() {};
			req.abort();
			req = null;
		}
//	}
}

/* Called on mouseover for the popup, to prevent it from disappearing */
function retainPopup()
{
	resetHideTimer();
}

/* Hide the popup */
function hideVerse()
{
	if ( popupDiv != null )
	{
		popupDiv.style.visibility = 'hidden';
		requestedVerse = '';
		gotFullText = false;
	}
}

/* Time to actually send the request */
function onReqTimer()
{
	reqTimer = null;
	requestVerse( requestedVerse );
}

/* Time to actually display the popup */
function onPopupTimer()
{
	popupTimer = null;
	positionPopup( verseObj, popupDiv );
	popupDiv.style.visibility = 'visible';
}

/* Time to actually hide the popup */
function onHideTimer()
{
	hideTimer = null;
	hideVerse();
}

function resetReqTimer()
{
	if ( reqTimer != null )
		clearTimeout( reqTimer );
	reqTimer = null;
}
	
function resetPopupTimer()
{
	if ( popupTimer != null )
		clearTimeout( popupTimer );
	popupTimer = null;
}

function resetHideTimer()
{
	if ( hideTimer != null )
		clearTimeout( hideTimer );
	hideTimer = null;
}

function newXHR()
{
	if ( window.XMLHttpRequest )
		return new XMLHttpRequest();
	else if ( window.ActiveXObject )
		return new ActiveXObject( "Microsoft.XMLHTTP" );
}

/* Traverse up the DOM hierarchy for an object to find its absolute position */
function findPos( obj )
{
	var curleft = curtop = 0;
	if ( obj.offsetParent )
	{
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while ( obj = obj.offsetParent )
		{
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

/* Center the popup over the source object but try to keep it on screen */
function positionPopup( popupSource, popupBox )
{
	var scrollLeft, scrollTop, windowWidth, windowHeight, posX, posY;

	var popupHeight = popupBox.offsetHeight;
	var popupWidth = popupBox.offsetWidth;

	var sourcePos = findPos( popupSource );
	var sourceLeft = sourcePos[0];
	var sourceTop = sourcePos[1];
	var sourceWidth = popupSource.offsetWidth;
	var sourceHeight = popupSource.offsetHeight;

	// Cross-browser compatible way of determining document/window dimensions
	if (document.documentElement.clientHeight != 0) {
		scrollLeft = document.documentElement.scrollLeft;
		scrollTop = document.documentElement.scrollTop;
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body.clientHeight != 0) {
		scrollLeft = document.body.scrollLeft;
		scrollTop = document.body.scrollTop;
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	} else if (window.innerHeight != 0) {
		scrollLeft = window.pageXOffset;
		scrollTop = window.pageYOffset;
		windowWidth = window.innerWidth;
		windowHeight = window.innerHeight;
	} else {
		popupBox.style.left = '0px';
		popupBox.style.top = '0px';
		return;
	}

	// Position popup above or below source, wherever there is more room
	if ( sourceTop - scrollTop > windowHeight / 2 )
		posY = sourceTop - popupHeight;
	else
		posY = sourceTop + sourceHeight;

	// Center popup over source, but make sure it stays within the window
	posX = scrollLeft + sourceLeft + sourceWidth / 2 - popupWidth / 2;
	posX = Math.min( scrollLeft + windowWidth - popupWidth - 8, posX );
	posX = Math.max( scrollLeft + 8, posX );
	posY = Math.min( scrollTop + windowHeight - popupHeight, posY );
	posY = Math.max( scrollTop + 8, posY );

	popupBox.style.left = posX + 'px';
	popupBox.style.top = posY + 'px';
}


// --- Annotation stuff --- //

function requestNote (refObj, id) {
	var postData = 'op=reqnote&id='+id;

	var request = newXHR();
	request.onreadystatechange = function () {
		if (request.readyState == 4 && request.status == 200) {
			popupDiv.innerHTML = parseXMLNote(request.responseXML);
			gotFullText = true;
			positionPopup(refObj.parentNode, popupDiv);
			document.getElementById('boxTop').style.cursor = 'default';
		}
	};
	
	request.open('POST', SCRIPT_PATH, true);
	request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	request.send(postData);
}

function createPopupNoteDiv() {
	if (noteDiv == null) {
		noteDiv = document.createElement('div');
		noteDiv.style.visibility = 'hidden';
		noteDiv.style.position = 'absolute';
		noteDiv.innerHTML = buildPopup('<b>Create Note</b>', 'blah');
		document.body.appendChild(noteDiv);
	}
}

function buildNote (text) {
	var note = '<p id="pNote">'+text+'</p><br />';
	note +=  '<div class="noteButtons"><button class="b1" onclick="editNote('+requestedVerse+');">Edit</button><button class="b2" onclick="deleteNote('+requestedVerse+');">Delete</button></div>';
	return note;
}

function buildNoteEditor (submitHandler, text) {
	var editor = '<textarea id="note" rows="5" cols="45">'+text+'</textarea>';
	editor += '<br /><br />';
	editor += '<div class="noteButtons"><button class="b1" onclick="'+submitHandler+';">Submit</button><button class="b2" onclick="closeEditor();">Cancel</button></div>';

	return editor;
}

function editNote (id) {
	EditID = id;
	popupNoteEditor(verseObj, OnEdit, getTextContent(document.getElementById('pNote')));
	leaveVerse();
}

function deleteNote (id) {
	deleteAnnotation(id);
	leaveVerse();
	refreshPage();
}

function parseXMLNote (xml) {
	var note = xml.getElementsByTagName('text')[0].firstChild.nodeValue;
	note = note.replace(/%26/g, '&');
	note = note.replace(/\n/g, '<br />');
	NoteID = xml.getElementsByTagName('id')[0].firstChild.nodeValue;
	NoteOffset = xml.getElementsByTagName('offset')[0].firstChild.nodeValue;
	return buildPopup('<b>Note</b>', buildNote(note));
}

function popupNote (referenceObj, id) {
	createPopupDiv();
	resetHideTimer();
	if (id != requestedVerse) {
		hideVerse();
		verseObj = referenceObj;
		requestedVerse = id;
		resetPopupTimer();
		popupTimer = setTimeout(onPopupTimer, 500);
		resetReqTimer();
		reqTimer = setTimeout(onReqTimerNote, 100);
	}
}

function popupNoteEditor (referenceObj, submitHandler, text) {
	noteObj = referenceObj;
	createPopupNoteDiv();

	if (editorOpen) {
		var note = document.getElementById('note');
		note.focus();
		flashTextArea(note, 'yellow', 250, 4);
	}
	else {
		noteDiv.innerHTML = buildPopup('<b>Create Note</b>', buildNoteEditor(submitHandler, text));
		positionPopup(noteObj, noteDiv);
		noteDiv.style.visibility = 'visible';
		var dPopup = new YAHOO.util.DD(noteDiv);
		dPopup.setHandleElId('boxTop');
		editorOpen = true;
		document.getElementById('boxTop').style.cursor = 'move';
		document.getElementById('note').focus();
	}
}

function flashTextArea (node, color, speed, reps) {
	if (reps > 0) {
		node.style.backgroundColor = (reps%2==0) ? color : 'white';
		var timer = setTimeout(function () { flashTextArea(node, color, speed, reps-1);  }, speed);
	}
}

function closeEditor () {
	noteDiv.style.visibility = 'hidden';
	editorOpen = false;
}

function onReqTimerNote () {
	reqTimer = null;
	requestNote(verseObj, requestedVerse);
}

