/** PostVoting object. */
function PostVoting(oOptions)
{
	this.opt = oOptions;
	this.sMessageId = '';
	this.sPosterId = '';
	this.bXmlHttpCapable = typeof(window.XMLHttpRequest) == 'undefined' ? false : true;
}

// Send a vote.
PostVoting.prototype.vote = function (sVoteDirection, iMessageId, sSessionId)
{
	if (!this.bXmlHttpCapable)
		return false;

	// For IE 5.0 support, 'call' is not yet used.
	this.tmpMethod = getXMLDocument;
	this.tmpMethod(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=gpbp;sa=' + sVoteDirection + ';msg=' + iMessageId + ';' + this.opt.sSessionVar + '=' + sSessionId + ';board=' + this.opt.iBoard + ';topic=' + this.opt.iTopic + ';xml', this.onVoteCasted);
	delete this.tmpMethod;
}

// The callback function used for the XMLhttp request sending the post vote.
PostVoting.prototype.onVoteCasted = function(XMLDoc)
{
	// Prepare the values to update the DOM.
	// Which post was it again?
	this.sMessageId = XMLDoc.getElementsByTagName('message')[0].childNodes[0].nodeValue;
	// Succeeded? What is the result (up, not up, down, not down)?
	var outputTitle = '';
	var outputImage = '';
	var litArrowStatus = true;
	var updateOpposite = XMLDoc.getElementsByTagName('opposite')[0].childNodes[0].nodeValue;
	switch (XMLDoc.getElementsByTagName('success')[0].childNodes[0].nodeValue)
	{
		case 'down':
			outputTitle = this.opt.sVotedDown;
			outputAlt = this.opt.sVotedDownAlt;
			outputImage = 'down';
			break;
		case 'not down':
			outputTitle = this.opt.sToVoteDown;
			outputAlt = this.opt.sVoteDownAlt;
			outputImage = 'down';
			litArrowStatus = false;
			break;
		case 'up':
			outputTitle = this.opt.sVotedUp;
			outputAlt = this.opt.sVotedUpAlt;
			outputImage = 'up';
			break;
		case 'not up':
			outputTitle = this.opt.sToVoteUp;
			outputAlt = this.opt.sVoteUpAlt;
			outputImage = 'up';
			litArrowStatus = false;
			break;
	}
	// What is the new vote count for this message?
	var outputCounter = XMLDoc.getElementsByTagName('counter')[0].childNodes[0].nodeValue;
	if (outputCounter > 0)
		outputCounter = '+' + outputCounter;
	this.sPosterId = XMLDoc.getElementsByTagName('who')[0].childNodes[0].nodeValue;

	// Do the DOM dance! Update respect counter(s), the vote counter, and the button image and its title.
	if (this.sPosterId != 0)
	{
		// Not a guest, so whose Respect got affected and what is his new Respect counter?
		var outputRespect = XMLDoc.getElementsByTagName('who')[0].getAttribute('respect');
		if (outputRespect > 0)
			outputRespect = '+' + outputRespect;
		// Attempt to modify each of this person's counters in the page.
		this.j = document.getElementsByTagName("span");
		for (var i = this.j.length - 1; i >= 0; i--)
			if (this.j[i].className == 'gpbp_respect_count_' + this.sPosterId)
				setInnerHTML(this.j[i], outputRespect);
		delete this.j;
	}
	// Look for the vote counter.
	this.j = document.getElementsByTagName("span");
	for (var i = this.j.length - 1; i >= 0; i--)
	{
		if (this.j[i].id == 'gpbp_score_' + this.sMessageId)
		{ 
			setInnerHTML(this.j[i], outputCounter);
			break;
		}
	}
	delete this.j;
	for (var i = document.images.length - 1; i>=0; i--)
	{
		this.gotcha = 0;
		// Also update the opposite arrow if needed.
		if (document.images[i].id == 'gpbp_vote_' + outputImage + '_' + this.sMessageId)
		{
			document.images[i].setAttribute("src", this.opt.sImagesUrl + '/gpbp_arrow_' + outputImage + ( litArrowStatus ? '_lit' : '' ) + '.gif');
			document.images[i].setAttribute("title", outputTitle);
			document.images[i].setAttribute("alt", outputAlt);
			this.gotcha++;
		}
		else if (updateOpposite == 1 && (document.images[i].id == 'gpbp_vote_' + (outputImage == 'up' ? 'down' : 'up') + '_' + this.sMessageId))
		{
			document.images[i].setAttribute("src", this.opt.sImagesUrl + '/gpbp_arrow_' + (outputImage == 'up' ? 'down' : 'up') + ( litArrowStatus ? '' : '_lit' ) + '.gif');
			document.images[i].setAttribute("title", outputImage == 'up' ? this.opt.sToVoteDown : this.opt.sToVoteUp);
			document.images[i].setAttribute("alt", outputImage == 'up' ? this.opt.sVoteDownAlt : this.opt.sVoteUpAlt);
			this.gotcha++;
		}
		if (this.gotcha == 1 + updateOpposite)
		{
			delete this.gotcha;
			break;
		}
	}

	return true;
}

// Display a hidden post (grey).
function gpbp_show_post(iMessageId)
{
	
	// First, let's remove the inform bar
	document.getElementById('gpbp_hiddenmsg_' + iMessageId).style.display = 'none';

	// Now to display the post itself, remove the gpbp_hider class from any element within.
	var current = document.getElementById('gpbp_hidden_' + iMessageId);
	gpbp_RemoveClassRecursive(current, 'gpbp_hider', false);

	return false;
}

// Display a hidden post 2 (hide).
function gpbp_show_posta(iMessageId)
{
	
	// First, let's remove the inform bar
	document.getElementById('gpbp_hiddenmsga_' + iMessageId).style.display = 'none';
	
	// Now to display the post itself, remove the gpbp_hider class from any element within.
	var currenta = document.getElementById('gpbp_hiddena_' + iMessageId);
	gpbp_RemoveClassRecursive(currenta, 'gpbp_hider', false);

	return false;
}

// Recursive class lookup+removal. Meant to support any theme, if it's WC3-compliant at least...
function gpbp_RemoveClassRecursive(current, targetClass, hide_inline) {
	if (current == null)
		return;

	// Class sweeping.
	if (current.className != undefined && current.className != '')
	{
		names = current.className.split(" ");
		found = [];
		var gotcha = false;
		// This will hopefully help get rid of the target class from any element.
		for (var i = names.length - 1; i >= 0; i--)
			if (names[i] == targetClass)
				gotcha = true;
			else
				found[found.length] = names[i];

		// Is there a NEED to tweak its class? 
		if (gotcha)
		{
			current.className = '';
			for (var i = 0, l = found.length; i < l; i++)
				current.className += (i > 0 ? ' ' : '') + found[i];

			// If required, hide this element via inline property.
			if (hide_inline)
				current.style.display = 'none';
		}

		// For efficiency's sake, and browser healthyness!
		delete names;
		delete found;
	}

	// Do the same for any and every descendant element.
	var i = 0, currentChild = current.childNodes[i];
	while (currentChild != null)
	{
		gpbp_RemoveClassRecursive(currentChild, targetClass, hide_inline);
		i++;
		currentChild = current.childNodes[i];
	}
}