
/**
 * Tippem management class.
 * ---------------------------------------
 * Manages all tip actions within OpenSalon
 * Author: Cash Coleman <ccoleman@salon.com>
 * Created On: Tue May 27, 2008
 * Version: 2.1 (per v2.1 spec)
 * ChangeLog:
 *	+ 5/27/2008: File Created. 
 *  + 8/16/2008: Added code to support the switchout of dojo-0.4.3 with dojo-1.1.1.
 *  + 10/6/2008: Refactored code to support *both* dojo-0.4.3 and dojo-1.1.1 as needed.
 */
function Tippem()
{
	this.__actionUrl = '/tippem/ajax.php';
	this.__actionTimeout = 60;
}



/**
 * Class property to store the URL for the Action Handler.
 */
Tippem.prototype.__actionUrl;

/**
 * Class property to store the default timeout for 
 * all ajax operations before throwing an error.
 */
Tippem.prototype.__actionTimeout;

/**
 * Static property to store ajax responses across 
 * methods, without passing it around by value.
 */
Tippem.__response;

Tippem.sortColumn;
Tippem.sortDirection;
Tippem.currentOffset = 0;
Tippem.currentPage = 1;
Tippem.rowCount;
Tippem.rmxActionType;
Tippem.rmxToken;
Tippem.alertThreshold = 20.00;
Tippem.hasMarkedMoney = false;
Tippem.rmxWindow;
Tippem.payTipsNowVisible = false;
Tippem.context;
Tippem.isError = false;
Tippem.hasPayableTips = false;
Tippem.claimReferenceId;
Tippem.markedItemCount = 0;
Tippem.historyType = 'Paid';


/**
 * Defines the response to the class.
 */
Tippem.prototype.setResponse = function(response)
{
	Tippem.__response = response;
}

/**
 * Returns the current response to the caller.
 */
Tippem.prototype.getResponse = function()
{
	return Tippem.__response;
}

/**
 * Returns the Action Handler for Tippem.
 */
Tippem.prototype.getActionUrl = function()
{
	return this.__actionUrl;
}

/**
 * Returns the default action timeout for Tippem.
 */
Tippem.prototype.getActionTimeout = function()
{
	return this.__actionUrl;
}

/**
 * Deserializes JSON data returned from the server.
 */
Tippem.prototype.evalResponse = function(data)
{
	return eval('(' + data + ')');
}

Tippem.prototype.readCookie = function(name) 
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}


Tippem.prototype.checkTipBalance = function()
{
	var t = new Tippem();
	if (t.readCookie('tippemAlertState') == 'confirmed') 
	{
		return;
	}

	try {

		dojo.io.bind({
			url: this.getActionUrl() + '?action=checkTipBalance',
			handler: this.checkTipBalanceCallback
		});

	} catch (e) {

		dojo.xhrGet ({
			url: this.getActionUrl() + '?action=checkTipBalance',
			load: this.checkTipBalanceCallback,
			handleAs: "text"
		});
	}
}

Tippem.prototype.checkTipBalanceCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	tippem.setResponse(tippem.evalResponse(response));
	if (tippem.getResponse()[0].result == 'SUCCESS' && 
		(tippem.getResponse()[1].balance > Tippem.alertThreshold))
	{
	    Dialog.confirm({
	    	url:"/tippem/tipAlert.php?user=" + tippem.getResponse()[2].user, 
	    	options:{method:'get'}}, 
	    	{width:480, height:'auto', className:"alphacube", 
	    	okLabel:"Pay Tips Now", cancelLabel:"Cancel", 
	        destroyOnClose:true, 
	        zIndex: 99999, recenterAuto:false, 
	        onOk: function() { document.location = '/edit_profile.php?type=tippem'; },
	        cancel: function() { }
	    	});
	}
}

/**
 * Defines the default tip amount for the "tip" button, per 
 * user preference.
 * - Calls back to setDefaultTipAmountCallback() for the ajax response.
 * - Calls back to setDefaultTipAmountError() for error and/or timeout operations.
 */
Tippem.prototype.setDefaultTipAmount = function(amount)
{

	try {

		dojo.io.bind({
			url: this.getActionUrl() + '?action=setDefaultTipAmount',
			handler: setDefaultTipAmountCallback,
			error: setDefaultTipAmountError,
			timeout: this.getActionTimeout()
		});
	} catch (e) {

		dojo.xhrGet ({
			url: this.getActionUrl() + '?action=setDefaultTipAmount',
			handleAs: "text",
			load: setDefaultTipAmountCallback,
			error: setDefaultTipAmountError,
			timeout: this.getActionTimeout()
		});
	}
}

/**
 * Handles the server response from setDefaultTipAmount()
 */
Tippem.prototype.setDefaultTipAmountCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	this.setResponse(tippem.evalResponse(response));
	if (response.result == 'SUCCESS')
	{
		tippem.showMessage('Your tipping preference has been saved.', 'OK', 'info', 'hideMessage()', null, 3000);
	} else {
		tippem.setDefaultTipAmountError(type, data, evt);
	}
}

/**
 * Handles the error response from setDefaultTipAmount(), either via 
 * an exception or timeout operation.
 */
Tippem.prototype.setDefaultTipAmountError = function(type, data, evt) 
{
	tippem.showMessage(this.getResponse().message, 'OK', 'error', 'hideMessage()', null, null);
}

/**
 * Tips a user based on their Id and the article Id, but with a specified amount
 * - Calls back to tipUserCallback() for the ajax response.
 * - Calls back to tipUserError() for error and/or timeout operations.
 */
Tippem.prototype.tipUserMore = function(contentId, authorId)
{
	var amount = dojo.byId('tipBox');
	if (amount.value < .10)
	{
		alert('Please tip in amounts greater or equal to .10 (ten cents).');
		return false;
	}
	if (amount.value > 999.99)
	{
		alert('If you want to tip users in excess of $1,000.00 or more, please contact them directly.');
		return false;
	}

	try {

		dojo.io.bind({
			url: this.getActionUrl() + '?action=tipUserExtended&contentId=' + contentId + '&accountId=' + authorId + '&amount=' + amount.value,
			handler: this.tipUserExtendedCallback,
			error: this.tipUserError,
			timeout: this.getActionTimeout()
		});
	} catch (e) {

		dojo.xhrGet ({
			url: this.getActionUrl() + '?action=tipUserExtended&contentId=' + contentId + '&accountId=' + authorId + '&amount=' + amount.value,
			load: this.tipUserExtendedCallback,
			error: this.tipUserError,
			timeout: this.getActionTimeout()
		});
	}
}


/**
 * Handles the server response from tipUserCallback()
 */
Tippem.prototype.tipUserExtendedCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	tippem.setResponse(tippem.evalResponse(response));
	var tipControls = dojo.byId('tipControls');
	var tipMessage = dojo.byId('tipMessage');
	var tipPayNowBox = dojo.byId('tipPayNowBox');
	if (tippem.getResponse()[0].result == 'SUCCESS')
	{
		tipMessage.innerHTML = "You've tipped $" + tippem.getResponse()[0].amount + "!";
		tipMessage.style.display = 'inline';
		tipControls.style.display = 'none';
		if (!Tippem.payTipsNowVisible && !dojo.byId('payTipsNowButton')) 
		{
			tipPayNowBox.innerHTML += '&nbsp;<input id="payTipsNowButton" class="tippemMiniButton" type="button" ' +
				'onClick="document.location = \'/edit_profile.php?type=tippem\';" value="Pay Tips Now" />';
			Tippem.payTipsNowVisible = true;
		}
	} else {
		if (tippem.getResponse()[0].reason.indexOf('invalid input syntax for type numeric') != -1)
		{
			alert('Please enter a valid dollar amount.');
		}
		else
		{
			alert("We're sorry, but an unknown error has occurred. Please try again later.");
			//tippem.tipUserError(type, data, evt);
		}
	}
}

/**
 * Tips a user based on their Id and the article Id.
 * - Calls back to tipUserCallback() for the ajax response.
 * - Calls back to tipUserError() for error and/or timeout operations.
 */
Tippem.prototype.tipUser = function(contentId, authorId)
{

	try {

		dojo.io.bind({
			url: this.getActionUrl() + '?action=tipUser&contentId=' + contentId + '&accountId=' + authorId,
			handler: this.tipUserCallback,
			error: this.tipUserError,
			timeout: this.getActionTimeout()
		});
	} catch (e) {

		dojo.xhrGet ({
			url: this.getActionUrl() + '?action=tipUser&contentId=' + contentId + '&accountId=' + authorId,
			load: this.tipUserCallback,
			error: this.tipUserError,
			timeout: this.getActionTimeout()
		});
	}
}

/**
 * Handles the server response from tipUserCallback()
 */
Tippem.prototype.tipUserCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	tippem.setResponse(tippem.evalResponse(response));
	var tipLink = dojo.byId('tipLink');
	var tipMoreLink = dojo.byId('tipMoreLink');
	var tipPayNowBox = dojo.byId('tipPayNowBox');
	if (tippem.getResponse()[0].result == 'SUCCESS')
	{
		tipLink.innerHTML = '$' + tippem.getResponse()[0].amount;
		tipMoreLink.style.display = 'inline';
		if (!Tippem.payTipsNowVisible && !dojo.byId('payTipsNowButton')) 
		{
			tipPayNowBox.innerHTML += '&nbsp;<input id="payTipsNowButton" class="tippemMiniButton" type="button" ' +
				'onClick="document.location = \'/edit_profile.php?type=tippem\';" value="Pay Tips Now" />';
			Tippem.payTipsNowVisible = true;
		}
	
	} else {
		tippem.tipUserError(type, data, evt);
	}
}

/**
 * Handles the error response from tipUser(), either via 
 * an exception or timeout operation.
 */
Tippem.prototype.tipUserError = function(type, data, evt)
{
	var tippem = new Tippem();
	alert(tippem.getResponse()[0].reason);
	//tippem.showMessage(this.getResponse().message, 'OK', 'error', 'hideMessage()', null, null);
}

Tippem.prototype.checkBrowserCompat = function()
{
	var type = navigator.userAgent.toLowerCase();
	if (type.indexOf('version/3.1') != -1)
	{
		Dialog.confirm({
			url:"/tippem/browserAlert.php", 
			options:{method:'get'}}, 
			{width:480, height:'auto', className:"alphacube", 
			okLabel:"Return to Tips", cancelLabel:"Cancel", 
		    destroyOnClose:true, 
		    zIndex: 99999, recenterAuto:false, 
		    onOk: function() { Dialog.cancelCallback(); },
		    cancel: function() { }
			});
		return false;
	} 
	
//	if (type.indexOf('firefox/3') != -1)
//	{
//		Dialog.confirm({
//			url:"/tippem/browserAlert.php", 
//			options:{method:'get'}}, 
//			{width:480, height:'auto', className:"alphacube", 
//			okLabel:"Return to Tips", cancelLabel:"Cancel", 
//		    destroyOnClose:true, 
//		    zIndex: 99999, recenterAuto:false, 
//		    onOk: function() { Dialog.cancelCallback(); },
//		    cancel: function() { }
//			});
//		return false;
//	}
	return true;
}

Tippem.prototype.showRmxWindow = function(actionType)
{
//	if (!this.checkBrowserCompat())
//	{
//		return;
//	}
	if (actionType == null || actionType == '')
	{
		switch(Tippem.context)
		{
			case 'pay':
				actionType = 'sendMoney';
				break;
			case 'claim':
				actionType = 'accept';
				break;
			case 'register':
				actionType = 'register';
				break;
			case 'bind':
				actionType = 'bind';
				break;
			default:
				actionType = 'sendMoney';
				break;
		}
	}
	
	Tippem.rmxActionType = actionType;
    Tippem.rmxWindow = Dialog.alert({url:"/tippem/rmx.php?actionType=" + actionType},
                                    {className: "alphacube", top:5, width:540, height: 700, 
                                     buttonClass:"alphacube_tippem_buttons", destroyOnClose:true, 
                                     zIndex: 99999, recenterAuto:false,
                                     okLabel: "Cancel and return to Open Salon", 
                                     onOk: function() { document.location = '/edit_profile.php?type=tippem'; }});

	var t = new Tippem();
 	t.startRmx();
}

Tippem.prototype.startRmx = function()
{
	switch(Tippem.rmxActionType)
	{
		case 'pay':
			try {
				dojo.io.bind({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType,
					handler: this.startRmxCallback
				});
			} catch (e) {
				dojo.xhrGet ({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType,
					load: this.startRmxCallback,
					handleAs: "text"
				});
			}
			break;
		case 'accept':
			try {
				dojo.io.bind({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType + '&referenceId=' + Tippem.claimReferenceId,
					handler: this.startRmxCallback
				});
			} catch (e) {
				dojo.xhrGet ({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType + '&referenceId=' + Tippem.claimReferenceId,
					load: this.startRmxCallback,
					handleAs: "text"
				});
			}
			break;
		default:
			try {
				dojo.io.bind({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType,
					handler: this.startRmxCallback
				});
			} catch (e) {
				dojo.xhrGet ({
					url: this.getActionUrl() + '?action=startRmx&actionType=' + Tippem.rmxActionType,
					load: this.startRmxCallback,
					handleAs: "text"
				});
			}
			break;
	}

}

Tippem.prototype.startRmxCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	var rmxdata;
	var lineItems;
	var rmxIFrame = dojo.byId('RevolutionMoneyIFrame');
	rmxIFrame.style.display = 'inline';

	tippem.setResponse(tippem.evalResponse(response));

	if (tippem.getResponse()[0].result == 'SUCCESS')
	{
		if (Tippem.rmxActionType == 'bind' || Tippem.rmxActionType == 'register')
		{
			rmxdata = {
				"action": Tippem.rmxActionType,
				"from":tippem.getResponse()[2].from,
				"context":"salon",
				"reference":"salon1",
				"hash":tippem.getResponse()[3].hash,
				"timestamp":tippem.getResponse()[1].timestamp
			};
		}
		else
		{
			rmxdata = {
				"action": Tippem.rmxActionType,
				"from":tippem.getResponse()[2].from,
				"context":"salon",
				"reference":"salon1",
				"hash":tippem.getResponse()[4].hash,
				"timestamp":tippem.getResponse()[1].timestamp,
				"line_items":tippem.getResponse()[3].items
			};
		}
		setRevolutionMoneyFrame(rmxdata);
	}
	else
	{
		alert(tippem.getResponse()[0].reason);
	}
}

function confirmCommit(confirmToken)
{
	var t = new Tippem();
	switch(Tippem.rmxActionType)
	{
		case 'bind':
			try {
				dojo.io.bind({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=bind&debug=on',
					handler: Tippem.ProcessRmeXmlResponse
				});
			} catch (e) {
				dojo.xhrGet ({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=bind&debug=on',
					load: Tippem.ProcessRmeXmlResponse,
					handleAs: "text"
				});
			}
			break;
		case 'register':
			try {
				dojo.io.bind({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=register&debug=on',
					handler: Tippem.ProcessRmeXmlResponse
				});
			} catch (e) {
				dojo.xhrGet ({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=register&debug=on',
					load: Tippem.ProcessRmeXmlResponse,
					handleAs: "text"
				});
			}
			break;
		case 'sendMoney':
			try {
				dojo.io.bind({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=sendMoney&debug=on',
					handler: Tippem.ProcessRmeXmlResponse
				});
			} catch (e) {
				dojo.xhrGet ({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=sendMoney&debug=on',
					load: Tippem.ProcessRmeXmlResponse,
					handleAs: "text"
				});
			}
			break;
		case 'accept':
			try {
				dojo.io.bind({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=accept&debug=on',
					handler: Tippem.ProcessRmeXmlResponse
				});
			} catch (e) {
				dojo.xhrGet ({
					url: t.getActionUrl() + '?action=processRmeRequest&token=' + confirmToken + '&context=accept&debug=on',
					load: Tippem.ProcessRmeXmlResponse,
					handleAs: "text"
				});
			}
			break;
	}
}
 
function commitResult(vSuccess)
{
    alert("commit result:" + vSuccess);
}

Tippem.ProcessRmeXmlResponse = function(response, ioArgs) 
{
	var tippem = new Tippem();
	var button = dojo.byId('tippemPayTipsButton');
	var heading = dojo.byId('tippemHeading');
	
	tippem.setResponse(tippem.evalResponse(response));
	if (tippem.getResponse().result == 'SUCCESS')
	{
		
		switch(Tippem.rmxActionType)
		{
			case 'bind':
				tippem.initialize();
				if (Tippem.hasPayableTips)
				{
					button.style.display = 'inline';
				}
				heading.style.display = 'none';
				tippem.showBindWindow();
				break;
			case 'register':
				if (Tippem.hasPayableTips)
				{
					button.style.display = 'inline';
				}
				heading.style.display = 'none';
				tippem.showRegisterWindow();
				break;
			case 'sendMoney':
				tippem.clearCancelledTransactions();
				tippem.showSendMoneyWindow();
				break;
			case 'accept':
				tippem.showAcceptWindow();
				break;
		}
	}
	else
	{
		tippem.showErrorWindow();
	}

}

Tippem.prototype.clearCancelledTransactions = function()
{
	try {
		dojo.io.bind({
			url: this.getActionUrl() + '?action=processCancelledTips',
			handler: this.clearCancelledTransactionsCallback
		});
	} catch (e) {
		dojo.xhrGet ({
			url: this.getActionUrl() + '?action=processCancelledTips',
			load: this.clearCancelledTransactionsCallback,
			handleAs: "text"
		});
	}
}

Tippem.prototype.clearCancelledTransactionsCallback = function(response, ioArgs)
{
	var t = new Tippem();
	t.setResponse(t.evalResponse(response));
	if (t.getResponse()[0].result == 'SUCCESS')
	{
		Tippem.isError = false;
	}
	else
	{
		Tippem.isError = true;
	}
}

Tippem.prototype.showAcceptWindow = function()
{
	var rmxFrame = dojo.byId('RevolutionMoneyIFrame');
	var window = dojo.byId('tippemWindow');
	var heading = dojo.byId('tippemFrameHeading');
	var page = dojo.byId('tippemPage');
	var line = '';
	var isPartial = false;
	var i = 0;
	
	rmxFrame.style.display = 'none';
	window.style.display = 'inline';
	
	for(i=0; i<this.getResponse().lineItems.length; i++)
	{
		if (this.getResponse().lineItems[i].result == 'FAILURE')
		{
			isPartial = true;
			break;
		}
	}
	
	if (!isPartial && this.getResponse().rmeResult == 'SUCCESS')
	{
		heading.innerHTML = 'Congratulations!';
		page.innerHTML = '<p>The following tips were successfully accepted:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(var i=0; i<this.getResponse().lineItems.length; i++)
		{
			line = '<div class="tippemLineItem">';
			line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].username + '</div>';
			line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
			line += '	<div class="cleardiv"></div>';
			line += '</div>';
			page.innerHTML += line;
		}
		page.innerHTML += '<p>You can see your transaction history at any time, by viewing your Tippem history tab.</p>';
		page.innerHTML += '<p style="text-align: center;">';
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
	else if (isPartial && this.getResponse().rmeResult == 'SUCCESS')
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>The following tips were <strong>not processed successfully</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			if (this.getResponse().lineItems[i].result == 'FAILURE')
			{
				line = '<div class="tippemLineItem">';
				line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].username + '</div>';
				line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
				line += '	<div class="cleardiv"></div>';
				line += '</div>';
			}
			page.innerHTML += line;
		}
		page.innerHTML += '<p>These tips will remain on your balance sheet and you can try accepting them at a later time.</p>';
		
		page.innerHTML += '<p>The following tips were processed successfully:</p>';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			if (this.getResponse().lineItems[i].result == 'SUCCESS')
			{
				line = '<div class="tippemLineItem">';
				line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].username + '</div>';
				line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
				line += '	<div class="cleardiv"></div>';
				line += '</div>';
			}
			page.innerHTML += line;
		}
		
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
	else if (this.getResponse().rmeResult == 'FAILURE')
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>The following tips were <strong>not processed successfully</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			line = '<div class="tippemLineItem">';
			line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].username + '</div>';
			line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
			line += '	<div class="cleardiv"></div>';
			line += '</div>';
			page.innerHTML += line;
		}
		page.innerHTML += '<p>These tips will remain on your balance sheet and you can try accepting them at a later time.</p>';
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
	else
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>A system error has occurred</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		page.innerHTML += '<p>The tips you selected will remain on your balance sheet and you can try accepting them at a later time</p>';
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
}

Tippem.prototype.showSendMoneyWindow = function()
{
	var rmxFrame = dojo.byId('RevolutionMoneyIFrame');
	var window = dojo.byId('tippemWindow');
	var heading = dojo.byId('tippemFrameHeading');
	var page = dojo.byId('tippemPage');
	var line = '';
	var isPartial = false;
	var i = 0;
	
	rmxFrame.style.display = 'none';
	window.style.display = 'inline';
	
	for(i=0; i<this.getResponse().lineItems.length; i++)
	{
		if (this.getResponse().lineItems[i].result == 'FAILURE')
		{
			isPartial = true;
			break;
		}
	}
	
	if (!isPartial && this.getResponse().rmeResult == 'SUCCESS')
	{
		heading.innerHTML = 'Congratulations!';
		page.innerHTML = '<p>You have successfully tipped the following users:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(var i=0; i<this.getResponse().lineItems.length; i++)
		{
			line = '<div class="tippemLineItem">';
			line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].author + '</div>';
			line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
			line += '	<div class="cleardiv"></div>';
			line += '</div>';
			page.innerHTML += line;
		}
		page.innerHTML += '<p>These users have automatically been notified that they have received tips.</p>';
		page.innerHTML += '<p>You can see your transaction history at any time, by viewing your Tippem history tab.</p>';
	}
	else if (isPartial && this.getResponse().rmeResult == 'SUCCESS')
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>The following tips were <strong>not processed successfully</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			if (this.getResponse().lineItems[i].result == 'FAILURE')
			{
				line = '<div class="tippemLineItem">';
				line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].author + '</div>';
				line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
				line += '	<div class="cleardiv"></div>';
				line += '</div>';
			}
			page.innerHTML += line;
		}
		page.innerHTML += '<p>These tips will remain on your balance sheet and you can try paying them at a later time.</p>';
		
		page.innerHTML += '<p>The following tips were processed successfully:</p>';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			if (this.getResponse().lineItems[i].result == 'SUCCESS')
			{
				line = '<div class="tippemLineItem">';
				line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].author + '</div>';
				line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
				line += '	<div class="cleardiv"></div>';
				line += '</div>';
			}
			page.innerHTML += line;
		}
		
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
	else if (this.getResponse().rmeResult == 'FAILURE')
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>The following tips were <strong>not processed successfully</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		for(i=0; i<this.getResponse().lineItems.length; i++)
		{
			line = '<div class="tippemLineItem">';
			line += '	<div class="user tippemLeft">' + this.getResponse().lineItems[i].author + '</div>';
			line += '	<div class="amount tippemRight">$' + this.getResponse().lineItems[i].total + '</div>';
			line += '	<div class="cleardiv"></div>';
			line += '</div>';
			page.innerHTML += line;
		}
		page.innerHTML += '<p>These tips will remain on your balance sheet and you can try paying them at a later time.</p>';
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
	else
	{
		heading.innerHTML = '<span class="warning">Notice!</span>';
		page.innerHTML = '<p>A system error has occurred</strong>:</p>';
		page.innerHTML += '<hr style="height: 1px" />';
		page.innerHTML += '<p>The tips you selected will remain on your balance sheet and you can try paying them at a later time</p>';
		page.innerHTML += '<p>If you have any questions, please <a href="/message.php">contact Open Salon Support</a>.';
		page.innerHTML += '<p style="text-align: center;">'
		page.innerHTML += '<a href="/edit_profile.php?type=tippem" target="_top">Return to Open Salon</a></p>';
	}
}

Tippem.prototype.showRegisterWindow = function()
{
	var rmxFrame = dojo.byId('RevolutionMoneyIFrame');
	rmxFrame.src = '/tippem/register.php?result=' + this.getResponse().rmeResult;
}

Tippem.prototype.showBindWindow = function()
{
	var rmxFrame = dojo.byId('RevolutionMoneyIFrame');
	rmxFrame.src = '/tippem/bind.php?result=' + this.getResponse().rmeResult;

}

Tippem.prototype.showErrorWindow = function()
{
	var rmxFrame = dojo.byId('RevolutionMoneyIFrame');
	rmxFrame.src = '/tippem/error.php?message=' + this.getResponse().rmeDetail + '&type=' + Tippem.rmxActionType;
}

function sortColumn(column)
{
	var t = new Tippem();
	Tippem.clearSort();
	var frame = dojo.byId('historyFrame');
	var suffix = '?sortBy='
	
	if (Tippem.sortDirection == 'up') {
		column.innerHTML = '<div class="tippemSortImage"><img src="/Themes/OpenSalon/images/tippem/sort_down.png"></div>';
		Tippem.sortDirection = 'down';
	} else {
		column.innerHTML = '<div class="tippemSortImage"><img src="/Themes/OpenSalon/images/tippem/sort_up.png"></div>';
		Tippem.sortDirection = 'up';
	}
	
	switch(column.id) 
	{
		case 'date':
			Tippem.sortColumn = 'create_time';
			column.innerHTML += ' Date';
			break;
		case 'ptitle':
			Tippem.sortColumn = 'title';
			column.innerHTML += ' Title';
			break;
		case 'author':
			Tippem.sortColumn = 'author';
			column.innerHTML += ' Author';
			break;
		case 'amount':
			Tippem.sortColumn = 'value';
			column.innerHTML += ' Amount';
			break;
		case 'user':
			Tippem.sortColumn = 'user_id';
			column.innerHTML += ' User';
			break;
		case 'receiveDate':
			Tippem.sortColumn = 'lastupdate_time';
			column.innerHTML += ' Received';
			break;
		default:
			Tippem.sortColumn = '';
			suffix = '';
			break;
	}
	
	suffix += Tippem.sortColumn;
	
	var sortOrder = 'DESC';
	if (Tippem.sortDirection == 'down')
	{
		sortOrder = '';
	}
	t.showTransition();
	t.loadTippemTransactions(suffix, sortOrder);
}

Tippem.clearSort = function()
{
	var date = dojo.byId('date');
	var title = dojo.byId('ptitle');
	var author = dojo.byId('author');
	var amount = dojo.byId('amount');
	var user = dojo.byId('user');
	var receiveDate = dojo.byId('receiveDate');
	
	date.innerHTML = 'Date';
	title.innerHTML = 'Title';
	author.innerHTML = 'Author';
	amount.innerHTML = 'Amount';
	user.innerHTML = 'User';
	receiveDate.innerHTML = 'Received';
}

Tippem.prototype.firstPage = function(context, suffix, order)
{
	Tippem.currentPage = 1;
	Tippem.currentOffset = 0;
	var t = new Tippem();
	t.showTransition(null);
	if (context == 'pay')
	{
		t.loadTippemTransactions(suffix, order);
		return;
	}
	t.loadClaimableTips(suffix, order);
}

Tippem.prototype.lastPage = function(context, suffix, order)
{
	var maxPages = (Tippem.rowCount / 10);
	Tippem.currentPage = maxPages;
	for(var i=1; i<maxPages; i++)
	{
		Tippem.currentOffset = (Tippem.currentOffset + 10);
	}
	var t = new Tippem();
	t.showTransition(null);
	if (context == 'pay')
	{
		t.loadTippemTransactions(suffix, order);
		return;
	}
	t.loadClaimableTips(suffix, order);
}

Tippem.prototype.previousPage = function(context, suffix, order)
{
	Tippem.currentPage = (Tippem.currentPage - 1);
	Tippem.currentOffset = (Tippem.currentOffset - 10);
	var t = new Tippem();
	t.showTransition(null);
	if (context == 'pay')
	{
		t.loadTippemTransactions(suffix, order);
		return;
	}
	t.loadClaimableTips(suffix, order);
}

Tippem.prototype.nextPage = function(context, suffix, order)
{
	Tippem.currentPage = (Tippem.currentPage + 1);
	Tippem.currentOffset = (Tippem.currentOffset + 10);
	var t = new Tippem();
	t.showTransition(null);
	if (context == 'pay')
	{
		t.loadTippemTransactions(suffix, order);
		return;
	}
	t.loadClaimableTips(suffix, order);
}

Tippem.prototype.showTransition = function(message)
{
	var status = dojo.byId('tippemPageStatus');
	var msg = '<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/nav_refresh_green.png" /></div>' +
		'<span class="statusMessage">Loading, one moment...</span><div class="cleardiv"></div>';

	if (!message)
	{
		if (Tippem.isError)
		{
			msg = '<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/cornerIcons/warning.png" /></div>' +
			'<span class="statusMessage">An unknown error has occurred. We apologize for the inconvenience.</span><div class="cleardiv"></div>';
		}
		Tippem.isError = false;
		status.innerHTML = msg;
		return;
	}

	if (Tippem.isError)
	{
		msg = '<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/cornerIcons/warning.png" /></div>' +
			'<span class="statusMessage">' + message + '</span><div class="cleardiv"></div>';
		Tippem.isError = false;
		status.innerHTML = msg;
		return;
	}
	status.innerHTML = message;
}

Tippem.prototype.initialize = function()
{
	this.showTransition();
	if (Tippem.context == null) { Tippem.context = 'pay'; }
	
	
	
	switch(Tippem.context)
	{
		case 'pay':
			
			dojo.byId('tippemColumnUser').style.display = 'none';
			this.loadTippemTransactions('?sortBy=create_time', 'DESC');
			break;
		case 'claim':

			this.loadTippemTransactions('?sortBy=user_id', 'DESC');
			break;
		case 'history':
			dojo.byId('tippemPayTipsButton').style.display = 'none';
			dojo.byId('tippemColumnUser').style.display = 'none';
			this.loadTippemTransactions('?sortBy=title', 'DESC');
			break;
	}
}

Tippem.prototype.loadTippemTransactions = function(suffix, order)
{
	Tippem.hasPayableTips = false;
	switch(Tippem.context)
	{
		case 'pay':
			try {
				dojo.io.bind({
					url: this.getActionUrl() + suffix + '&action=getPayables&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
					handler: this.loadTippemTransactionsCallback
				});
			} catch (e) {
				dojo.xhrGet({
					url: this.getActionUrl() + suffix + '&action=getPayables&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
					handleAs: "text",
					timeout: 30000,
					load: this.loadTippemTransactionsCallback
				});
			}
			break;
		case 'claim':
			try {
				dojo.io.bind({
					url: this.getActionUrl() + suffix + '&action=getClaimables&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
					handler: this.loadTippemClaimsCallback
				});
			} catch (e) {
				dojo.xhrGet({
	            	url: this.getActionUrl() + suffix + '&action=getClaimables&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
					handleAs: "text",
	                timeout: 30000,
	                load: this.loadTippemClaimsCallback
	            });
			}
			break;
		case 'history':
			switch(Tippem.historyType)
			{
				case 'Paid':
					try {
						dojo.io.bind({
							url: this.getActionUrl() + suffix + '&action=getPaidHistory&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
							handler: this.loadTippemHistoryCallback
						});
					} catch (e) {
						dojo.xhrGet({
							url: this.getActionUrl() + suffix + '&action=getPaidHistory&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
							handleAs: "text",
							timeout: 30000,
							load: this.loadTippemHistoryCallback
						});
					}
					break;
				case 'Accepted':
					try {
						dojo.io.bind({
							url: this.getActionUrl() + suffix + '&action=getAcceptedHistory&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
							handler: this.loadTippemHistoryCallback
						});
					} catch (e) {
						dojo.xhrGet({
							url: this.getActionUrl() + suffix + '&action=getAcceptedHistory&offset=' + Tippem.currentOffset + '&sortOrder=' + order,
                            handleAs: "text",
                        	timeout: 30000,
                            load: this.loadTippemHistoryCallback
                        });
					}
					break;
				default:
					alert('[loadTippemTransactions]: Invalid historyType parameter, "' + Tippem.historyType + "'");
					break;
			}

			break;
	}
}

Tippem.prototype.loadTippemClaimsCallback = function(response, ioArgs)
{
	Tippem.markedItemCount = 0;
	var queue = dojo.byId('transactionQueue');
	var nav = dojo.byId('tippemPageNavigation');
	var button = dojo.byId('tippemPayTipsButton');
	queue.innerHTML = '';
	var tippem = new Tippem();
	var line = '';
	var alternate = true;
	tippem.setResponse(tippem.evalResponse(response));
	
	if (tippem.getResponse()[0].result == 'FAILURE')
	{
		Tippem.isError = true;
		tippem.showTransition('An error has occurred. We apologize for the inconvenience.');
		return;
	}
	
	tippem.updateBalanceTotal(tippem.getResponse()[2].approvedTotal, tippem.getResponse()[3].amountPledged);
	
	var rowCount = tippem.getResponse()[1].rowCount;
	var pages = (rowCount / 10);
	Tippem.rowCount = rowCount;
	
	var order = 'DESC';
	if (Tippem.sortDirection == 'down')
	{
		order = '';
	}
	
	var fastBackNav = '<a href="#top" onClick="var t = new Tippem(); t.firstPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="First Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" /></a>';
	
	var fastForwardNav = '<a href="#top" onClick="var t = new Tippem(); t.lastPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Last Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" /></a>';
		
	var backwardNav = '<a href="#top" onClick="var t = new Tippem(); t.previousPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Previous Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left.png" /></a>';
	
	var forwardNav = '<a href="#top" onClick="var t = new Tippem(); t.nextPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Next Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right.png" /></a>';
		
	if (Tippem.currentPage <= 1) 
	{
		fastBackNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" title="Currently at the beginning of the ledger" />';
		backwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left.png" title="Currently at the beginning of the ledger" />';
	}
	
	if (Tippem.currentPage >= pages)
	{
		forwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right.png" title="Currently at the end of the ledger" />';
		fastForwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" title="Currently at the end of the ledger" />'
	}
	nav.innerHTML = fastBackNav + ' ' + backwardNav + ' ' + forwardNav + ' ' + fastForwardNav;
	for (var i=4; i<tippem.getResponse().length; i++)
	{

		if (tippem.getResponse()[i].marker == 'CLAIM_READY')
		{
			Tippem.claimReferenceId = tippem.getResponse()[i].referenceId;
			line = '<div class="tippemTransactionLineSelected" id="tip_' + tippem.getResponse()[i].referenceId + '">';
			button.style.display = 'inline';
			Tippem.markedItemCount++;
		}
		else
		{
			line = '<div class="tippemTransactionLine" id="tip_' + tippem.getResponse()[i].referenceId + '">';
		}

		line += '	<div class="tippemColumn user" title="' + tippem.getResponse()[i].referenceId + '">' + tippem.getResponse()[i].username + '</div>';
		line += '	<div class="tippemColumn receiveDate">' + tippem.getResponse()[i].lastUpdateTs + '</div>';
		line += '	<div class="tippemColumn amount">$' + tippem.getResponse()[i].value + '</div>';
		line += '	<div class="tippemColumn pay">';
		line += '		<a class="tippemCashLink" title="Click to add this tip" id="tip_cash_' + tippem.getResponse()[i].referenceId + '"';
		line += ' 			onClick="var t = new Tippem(); t.togglePayField(\'tip_' + tippem.getResponse()[i].referenceId + '\', \'claim\');"/>';
		line += '			<img src="/Themes/OpenSalon/images/tippem/money2_add.png"/>';
		line += '		</a>';
		line += '	</div>';
		line += '</div>';
		queue.innerHTML += line;
	}
	tippem.displayResultStatus();
}

Tippem.prototype.loadTippemHistoryCallback = function(response, ioArgs)
{
	var queue = dojo.byId('transactionQueue');
	var nav = dojo.byId('tippemPageNavigation');
	queue.innerHTML = '';
	var tippem = new Tippem();
	var line = '';
	var alternate = true;
	tippem.setResponse(tippem.evalResponse(response));
	
	if (tippem.getResponse()[0].result == 'FAILURE')
	{
		Tippem.isError = true;
		tippem.showTransition('An error has occurred. We apologize for the inconvenience.');
		return;
	}
	
	tippem.updateBalanceTotal(tippem.getResponse()[2].approvedTotal, tippem.getResponse()[3].amountPledged);
	
	var rowCount = tippem.getResponse()[1].rowCount;
	var pages = (rowCount / 10);
	Tippem.rowCount = rowCount;
	
	var order = 'DESC';
	if (Tippem.sortDirection == 'down')
	{
		order = '';
	}
	
	var fastBackNav = '<a href="#top" onClick="var t = new Tippem(); t.firstPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="First Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" /></a>';
	
	var fastForwardNav = '<a href="#top" onClick="var t = new Tippem(); t.lastPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Last Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" /></a>';
		
	var backwardNav = '<a href="#top" onClick="var t = new Tippem(); t.previousPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Previous Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left.png" /></a>';
	
	var forwardNav = '<a href="#top" onClick="var t = new Tippem(); t.nextPage(\'claim\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Next Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right.png" /></a>';
		
	if (Tippem.currentPage <= 1) 
	{
		fastBackNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" title="Currently at the beginning of the ledger" />';
		backwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left.png" title="Currently at the beginning of the ledger" />';
	}
	
	if (Tippem.currentPage >= pages)
	{
		forwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right.png" title="Currently at the end of the ledger" />';
		fastForwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" title="Currently at the end of the ledger" />'
	}
	nav.innerHTML = fastBackNav + ' ' + backwardNav + ' ' + forwardNav + ' ' + fastForwardNav;
	for (var i=4; i<tippem.getResponse().length; i++)
	{
		var title = tippem.getResponse()[i].title;
		if (title.length > 80)
		{
			title = title.substr(0, 80) + '...';
		}
		line = '<div class="tippemTransactionLine">';
		line += '	<div class="tippemColumn title titleHistory" title="' + tippem.getResponse()[i].title + '">' + title + '</div>';
		line += '	<div class="tippemColumn amount">$' + tippem.getResponse()[i].value + '</div>';
		line += '</div>';
		queue.innerHTML += line;
	}
	tippem.displayResultStatus();
}

Tippem.prototype.loadTippemTransactionsCallback = function(response, ioArgs)
{
	Tippem.markedItemCount = 0;
	var queue = dojo.byId('transactionQueue');
	var nav = dojo.byId('tippemPageNavigation');
	var button = dojo.byId('tippemPayTipsButton');
	
	// Disable the multi-button by default...
	button.style.display = 'none';
	
	queue.innerHTML = '';
	var tippem = new Tippem();
	var line = '';
	var alternate = true;
	tippem.setResponse(tippem.evalResponse(response));
	
	if (tippem.getResponse()[0].result == 'FAILURE')
	{
		Tippem.isError = true;
		tippem.showTransition('An error has occurred. We apologize for the inconvenience.');
		return;
	}
	
	tippem.updateBalanceTotal(tippem.getResponse()[2].approvedTotal, tippem.getResponse()[3].amountPledged);
	
	var rowCount = tippem.getResponse()[1].rowCount;
	var pages = (rowCount / 10);
	Tippem.rowCount = rowCount;
	
	var order = 'DESC';
	if (Tippem.sortDirection == 'down')
	{
		order = '';
	}
	
	var fastBackNav = '<a href="#top" onClick="var t = new Tippem(); t.firstPage(\'pay\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="First Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" /></a>';
	
	var fastForwardNav = '<a href="#top" onClick="var t = new Tippem(); t.lastPage(\'pay\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Last Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" /></a>';
		
	var backwardNav = '<a href="#top" onClick="var t = new Tippem(); t.previousPage(\'pay\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Previous Page"><img src="/Themes/OpenSalon/images/tippem/navigate_left.png" /></a>';
	
	var forwardNav = '<a href="#top" onClick="var t = new Tippem(); t.nextPage(\'pay\', \'?sortBy=' + 
		Tippem.sortColumn + '\',\'' + order + '\');" title="Next Page"><img src="/Themes/OpenSalon/images/tippem/navigate_right.png" /></a>';
		
	if (Tippem.currentPage <= 1) 
	{
		fastBackNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left2.png" title="Currently at the beginning of the ledger" />';
		backwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_left.png" title="Currently at the beginning of the ledger" />';
	}
	
	if (Tippem.currentPage >= pages)
	{
		forwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right.png" title="Currently at the end of the ledger" />';
		fastForwardNav = '<img src="/Themes/OpenSalon/images/tippem/navigate_right2.png" title="Currently at the end of the ledger" />'
	}
	nav.innerHTML = fastBackNav + ' ' + backwardNav + ' ' + forwardNav + ' ' + fastForwardNav;
	
	for (var i=4; i<tippem.getResponse().length; i++)
	{
		
		if (tippem.getResponse()[i].restricted == 'FALSE')
		{
			Tippem.hasPayableTips = true;
		}
		
		if (i == (tippem.getResponse().length - 1))
		{
			if (tippem.getResponse()[i].marker == 'PAY_READY')
			{
				Tippem.markedItemCount++;
				button.style.display = 'inline';
				button.value = 'Complete Payment Now';
				line = '<div class="tippemTransactionLineSelected" id="tip_' + tippem.getResponse()[i].id + '">';
			}
			else if (tippem.getResponse()[i].marker == 'CANCELLED')
			{
				line = '<div class="tippemTransactionCancelled" id="tip_' + tippem.getResponse()[i].id + '">';
			}
			else 
			{
				line = '<div class="tippemTransactionLineEnd" id="tip_' + tippem.getResponse()[i].id + '">';
			}
		} 
		else
		{
			if (tippem.getResponse()[i].marker == 'PAY_READY')
			{
				Tippem.hasMarkedMoney = true;
				Tippem.markedItemCount++;
				button.style.display = 'inline';
				button.value = 'Complete Payment Now';
				line = '<div class="tippemTransactionLineSelected" id="tip_' + tippem.getResponse()[i].id + '">';
			}
			else if (tippem.getResponse()[i].marker == 'CANCELLED')
			{
				line = '<div class="tippemTransactionCancelled" id="tip_' + tippem.getResponse()[i].id + '">';
			}
			else 
			{
				line = '<div class="tippemTransactionLine" id="tip_' + tippem.getResponse()[i].id + '">';
			}
		}
		
		var title = tippem.getResponse()[i].title;
		if (title.length > 20)
		{
			title = title.substr(0, 20) + '...';
		}
		
		var author = tippem.getResponse()[i].author;
		if (author.length > 11)
		{
			author = author.substr(0, 11) + '...';
		}
		
		line += '	<div class="tippemColumn date">' + tippem.getResponse()[i].createTs + '</div>';
		if (tippem.getResponse()[i].restricted == 'TRUE')
		{
			line += '	<div class="tippemColumn title restricted"><a class="restricted" href="/content.php?cid=' + tippem.getResponse()[i].contentId + '" ';
			line += ' 		title="' + tippem.getResponse()[i].title + '">' + title + '</a>';
			line += '	</div>';
		}
		else
		{
			line += '	<div class="tippemColumn title"><a href="/content.php?cid=' + tippem.getResponse()[i].contentId + '" ';
			line += ' 		title="' + tippem.getResponse()[i].title + '">' + title + '</a>';
			line += '	</div>';
		}
		
		if (tippem.getResponse()[i].restricted == 'TRUE')
		{
			line += '	<div class="tippemColumn author restricted"><a class="restricted" href="/user_blog.php?uid=' + tippem.getResponse()[i].accountId + '"';
			line += ' 		title="Go to ' + tippem.getResponse()[i].author + '\'s blog">' + author + '</a>';
			line += '	</div>';
		}
		else
		{
			line += '	<div class="tippemColumn author"><a href="/user_blog.php?uid=' + tippem.getResponse()[i].accountId + '"';
			line += ' 		title="Go to ' + tippem.getResponse()[i].author + '\'s blog">' + author + '</a>';
			line += '	</div>';
		}

		line += '	<div class="tippemColumn amount">$' + tippem.getResponse()[i].value + '</div>';
		line += '	<div class="tippemColumn pay">';
		
		if (tippem.getResponse()[i].restricted == 'TRUE')
		{
			
			line += '		<a class="tippemCashLink" href="#" onClick="var t = new Tippem(); t.showSignupRequestHelp(\'' + tippem.getResponse()[i].author + '\');">';
			line += '			<img src="/Themes/OpenSalon/images/tippem/help.png" ';
			line += '			title="' + tippem.getResponse()[i].author + ' has been asked to sign up for Revolution Money Exchange"/>';
			line += '		</a>';
		}
		else
		{
			line += '		<a class="tippemCashLink" title="Click to add this tip" id="tip_cash_' + tippem.getResponse()[i].id + '"';
			line += ' 			onClick="var t = new Tippem(); t.togglePayField(\'tip_' + tippem.getResponse()[i].id + '\', \'pay\');"/>';
			line += '			<img src="/Themes/OpenSalon/images/tippem/money2_add.png"/>';
			line += '		</a>';
		}
		
		line += '	</div>';
		line += '	<div class="tippemColumn delete">';
		line += '		<a class="tippemCashLink" title="Click to cancel this tip" id="tip_cancel_' + tippem.getResponse()[i].id + '"';
		line += ' 			onClick="var t = new Tippem(); t.togglePayField(\'tip_' + tippem.getResponse()[i].id + '\', \'cancel\');"/>';
		line += '			<img src="/Themes/OpenSalon/images/tippem/money2_delete.png"/>';
		line += '		</a>';
		line += '	</div>';
		line += '	<div class="cleardiv"></div>';
		line += "</div>\n";
		queue.innerHTML += line;

	}
	tippem.displayResultStatus();
}


Tippem.prototype.displayResultStatus = function()
{
	var status = dojo.byId('tippemPageStatus');
	var pageRowsTotal;
	if (Tippem.rowCount == 0)
	{
		status.innerHTML = '<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/cornerIcons/information.png" /></div>';
		switch(Tippem.context)
		{
			case 'pay':
				status.innerHTML += '<span class="statusMessage">You have no tips to display.</span><div class="cleardiv"></div>';
				break;
			case 'claim':
				status.innerHTML += '<span class="statusMessage">You have no tips to accept.</span><div class="cleardiv"></div>';
				break;
			case 'history':
				switch(Tippem.historyType)
				{
					case 'Paid':
						status.innerHTML += '<span class="statusMessage">No tips have been paid yet.</span><div class="cleardiv"></div>';
						break;
					case 'Accepted':
						status.innerHTML += '<span class="statusMessage">No tips have been accepted yet.</span><div class="cleardiv"></div>';
						break;
					default:
						alert('[displayResultStatus]: Invalid historyType "' + Tippem.historyType + '" was set prior to status update.');
						break;
				}
				break;
		}
		return;
	}
	if ((Tippem.currentOffset + 10) > Tippem.rowCount)
	{
		pageRowsTotal = Tippem.rowCount;
	} 
	else
	{
		pageRowsTotal = (Tippem.currentOffset + 10);
	}
	
	status.innerHTML = 'Displaying ' + (Tippem.currentOffset + 1) + ' - ' + pageRowsTotal + ' of ' + Tippem.rowCount + ' items.';

}

Tippem.prototype.togglePayField = function(payField, option)
{
	var payLine = dojo.byId(payField);
	var button = dojo.byId('tippemPayTipsButton');
	switch(option)
	{
		case 'pay':
			Tippem.hasMarkedMoney = true;
			if (payLine.className == 'tippemTransactionLineSelected')
			{
				if (Tippem.markedItemCount == 1)
				{
					button.style.display = 'none';
				}
				
				Tippem.markedItemCount--;
				payLine.className = 'tippemTransactionLine';
				this.notifyTransactionUpdate(payField, 'reset');
				
			}
			else if (payLine.className == 'tippemTransactionCancelled')
			{
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'pay');
				button.value = "Complete Payment Now";
				button.style.display = 'inline';
				Tippem.markedItemCount++;
			}
			else if (payLine.className == 'tippemTransactionLine')
			{
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'pay');
				button.value = "Complete Payment Now";
				button.style.display = 'inline';
				Tippem.markedItemCount++;
			}
			else if (payLine.className == 'tippemTransactionLineEnd')
			{
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'pay');
				button.value = "Complete Payment Now";
				button.style.display = 'inline';
				Tippem.markedItemCount++;
			}
			else
			{
				if (Tippem.markedItemCount == 1)
				{
					button.style.display = 'none';
				}
				
				Tippem.markedItemCount--;
				payLine.className = 'tippemTransactionLine';
				button.style.display = 'none';
			}
			break;
		case 'cancel':
			if (payLine.className == 'tippemTransactionLine')
			{
				payLine.className = 'tippemTransactionCancelled';
				this.notifyTransactionUpdate(payField, 'remove');
			}
			else if (payLine.className == 'tippemTransactionCancelled')
			{
				payLine.className = 'tippemTransactionLine';
				this.notifyTransactionUpdate(payField, 'reset');
			}
			else if (payLine.className == 'tippemTransactionLineEnd')
			{
				payLine.className = 'tippemTransactionCancelled';
				this.notifyTransactionUpdate(payField, 'cancel');
			}
			else if (payLine.className == 'tippemTransactionRestricted')
			{
				payLine.className = 'tippemTransactionCancelled';
				this.notifyTransactionUpdate(payField, 'cancel');
			}
			else
			{
				payLine.className = 'tippemTransactionLine';
				this.notifyTransactionUpdate(payField, 'reset');
			}
			break;
		case 'claim':
			Tippem.hasMarkedMoney = true;
			if (payLine.className == 'tippemTransactionLineSelected')
			{
				payLine.className = 'tippemTransactionLine';
				this.notifyTransactionUpdate(payField, 'claimReset');
				button.style.display = 'none';
				Tippem.markedItemCount--;
			}
			else if (payLine.className == 'tippemTransactionCancelled')
			{
				if (Tippem.markedItemCount >= 1)
				{
					/**
					 * We need to show a dialog here that informs the user that 
					 * they cannot select more than one user at a time.
					 */
					Dialog.confirm({
						url:"/tippem/acceptAlert.php", 
						options:{method:'get'}}, 
						{width:480, height:'auto', className:"alphacube", 
						okLabel:"Return to Tips", cancelLabel:"Cancel", 
					    destroyOnClose:true, 
					    zIndex: 99999, recenterAuto:false, 
					    onOk: function() { Dialog.cancelCallback(); },
					    cancel: function() { }
						});
					return;
				}
				else
				{
					Tippem.markedItemCount++;
				}
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'claim');
				button.value = "Get Tips Now!";
				button.style.display = 'inline';
				
			}
			else if (payLine.className == 'tippemTransactionLine')
			{
				if (Tippem.markedItemCount >= 1)
				{
					/**
					 * We need to show a dialog here that informs the user that 
					 * they cannot select more than one user at a time.
					 */
					Dialog.confirm({
						url:"/tippem/acceptAlert.php", 
						options:{method:'get'}}, 
						{width:480, height:'auto', className:"alphacube", 
						okLabel:"Return to Tips", cancelLabel:"Cancel", 
					    destroyOnClose:true, 
					    zIndex: 99999, recenterAuto:false, 
					    onOk: function() { Dialog.cancelCallback(); },
					    cancel: function() { }
						});
					return;
				}
				else
				{
					Tippem.markedItemCount++;
				}
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'claim');
				button.value = "Get Tips Now!";
				button.style.display = 'inline';
			}
			else if (payLine.className == 'tippemTransactionLineEnd')
			{
				if (Tippem.markedItemCount >= 1)
				{
					/**
					 * We need to show a dialog here that informs the user that 
					 * they cannot select more than one user at a time.
					 */
					Dialog.confirm({
						url:"/tippem/acceptAlert.php", 
						options:{method:'get'}}, 
						{width:480, height:'auto', className:"alphacube", 
						okLabel:"Return to Tips", cancelLabel:"Cancel", 
					    destroyOnClose:true, 
					    zIndex: 99999, recenterAuto:false, 
					    onOk: function() { Dialog.cancelCallback(); },
					    cancel: function() { }
						});
					return;
				}
				else
				{
					Tippem.markedItemCount++;
				}
				payLine.className = 'tippemTransactionLineSelected';
				this.notifyTransactionUpdate(payField, 'claim');
				button.value = "Get Tips Now!";
				button.style.display = 'inline';
			}
			else
			{
				payLine.className = 'tippemTransactionLine';
				button.style.display = 'none';
				Tippem.markedItemCount--;
			}
			break;
	}	
}

Tippem.prototype.notifyTransactionUpdate = function(id, payType)
{
	this.showTransition('Saving, one moment...')
	switch(Tippem.context)
	{
		case 'pay':
			try {
				dojo.io.bind({
					url: this.getActionUrl() + '?action=notifyStateUpdate&transactionId=' + id.replace(/tip_/g, '') + '&status=' + payType,
					handler: this.notifyTransactionUpdateCallback,
					error: this.notifyTransactionUpdateError
				});
			} catch (e) {

				dojo.xhrGet ({
					url: this.getActionUrl() + '?action=notifyStateUpdate&transactionId=' + id.replace(/tip_/g, '') + '&status=' + payType,
					load: this.notifyTransactionUpdateCallback,
					error: this.notifyTransactionUpdateError,
					handleAs: "text"
				});
			}
			break;
		case 'claim':
			Tippem.claimReferenceId = id.replace(/tip_/g, '');
			try {
				dojo.io.bind({
					url: this.getActionUrl() + '?action=notifyStateUpdate&referenceId=' + id.replace(/tip_/g, '') + '&status=' + payType,
					handler: this.notifyTransactionUpdateCallback,
					error: this.notifyTransactionUpdateError
				});
			} catch (e) {
				dojo.xhrGet ({
					url: this.getActionUrl() + '?action=notifyStateUpdate&referenceId=' + id.replace(/tip_/g, '') + '&status=' + payType,
                    load: this.notifyTransactionUpdateCallback,
                    error: this.notifyTransactionUpdateError,
                    handleAs: "text"
                });
			}
			break;
	}

}

Tippem.prototype.notifyTransactionUpdateCallback = function(response, ioArgs)
{
	var tippem = new Tippem();
	var response = tippem.evalResponse(response);
	if (response[0].result == 'SUCCESS')
	{
		tippem.showTransition('<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/cornerIcons/check.png" /></div>' +
		'<span class="statusMessage">Record marked for ' + response[0].status + '.</span><div class="cleardiv"></div>');
	}
	else 
	{
		tippem.showTransition('<div class="statusImage"><img src="/Themes/OpenSalon/images/tippem/cornerIcons/warning.png" /></div>' +
		'<span class="statusMessage">Update failed!</span><div class="cleardiv"></div>');
	}
	tippem.updateBalanceTotal(response[1].approvedTotal, response[2].amountPledged);
	//setTimeout('var t = new Tippem(); t.displayResultStatus();', 1000);
	tippem.initialize();
}

Tippem.prototype.notifyTransactionUpdateError = function(response, ioArgs)
{
	var tippem = new Tippem();
	var response = tippem.evalResponse(response);
	alert(response[0].reason);
}

Tippem.prototype.showContributeBox = function(contentId, authorId)
{
	var box = dojo.byId('tipMoreBox');
	var link = dojo.byId('tipMoreLink');
	
	link.style.display = 'none';
	
	box.innerHTML = '<span class="tippemDollar">+ $</span><input class="tipMore tippemLeft" type="text" id="tipBox" value="1.00" /> ' + 
		'<input id="tipButton" class="tippemMiniButton tippemLeft" type="button" onClick="var t = new Tippem(); t.tipUserMore(\'' + 
			contentId + '\', \'' + authorId + '\'); return false;" value="Tip!">' + 
		'<input id="tipCancelButton" class="tippemMiniButton tippemLeft" type="button" onClick="var t = new Tippem(); t.cancelTipMore();" ' +
			'value="Cancel">';
			
	if (!Tippem.payTipsNowVisible) 
	{
		try {
			var payNow = dojo.byId('payTipsNowButton');
		} catch (e) {
			box.innerHTML += '&nbsp;<input id="payTipsNowButton" class="tippemMiniButton" type="button" ';
			box.innerHTML += 'onClick="document.location = \'/edit_profile.php?type=tippem\';" value="Pay Tips Now" />';
			Tippem.payTipsNowVisible = true;
		}
	}

}

Tippem.prototype.cancelTipMore = function()
{
	var tipMessage = dojo.byId('tipMessage');
	var tipControls = dojo.byId('tipControls');
	tipMessage.innerHTML = "Contribute more cancelled.";
	tipMessage.style.display = 'inline';
	tipControls.style.display = 'none';
}

Tippem.prototype.updateBalanceTotal = function(amount, pledgedAmount)
{
	var total = dojo.byId('transactionTotal');
	if (amount == 'null' || amount == null || amount == 0) 
	{
		amount = '0.00';
	}
	
	if (pledgedAmount == 'null' || pledgedAmount == null || pledgedAmount == 0)
	{
		pledgedAmount = '0.00';
	}
	
	if (amount.length == 1 || amount.length == 2)
	{
		amount = amount + '.00';
	}
	
	if (amount.length == 5) 
	{
		amount = '&nbsp;&nbsp;$' + amount;
	}
	else if (amount.length == 4)
	{
		amount = '&nbsp;&nbsp;&nbsp;&nbsp;$' + amount;
	}
	else 
	{
		amount = '$' + amount;
	}
	
	if (pledgedAmount <= 5)
	{
		pledgedAmount = '&nbsp;&nbsp;&nbsp;$' + pledgedAmount;
	}
	else
	{
		pledgedAmount = '$' + pledgedAmount;
	}
	
	switch(Tippem.context)
	{
		case 'claim':
			total.innerHTML = '<span class="tippemTotalCaption">Total amount selected: ' + amount + '</span><br />';
			total.innerHTML += '<span class="tippemTotalCaption">Total amount pending: ' + pledgedAmount + '</span>';
			break;
		case 'pay':
			total.innerHTML = '<span class="tippemTotalCaption">Total amount due: ' + amount + '</span><br />';
			total.innerHTML += '<span class="tippemTotalCaption">Total amount pledged: ' + pledgedAmount + '</span>';
			break;
		case 'history':
			if (Tippem.historyType == 'Paid') 
			{
				total.innerHTML = '<span class="tippemTotalCaption totalClaim">Total tips paid: ' + amount + '</span>';
			}
			else 
			{
				total.innerHTML = '<span class="tippemTotalCaption totalClaim">Total tips received: ' + amount + '</span>';
			}
			break;
	}
}

Tippem.prototype.showPane = function(pane)
{
	Tippem.clearSort();
	var paidColumn = dojo.byId('tippemColumnPaid');
	var acceptedColumn = dojo.byId('tippemColumnAccepted');
	var payTab = dojo.byId('tippemTabPay');
	var claimTab = dojo.byId('tippemTabClaim');
	var historyTab = dojo.byId('tippemTabHistory');
	var payColumn = dojo.byId('tippemColumnPay');
	var cancelColumn = dojo.byId('tippemColumnCancel');
	var authorColumn = dojo.byId('tippemColumnAuthor');
	var titleColumn = dojo.byId('tippemColumnTitle');
	var dateColumn = dojo.byId('tippemColumnDate');
	var button = dojo.byId('tippemPayTipsButton');
	var userColumn = dojo.byId('tippemColumnUser');
	var receivedColumn = dojo.byId('tippemColumnReceived');
	var amountColumn = dojo.byId('tippemColumnAmount');
	var notice = dojo.byId('tippemNotice');
	
	button.style.display = 'none';
	paidColumn.style.display = 'none';
	acceptedColumn.style.display = 'none';
	
	switch(pane)
	{
		case 'Pay':
			receivedColumn.style.display = 'none';
			notice.style.display = 'none';
			userColumn.style.display = 'none';
			titleColumn.style.display = 'inline';
			payTab.style.backgroundColor = '#eeeeff';
			claimTab.style.backgroundColor = '#dcdcdc';
			historyTab.style.backgroundColor = '#dcdcdc';
			payColumn.style.display = 'inline';
			payColumn.innerHTML = 'Pay';
			cancelColumn.style.display = 'inline';
			authorColumn.style.display = 'inline';
			dateColumn.style.display = 'inline';
			titleColumn.style.width = '170px';
			amountColumn.style.display = 'inline';
			Tippem.context = 'pay';
			break;
		case 'Claim':
			receivedColumn.style.display = 'inline';
			notice.style.display = 'inline';
			userColumn.style.display = 'inline';
			titleColumn.style.display = 'none';
			payTab.style.backgroundColor = '#dcdcdc';
			claimTab.style.backgroundColor = '#eeeeff';
			historyTab.style.backgroundColor = '#dcdcdc';
			payColumn.style.display = 'inline';
			payColumn.innerHTML = 'Accept';
			cancelColumn.style.display = 'none';
			authorColumn.style.display = 'none';
			dateColumn.style.display = 'none';
			titleColumn.style.width = '390px';
			amountColumn.style.display = 'inline';
			Tippem.context = 'claim';
			break;
		case 'History':
			receivedColumn.style.display = 'none';
			notice.style.display = 'none';
			userColumn.style.display = 'none';
			titleColumn.style.display = 'none';
			payTab.style.backgroundColor = '#dcdcdc';
			claimTab.style.backgroundColor = '#dcdcdc';
			historyTab.style.backgroundColor = '#eeeeff';
			payColumn.style.display = 'none';
			cancelColumn.style.display = 'none';
			authorColumn.style.display = 'none';
			dateColumn.style.display = 'none';
			titleColumn.style.width = '390px';
			Tippem.context = 'history';
			this.showHistoryPane();
			break;
		default:
			receivedColumn.style.display = 'none';
			notice.style.display = 'none';
			userColumn.style.display = 'none';
			titleColumn.style.display = 'inline';
			payTab.style.backgroundColor = '#eeeeff';
			claimTab.style.backgroundColor = '#dcdcdc';
			payColumn.style.display = 'inline';
			payColumn.innerHTML = 'Pay';
			cancelColumn.style.display = 'inline';
			authorColumn.style.display = 'inline';
			dateColumn.style.display = 'inline';
			titleColumn.style.width = '170px';
			amountColumn.style.display = 'inline';
			Tippem.context = 'pay';
			break;
	}
	this.initialize();
}

Tippem.prototype.showHistoryPane = function()
{
	var paidLink = dojo.byId('historyPaid');
	var acceptedLink = dojo.byId('historyAccepted');
	var paidColumn = dojo.byId('tippemColumnPaid');
	var acceptedColumn = dojo.byId('tippemColumnAccepted');
	var amount = dojo.byId('tippemColumnAmount');
	
	amount.style.display = 'none';
	paidColumn.style.display = 'inline';
	acceptedColumn.style.display = 'inline';
	
	switch(Tippem.historyType)
	{
		case 'Paid':
			paidLink.style.color = '#dcdcdc';
			acceptedLink.style.color = 'navy';
			break;
		case 'Accepted':
			acceptedLink.style.color = '#dcdcdc';
			paidLink.style.color = 'navy';
			break;
		default:
			alert('Invalid history type "' + Tippem.historyType + 
				'" was set prior to showing the history pane.');
			break;
	}
	this.initialize();
}

Tippem.prototype.hideContributeBox = function()
{
	var box = dojo.byId('tipMoreBox');
	box.innerHTML = '';
}

Tippem.prototype.checkSelectedTipAmount = function(contentId, authorId)
{
	var t = new Tippem();
	var select = dojo.byId('tippemSelect');
	if (select.options[select.selectedIndex].value == 'Other')
	{
		t.showContributeBox(contentId, authorId);
		return;
	}
	t.hideContributeBox();
	
}

Tippem.prototype.showSignupRequestHelp = function(loginName)
{
	Dialog.confirm({
		url:"/tippem/help.php?loginName=" + loginName, 
		options:{method:'get'}}, 
		{width:480, height:'auto', className:"alphacube", 
		okLabel:"Return to Tips", cancelLabel:"Cancel", 
	    destroyOnClose:true, 
	    zIndex: 99999, recenterAuto:false, 
	    onOk: function() { Dialog.cancelCallback(); },
	    cancel: function() { }
		});
}
