base2.DOM.bind(document);
var OB = {};

OB.Json =
{
	mySingle: null,
	myQueue: [],
	myPool: [],

	ReadyStateChange: function(myObj, myFunction)
	{
		if (!myObj || myObj.readyState != 4) return;
		if (myObj.status == 200 && myFunction) myFunction(myObj);
		OB.Json.cleanupXhr(myObj);
	},

	Single: function(myUrl, myFunction)
	{
		if (this.mySingle) this.abortXhr(this.mySingle);
		this.mySingle = this.makeXhr();
		if (!this.mySingle) return false;
		this.mySingle.onreadystatechange =
			function() { OB.Json.ReadyStateChange(OB.Json.mySingle, myFunction); };
		this.mySingle.open('GET', myUrl, true);
		this.mySingle.send(null);
		return true;
	},

	Queue: function(myUrl, myFunction)
	{
		var myObj = this.makeXhr();
		if (!myObj) return false;
		myObj.onreadystatechange =
			function() { OB.Json.ReadyStateChange(myObj, myFunction); };
		myObj.open('GET', myUrl, true);
		this.myQueue.push(myObj);
		if (this.myQueue.length == 1) myObj.send(null);
		return true;
	},

	abortXhr: function(myObj) //do some internal cleanup
	{
		myObj.onreadystatechange = function() {};
		myObj.abort();
		this.myPool.push(myObj);
	},

	cleanupXhr: function(myObj) //only for successes
	{
		this.abortXhr(myObj);
		if (this.myQueue.length && myObj == this.myQueue[0]) this.myQueue.shift();
		if (this.mySingle && myObj == this.mySingle) this.mySingle = null;
		else if (this.myQueue.length) this.myQueue[0].send(null);
	},

	makeXhr: function()
	{
		if (this.myPool.length > 0) return this.myPool.shift();
		var myObj;
		if (window.XMLHttpRequest) return new XMLHttpRequest();
		try
		{
			return new ActiveXObject('Microsoft.XMLHTTP');
		}
		catch(e)
		{
			return null;	
		}
	}

};

OB.Load =
{
	Load: function()
	{
		document.addEventListener('DOMContentLoaded', OB.Load.DomContentLoaded, false);
		if (document.body)
		{
			base2.DOM.bind(document.body)
			document.body.addClass('script');
		}
		else setTimeout(OB.Load.Load, 100);
	},

	Unload: function()
	{
	},

	DomContentLoaded: function()
	{
		if (getById('search'))
		{
			var myNode = getById('search');
			myNode.addEventListener('keyup', OB.Suggest.KeyPress, false);
			if (myNode.value) OB.Suggest.Timeout();
		}
		if (getById('vote'))
		{
			document.matchAll('form#vote button').forEach(function(myNode)
			{
				myNode.addEventListener('click', OB.Vote.Form, false);
			});
			getById('vote').addEventListener('mouseover', OB.Vote.Hover, false);
			getById('vote').addEventListener('mouseout', OB.Vote.Out, false);
		}
		if (getById('preview-button'))
		{
			getById('preview-button').addEventListener('click', OB.Verse.Preview, false);	
		}
	}
};

OB.Suggest =
{
	myInterval: 300,
	myId: 'search',
	myTimeout: 0,
	myUrl: '/topics/tools/suggest?q=',

	KeyPress: function()
	{
		if (OB.Suggest.myTimeout) clearTimeout(OB.Suggest.myTimeout);
		OB.Suggest.myTimeout = setTimeout(OB.Suggest.Timeout, OB.Suggest.myInterval);
	},

	Response: function(myXhr)
	{
		if (myXhr.responseText)
		{
			try
			{
				var myObj = eval('(' + myXhr.responseText + ')');
				getById('suggest').innerHTML = myObj.result;
				return;
			}
			catch(e) {}
		}
		getById('suggest').innerHTML = '';
	},

	Timeout: function()
	{
		var myValue = getById(OB.Suggest.myId).value;
		if (myValue == '') getById('suggest').innerHTML = '';
		else OB.Json.Single(OB.Suggest.myUrl + escape(myValue), OB.Suggest.Response);
	}
	
};

OB.Url =
{
	QueryString: function(myObj)
	{
		var myOuts = new Array;
		for (var i in myObj)
		{
			myOuts.push(escape(i) + '=' + escape(myObj[i]));
		}
		return myOuts.join('&');
	}
};


OB.Verse =
{
	previewUrl: '/topics/tools/verse?verse=',

	Preview: function(myEvent)
	{
		myEvent.preventDefault();
		var myValue = getById('preview').value;
		if (myValue.length > 0)
		{
			myValue = escape(myValue);
			OB.Json.Single(OB.Verse.previewUrl + myValue, OB.Verse.PreviewResponse);
		}
	},

	PreviewResponse: function(myXhr)
	{
		if (myXhr.responseText)
		{
			try
			{
				var myObj = eval('(' + myXhr.responseText + ')');
				var myNode = getById('preview-text');
				if (myObj.content && myObj.id && myObj.reference)
				{
					myNode.innerHTML = '<h3>' + myObj.reference + '</h3>';
					myNode.innerHTML += '<p>' + myObj.content + '</p>';
					myNode.innerHTML += '<p><input type="submit" value="Suggest This Verse" /></p>';
					getById('verse').value = myObj.id;
					return;
				}
				else
				{
					throw '';
				}
			}
			catch(e)
			{
			}
		}
		getById('preview-text').innerHTML = '<p class="error">Sorry, we couldn&rsquo;t find a passage matching the verse you suggest. We may be experiencing technical difficulties. Please double-check your spelling, then wait a few moments and try again.</p>';
	}

};

OB.Vote =
{
	currentHover: null,
	myUrl: '/topics/tools/vote',

	Form: function(myEvent)
	{
		var myTarget = myEvent.target || myEvent.srcElement;
		if (!myTarget || !myTarget.id) return;
		myEvent.preventDefault();
		var myWord = document.URL;
		myWord = myWord.replace(/\/+$/, ''); //remove trailing slash, if any
		var myQueryString = OB.Url.QueryString({
			word: myWord.split(/\//).pop(),
			id: myTarget.id,
			time: (new Date()).getTime() //to allow re-requests on ie
			});
		var myUrl = OB.Vote.myUrl + '?' + myQueryString;
		OB.Json.Queue(myUrl, null);
		myTarget.parentNode.innerHTML = 'Thank you for your vote.';
	},

	Hover: function(myEvent)
	{
		var myTarget = myEvent.target || myEvent.srcElement;
		if (!myTarget) return;
		do
		{
			if (myTarget.nodeName == 'DIV')
			{
				myTarget = getById(myTarget); //add methods
				if (myTarget.hasClass('verse'))
				{
					if (!myTarget.hasClass('visible')) myTarget.addClass('visible');
					OB.Vote.currentHover = myTarget;
					return;
				}
				else OB.Vote.clearCurrentHover();
				break;
			}
		}
		while (myTarget = myTarget.parentNode);
	},

	Out: function(myEvent)
	{
		OB.Vote.clearCurrentHover();
	},

	Thanks: function(myObj)
	{
	},

	clearCurrentHover: function()
	{
		if (OB.Vote.currentHover)
		{
			OB.Vote.currentHover.removeClass('visible');
			OB.Vote.currentHover = null;
		}
	}
};

function getById(myId)
{
	if (typeof myId == 'object')
	{
		if (!myId.base) base2.DOM.bind(myId);
		return myId;
	}
	return document.matchSingle('#' + myId);	
}

OB.Load.Load();