// ==UserScript==
// @name           ESV: Short Dynamic Title
// @namespace      http://weston.ruter.net/
// @description    Cleans up the document title when looking up scripture. Changes the document title to be the scripture reference for the currently selected text. If no text is selected, then the reference for the entire page is used as the page title. Great for bookmarking, for identifying the loaded scripture in a window or tab, and for taking clippings for Google Notebook.
// @include        http://www.gnpcb.org/esv/search?q=*
// @include        http://www.gnpcb.org/esv/search/?q=*
// @include        http://www.esvstudybible.org/search?q=*
// @include        http://www.esvstudybible.org/search/?q=*
// ==/UserScript==

(function(){
	
//Change document title to be the current reference
var h2 = document.getElementsByTagName('h2')[0];
if(h2.parentNode.className.match(/errors/))
	return;	
var originalReference = h2.firstChild.data;
var currentReference = '';
document.title = originalReference + '(ESV)';

var matches = originalReference.match(/\w+\s*(\d+)/);
var originalChapter = +matches[1];

var bookMatches = h2.firstChild.data.match(/^\s*(\d*\s*?\w+)/);
if(!bookMatches)
	throw Error("Unable to get the book name from the string: " + h2.firstChild.data);
var bookName = bookMatches[1];

var currentStartContainer = null;
var currentEndContainer = null;
var currentStartOffset = 0;
var currentEndOffset = 0;


//Can we set xpointer?
var interval = window.setInterval(function(){
	var selected = window.getSelection();
	if(!selected || !selected.rangeCount)
		return;
	
	var range = selected.getRangeAt(0);
	if(currentStartContainer == range.startContainer &&
	   currentEndContainer == range.endContainer &&
	   currentStartOffset == range.startOffset &&
	   currentEndOffset == range.endOffset)
	{
		return;
	}
	
	//Abort if no text selected
	if(range.collapsed){
		document.title = originalReference + '(ESV)';
		return;
	}
	
	currentStartContainer = range.startContainer;
	currentEndContainer = range.endContainer;
	currentStartOffset = range.startOffset;
	currentEndOffset = range.endOffset;
	
	//Detect whether or not we are selecting a heading
	var heading = null;
	if(currentStartContainer.parentNode.nodeName.toLowerCase() == 'h3')
		heading = currentStartContainer.parentNode;
	else if(currentStartContainer.nodeName.toLowerCase() == 'h3')
		heading = currentStartContainer;
	if(heading){
		//If we only have selected heading text, then abort
		if(currentStartContainer == currentEndContainer){
			document.title = originalReference + '(ESV)';
			return;
		}
		//Set the start container to the end container, which is selecting the text
		currentStartContainer = currentEndContainer;
	}
	
	
	var startChapter = 0;
	var startVerse = 0;
	var endChapter = 0;
	var endVerse = 0;
	
	//We should be using NodeIterator, but FireFox doesn't support it
	var i = document.evaluate("//div[@class='esv-text']//node()", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
	
	//Get the start reference: find the preceding verse element
	var node = i.iterateNext(); 
	while (node) {
		if(node.nodeName.toLowerCase() == 'span'){
			//Detect a chapter/verse start element
			if(node.className.match(/chapter-num/)){
				var matches = node.firstChild.data.match(/(\d+)(?:\D+(\d+))?/,'');
				if(matches){
					startChapter = +matches[1];
					startVerse = matches[2] ? +matches[2] : 1;
				}
			}
			//Detect a verse start element
			else if(node.className.match(/verse-num/)){
				startVerse = +node.firstChild.data;
			}
		}
		//Stop iterating once we encounter the start container
		if(node == currentStartContainer)
			break;
		node = i.iterateNext();
	}
	//Abort if not selected the text at all!
	if(!node){
		document.title = originalReference + '(ESV)';
		return;
	}
	
	if(!startChapter)
		startChapter = originalChapter;

	currentReference = bookName + " " + startChapter + ":" + startVerse;
	endChapter = startChapter;
	endVerse = startVerse;
		
	//Get the end reference
	if(currentStartContainer != currentEndContainer){
		node = i.iterateNext(); 
		while (node) {
			if(node.nodeName.toLowerCase() == 'span'){
				//Detect a chapter/verse start element
				if(node.className.match(/chapter-num/)){
					var matches = node.firstChild.data.match(/(\d+)(?:\D+(\d+))?/,'');
					if(matches){
						endChapter = +matches[1];
						endVerse = matches[2] ? +matches[2] : 1;
					}
				}
				//Detect a verse start element
				else if(node.className.match(/verse-num/)){
					endVerse = +node.firstChild.data;
				}
			}
			if(node == currentEndContainer)
				break;
			node = i.iterateNext();
		}
		if(!endChapter)
			endChapter = originalChapter;
	}
	
	//Add a second reference if the selection spans multiple verses
	if(startChapter != endChapter || startVerse != endVerse){
		currentReference += '-';
		if(startChapter != endChapter)
			currentReference += endChapter + ':';
		currentReference += endVerse;
	}
	document.title = currentReference + ' (ESV)';
		
}, 100);

})();

