var Item = {
	baseAmount: 18.00, // GBP
	additions: {
		sizes: [
			{measurement: 'Sml (150 x 190mm)', amount: 18.00},
			{measurement: 'Med (200 x 250mm)', amount: 25.00},
			{measurement: 'Lrg (300 x 375mm)', amount: 35.00}
		],
		mounted: 12.00
	},
	// Dev
	/*paypal: {
		email: 'bill_1220273865_biz@peritussolutions.co.uk',
		url: 'https://www.sandbox.paypal.com/cgi-bin/webscr',
		successURL: 'http://jazzshot.indigo/thank-you-for-your-purchase/',
		cancellationURL: 'http://jazzshot.indigo/your-purchase-has-been-cancelled'
	},*/
	// Live
	paypal: {
		email: 'alan@jazzshot.co.uk',
		url:  'https://www.paypal.com/cgi-bin/webscr',
		successURL: 'http://www.jazzshot.com/thank-you-for-your-purchase/',
		cancellationURL: 'http://www.jazzshot.com/your-purchase-has-been-cancelled'
	},
	form: '<a href="#" title="Buy this photo" class="buy"><span>Buy</span></a><form class="buy" style="display: none" action="#{paypalURL}" method="post"><input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="#{paypalEmail}"><input type="hidden" name="undefined_quantity" value="1"><input type="hidden" name="item_name" value="#{name}"><input type="hidden" name="item_number" value="#{id}"><input type="hidden" name="amount" value="#{itemAmount}"><input type="hidden" name="page_style" value="PayPal"><input type="hidden" name="no_shipping" value="2"><input type="hidden" name="return" value="#{paypalSuccessURL}"><input type="hidden" name="cancel_return" value="#{paypalCancellationURL}"><input type="hidden" name="no_note" value="1"><input type="hidden" name="currency_code" value="GBP"><input type="hidden" name="lc" value="GB"><input type="hidden" name="bn" value="PP-BuyNowBF"><span class="size"><input type="hidden" name="on0" value="Size"><label for="image-#{id}-size">Size</label><select id="image-#{id}-size" class="size" name="os0">#{sizes}</select></span><span class="mounting"><input type="hidden" name="on1" value="Mounting"><input type="radio" name="os1" value="mounted" id="image-#{id}-mounted" class="mounted" /><label for="image-#{id}-mounted">Mounted (&pound;#{mountedPrice})</label><input type="radio" name="os1" value="unmounted" id="image-#{id}-unmounted" class="unmounted" checked="checked" /><label for="image-#{id}-unmounted">Unmounted</label></span><span class="price">&pound;<span class="amount">#{itemAmount}</span> per image</span><br /><span class="quantity"><label for="image-#{id}-quantity">Quantity</label><input id="image-#{id}-quantity" name="quantity" class="quantity" value="1" size="2" /></span><span class="total">&pound;<span class="total-amount">#{totalAmount}</span> total</span><span class="submit"><input type="submit" value="Buy &rarr;" class="submit"><a href="#" title="Cancel buying this photo" class="cancel">Cancel</a><img alt="" border="0" src="https://www.sandbox.paypal.com/en_GB/i/scr/pixel.gif" width="1" height="1"></span></form>',
	error: '<span class="error"><em class="message">#{message}</em></span>'
}

var Photo = Class.create({
	initialize: function(node)
	{
		this.node = node
		this.id = this.getID()
		this.filename = this.getFilename()
		this.containers = {
			thumb: this.getContainer(),
			full: 'TB_window'
		}

		// Add a Paypal form to the thumbnail
		this.thumbPaypal = new Paypal(this.id, this.filename, this.containers.thumb)

		// When clicked wait for the full size image to display then add a Paypal form
		this.node.observe('click', function(event) {
			new PeriodicalExecuter(function(executer) {
				if ($(this.containers.full) != null)
				{
					if ($(this.containers.full).down('a#TB_ImageOff'))
					{
						var container = this.prepareFullContainer($(this.containers.full).down('a#TB_ImageOff'))
						this.fullPaypal = new Paypal(this.id, this.filename, container)
						executer.stop()
					}
				}
			}.bind(this), 0.5);
		}.bind(this))
	},

	getID: function()
	{
		return this.node.id.replace('thumb', '')
	},

	getFilename: function()
	{
		return this.node.down('img').src.split('thumbs_')[1]
	},

	getContainer: function()
	{
		return this.node.up('div')
	},

	prepareFullContainer: function(node)
	{
		if ($('TB_image_wrapper'))
		{
			return $('TB_image_wrapper')
		}
		else
		{
			return node.wrap('div', {'id': 'TB_image_wrapper'})
		}
	}
})

var Paypal = Class.create({
	initialize: function(id, name, container)
	{
		this.itemID = id
		this.itemName = name
		this.container = container
		this.form = this.insertForm(this.container, this.buildForm())
		this.buy = this.getBuyButton()
		this.itemAmount = this.setItemAmount([this.getSizePrice(this.form.down('select.size').getValue())])
		this.totalAmount = this.setTotalAmount(this.itemAmount)
		this.quantityError = false

		this.setSwitch() // Activate the form open and close action

		new Form.Observer(this.form, 0.5, this.monitorForm.bind(this))

		this.form.observe('submit', function(event) {
			if (this.quantityError != false)
			{
				event.stop()
			}
		}.bind(this))
	},

	monitorForm: function(form)
	{
		currentSize = form.down('select.size').select('option').find(function(item) {return item.selected == true}).value

		size = (form.down('select.size').getValue() == currentSize) ? this.getSizePrice(form.down('select.size').getValue()) : currentSize

		mounted = (form.down('input.mounted').checked) ? Item.additions.mounted : 0

		additions = [
			size,
			mounted
		]

		this.itemAmount = this.setItemAmount(additions)
		
		if (this.checkQuantity(form.down('input.quantity').getValue()))
		{
			if (this.quantityError != false)
			{
				this.removeError()
			}
			this.totalAmount = this.setTotalAmount(this.itemAmount)
		}
		else
		{
			this.addError(form.down('input.quantity'))
		}
	},

	setItemAmount: function(additions)
	{
		if (additions.length > 0)
		{
			itemAmount = additions.inject(0, function(acc, n) { return acc + n; })
		}
		else
		{
			itemAmount = Item.baseAmount
		}

		this.insertItemAmount(itemAmount)

		return itemAmount
	},

	setTotalAmount: function(amount)
	{
		totalAmount = amount * this.form.down('input.quantity').value
		this.insertTotalAmount(totalAmount)

		return totalAmount
	},

	insertItemAmount: function(amount)
	{
		if (amount != this.itemAmount)
		{
			this.form.down('input[name="amount"]').value = amount
			this.form.down('span.amount').innerHTML = amount.toFixed(2)
			Effect.Pulsate(this.form.down('span.price'), {pulses: 2, duration: .5})
		}
	},

	insertTotalAmount: function(amount)
	{
		if (amount != this.totalAmount)
		{
			this.form.down('span.total-amount').innerHTML = amount.toFixed(2)
			Effect.Pulsate(this.form.down('span.total'), {pulses: 2, duration: .5})
		}
	},

	getSizePrice: function(measurement)
	{
		return Item.additions.sizes.find(function(size) {
			return size.measurement == measurement
		}).amount
	},

	insertForm: function(container, formHTML)
	{
		return container.insert({bottom: formHTML}).down('form.buy')
	},

	buildForm: function()
	{
		return Item.form.interpolate({
			id: this.itemID,
			name: this.itemName,
			paypalURL: Item.paypal.url,
			paypalEmail: Item.paypal.email,
			paypalSuccessURL: Item.paypal.successURL,
			paypalCancellationURL: Item.paypal.cancellationURL,
			sizes: this.buildSizes(),
			mountedPrice: Item.additions.mounted,
			itemAmount: this.itemAmount,
			totalAmount: this.totalAmount
		})
	},

	buildSizes: function()
	{
		var sizeList = ''
		Item.additions.sizes.each(function(size, index) {
			sizeList += '<option value="#{measurement}">#{measurement}</options>'.interpolate({measurement: size.measurement})
		})

		return sizeList
	},

	getBuyButton: function()
	{
		return this.container.down('a.buy')
	},

	setSwitch: function()
	{
		this.buy.observe('click', this.showForm.bindAsEventListener(this))
		this.form.down('a.cancel').observe('click', this.hideForm.bindAsEventListener(this))
	},

	showForm: function(event)
	{
		Effect.Fade(this.buy, {duration: 0.2, queue: 'front'})
		Effect.SlideDown(this.form, {duration: 0.5, queue: 'end'})
		event.stop()
	},

	hideForm: function(event)
	{
		Effect.SlideUp(this.form, {duration: 0.5, queue: 'front'})
		Effect.Appear(this.buy, {duration: 0.5, queue: 'end'})
		event.stop()
	},

	checkQuantity: function(quantity)
	{
		return (!quantity.blank() && quantity > 0)
	},

	addError: function(field)
	{
		if (field.next('.error') == undefined)
		{
			var error = field.insert({after: Item.error.interpolate({message: 'The quantity must be a number greater than zero'})}).next('span.error')

			this.quantityError = error

			this.styleError(error)
		}
	},

	removeError: function()
	{
		this.quantityError.remove()
		this.quantityError = false
	},

	styleError: function(error)
	{
		var dimensions = error.getDimensions()
		var y = dimensions.height*-1

		error.setOpacity(0.85)
		error.setStyle({top: y+"px", left: '0'})
	}
})