/**
 * Controls donations to attain a key for the addon
 * @title		Donation Controller
 * @author		Colin Nolan
 * @version		v2.0.1
 * @created		Unknown
 * @updated		09/10/11 (v2.0.1), 28/09/11 (v2.0.0)
 *
 * @param	{HTMLElement} amountUI	Element where the user is shown and can change the donation amount
 * @param	{HTMLElement} TACAccpet	Terms and conditions check box
 * @param	{HTMLElement} submitBtn	Button user presses to submit the donation
 * @param	{HTMLElement} paypalAmount	Transaction amount sent to Paypal
 * @param	{HTMLElement} paypalSubmit	Button used to send the transaction to Paypal
 */
var DonationController = function(amountUI, TACAccept, submitBtn, loadingDisplay, paypalAmount, paypalSubmit)
{
	/*
	 * Settings
	 */
	var STANDARD_DONATION = 2.99;								// Standard donation amount
	var MINIMUM_DONATION = 1.50;								// Minimum allowed donation amount

	var SMALL_DONATION_MSG = "Sorry, the value you have entered is below the minimum donation allowed (£"+ MINIMUM_DONATION.toFixed(2) +").\n A minimum value is in place due to relatively high Paypal charges on small amounts.";
	var NAN_DONATION_MSG = "The value you have entered is not a number";
	var DISAGREE_TAC = "Please read then accept the Terms and Conditions\n(Tick the checkbox below the donate button)";

	var LOADING_IMG = "/common/images/icons/loading_circle.gif";



	/*
	 * Instance variables
	 */
	var that = this;											// Cache "this" scope
	var loadingImg;												// Image to display to show that Paypal is loading



	/*
	 * Pseudo constructor
	 */
	var construct = function()
	{
		// Setup UI
		submitBtn.addEventListener(
			"click",
			onSubmit,
			true
		);
		amountUI.addEventListener(
			"change",
			function() {
				try {
					that.checkDonation();
				}
				catch(e) {
					window.alert(e.message);
				}
			},
			true
		);
		amountUI.value = STANDARD_DONATION.toFixed(2);

		// Preload loading image
		loadingImg = new Image();
		loadingImg.alt = "Loading Paypal...";
		loadingImg.style.height = "25px";
		loadingImg.src = LOADING_IMG;
	};



	// Private methods
	/**
	 * To be called when the donation submit button is pressed
	 */
	var onSubmit = function()
	{
		var validDonation = true;
		try {
			that.checkDonation();
		}
		catch(e) {
			window.alert(e.message);
			validDonation = false;
		}

		if(validDonation) {
			if(!TACAccept.checked) {
				// TAC not accepted
				window.alert(DISAGREE_TAC);
			}
			else {
				loadingDisplay.appendChild(loadingImg);				// Show loading image (as may be delay connecting to Payapl)
				submitBtn.onclick = function(){};					// Disable inline HTML onclick event (eg may be logger)
				sendDonation(Number(amountUI.value).toFixed(2));	// Send donation to paypal
			}
		}
	};


	/*
	 * Check the donation amount, reporting any problems
	 * @throws	SMALL_DONATION_MSG
	 * @throws	NAN_DONATION_MSG
	 */
	this.checkDonation = function()
	{
		// Allow donation amount to be reset to standard
		var resetAmount = function() {
			amountUI.value = STANDARD_DONATION;
		};
		
		// Allow for European pounds/pence seperator
		if(amountUI.value.indexOf(",") != -1) {
			amountUI.value = amountUI.value.replace(",", ".");
		}

		// Validate donation
		try {
			if(!isValidAmount(amountUI.value)) {
				// Donation too small
				resetAmount();
				throw (new Error(SMALL_DONATION_MSG));
			}
		}
		catch(e) {
			if(e.message == "NaN") {
				resetAmount();
				throw (new Error(NAN_DONATION_MSG));
			}
			else {
				throw e;
			}
		}
	};


	/*
	 * Check if amount is valid donation
	 * @param	{float} amount	Donation amount
	 * @throws	NaN (Not a number)
	 */
	var isValidAmount = function(amount)
	{
		amount = Number(amount);
		if(isNaN(amount)) {
			throw new Error("NaN");
		}
		else {
			return (amount >= MINIMUM_DONATION);
		}
	};


	/*
	 * Send the donation to be processed by Paypal
	 * @param	{float} amount	Value of the transaction
	 */
	var sendDonation = function(amount)
	{
		amountUI.value = amount;				// Show to user how much they are donating (as formatting to number may have occurred)
		paypalAmount.value = amount;
		paypalSubmit.click();
	};



	// Call the constructor
	construct();
};
