var offerSwapper = Class.create({
	initialize: function(offerClassName, mainOfferContainer, allOffersContainer, options) {
		this.offerClassName = offerClassName;
		this.mainOfferContainer = $(mainOfferContainer);
		this.allOffersContainer = $(allOffersContainer);
		this.offers = $$(offerClassName);
		this.options = Object.extend({
			onUpdate: Prototype.emptyFunction
		}, options || {});

		var timerStr = new Array();
		this.offers.each( function(c) {
			timerStr.push('"' + c.identify() + '":' +
				'{days:"' + c.down('span.days').innerHTML + '",' +
				'hours:"' + c.down('span.hours').innerHTML + '",' +
				'minutes:"' + c.down('span.minutes').innerHTML + '"}');
		}.bind(this));
		timerStr = '{' + timerStr + '}';
		this.toWatch = timerStr.evalJSON();

		this.updateFrequency = 60;
		new PeriodicalExecuter(this.updateTimers.bind(this), this.updateFrequency);
		this.updateLabels();

		if (this.offers.length > 0) {
			this.currentOffer = this.offers.first().identify();
			this.setupVisual();
		}
	},
	setupVisual: function() {
		this.allOffersContainer.select('div' + this.offerClassName).invoke('hide');

		// Create clickable offer summary
		this.offers.each(function(e, i) {
			var newElem = new Element('div', { 'class': 'overview', 'id': ('offer' + (i+1) +'-over')});
			newElem.setAttribute('class', 'overview')
			// Insert the number of the offer and days remaining.
			var daysLeft = e.down('span.days').innerHTML;
			newElem.insert({ bottom:('<p class="darrow">' +
				'<span class="offer-listing">offer ' + (i+1) + '</span> ' +
				'<span class="days-remain">' + checkNumberIsDoubleDigit(daysLeft) + ' day' + (daysLeft != '1' ? 's':'') + ' to go</span>' +
				'</p>')
			});
			// Insert the offer thumbnail image
			newElem.insert({ top: e.down('div.offer-thumbnail') });
			// Insert the block into the list.
			this.allOffersContainer.insert({ bottom: newElem });
		}.bind(this))

		// Add event handlers to summaries
		this.allOffersContainer.select('div.overview').each( function(f) {
			f.observe('mouseover', function(evt1) {
				var evtItem = evt1.element();
				if (evtItem.tagName == 'DIV') { evtItem.addClassName('onhover'); }
				else { evtItem.up('div.overview').addClassName('onhover'); }
			});
			f.observe('mouseout', function(evt2) {
			    var evtItem = evt2.element();
				if (evtItem.tagName == 'DIV') { evtItem.removeClassName('onhover'); }
				else { evtItem.up('div.overview').removeClassName('onhover'); }
			});
			f.observe('click', function(evt) {
				var offerId = (evt.element().hasClassName('overview'))
					? evt.element().identify().split('-over')
					: evt.element().up('div.overview').identify().split('-over');
				if (offerId[0]) { this.setCurrentOffer(offerId[0]) }
				else { }
			}.bind(this));
		}.bind(this));

		this.setCurrentOffer(this.currentOffer);
	},
	updateTimers: function() {
		this.offers.each( function(f) {
			var id = f.identify();
			if (this.toWatch[id].minutes == 0 && this.toWatch[id].hours == 0 && this.toWatch[id].days == 0) {
				//Offer has expired - update to reflect this or remove the offer.
				window.location.reload();
			}
			//Update the values of the countdown
			if (this.toWatch[id].minutes > 0) { this.toWatch[id].minutes--; }
			else {
				//Update hours
				this.toWatch[id].minutes = 59;
				if (this.toWatch[id].hours > 0) { this.toWatch[id].hours--; }
				else {
					//Update days
					this.toWatch[id].hours = 23;
					if (this.toWatch[id].days > 0) {
						this.toWatch[id].days--;
						// If the days are reduced, the overview will also need amending.
						$(id + '-over').down('span.days-remain').update(checkNumberIsDoubleDigit(this.toWatch[id].days) + ' day' + (this.toWatch[id].days != '1' ? 's':'') + ' to go');
					} else {
						// Shouldn't ever get to this stage!
					}
				}
			}
	   }.bind(this));
	   this.updateLabels();
	},
	updateLabels: function() {
		this.offers.each( function(f) {
			var id = f.identify();
			//Update the content of the page
			f.down('span.days').update(checkNumberIsDoubleDigit(this.toWatch[id].days));
			f.down('span.hours').update(checkNumberIsDoubleDigit(this.toWatch[id].hours));
			f.down('span.minutes').update(checkNumberIsDoubleDigit(this.toWatch[id].minutes));

			// If the offer is the selected one, the main section will also need amending.
			if (id == this.currentOffer) {
				this.mainOfferContainer.down('span.days').update(checkNumberIsDoubleDigit(this.toWatch[id].days));
				this.mainOfferContainer.down('span.hours').update(checkNumberIsDoubleDigit(this.toWatch[id].hours));
				this.mainOfferContainer.down('span.minutes').update(checkNumberIsDoubleDigit(this.toWatch[id].minutes));
			}
		}.bind(this));
	},
	setCurrentOffer: function(offerId) {
		$(this.currentOffer + '-over').removeClassName('currentOffer');
		this.currentOffer = offerId;
		// Copy content to go in mainOfferContainer
		var newDiv = new Element('div', { 'class':'single-offer' });
		newDiv.setAttribute('class','single-offer')
		newDiv.insert({ top: $(this.currentOffer).innerHTML });
		this.mainOfferContainer.update(newDiv);
		$(this.currentOffer + '-over').addClassName('currentOffer');
		this.notify('onUpdate');

		replaceHeaders();
	},
	notify: function(event_name){
		try{
			if(this.options[event_name])
				return [this.options[event_name].bindAsEventListener(this).apply(this.options[event_name],$A(arguments).slice(1))];
		}catch(e){
			if(e != $break)
				throw e;
			else
				return false;
		}
	}
});

var itemCarousel = Class.create({
	initialize: function(carouselContainer, options) {
		this.carouselContainer = carouselContainer;
		this.allItems = $$(this.carouselContainer + ' li');
		this.currentFirst = 0;
		this.countToShowAtOnce = 5;
		this.currentLast = this.currentFirst + this.countToShowAtOnce-1;
		this.currentlyMoving = false;
		this.pe = false;

		this.setup();
	},
	setup: function() {
		// Setup forward button
		$('rotate-backwards').setStyle({ display:'block' });
		$('rotate-backwards').observe('click', function(el) { el.stop(); this.slideRight(); }.bind(this));
		$('rotate-backwards').observe('mousedown', function(el) { if (!this.pe) this.pe = new PeriodicalExecuter(this.slideRight, 0.3);  }.bind(this));
		$('rotate-backwards').observe('mouseup', function(el) { this.stopPe(); }.bind(this));
		$('rotate-backwards').observe('mouseout', function(el) { this.stopPe(); }.bind(this));

		//Setup backwards button
		$('rotate-forwards').setStyle({ display:'block' });
		$('rotate-forwards').observe('click', function(e2) { e2.stop(); this.slideLeft(); }.bind(this));
		$('rotate-forwards').observe('mousedown', function(el) { if (!this.pe) this.pe = new PeriodicalExecuter(this.slideLeft, 0.3);  }.bind(this));
		$('rotate-forwards').observe('mouseup', function(el) { this.stopPe(); }.bind(this));
		$('rotate-forwards').observe('mouseout', function(el) { this.stopPe(); }.bind(this));

		//Calculate width of rotater
		var addedWidth = new Array(
							parseInt(this.allItems[0].getStyle('padding-left'), 10),
							parseInt(this.allItems[0].getStyle('padding-right'), 10),
							parseInt(this.allItems[0].getStyle('margin-left'), 10),
							parseInt(this.allItems[0].getStyle('margin-right'), 10),
							parseInt(this.allItems[0].getStyle('border-left-width'), 10),
							parseInt(this.allItems[0].getStyle('border-right-width'), 10));
		var i = 0;
		for (var j = 0; j < addedWidth.length; j++) {
			if (!isNaN(addedWidth[j]) && null != addedWidth[j]) { i += addedWidth[j]; }
		}
		var newWidth = (this.allItems.length * (this.allItems[0].getWidth() + i) + 1) + 'px';
		$$('#bright-carousel-list')[0].setStyle({ width:newWidth });
	},
	stopPe: function() {
		if (this.pe) this.pe.stop(); this.pe = false;
	},
	slideLeft: function() {
		var firstElement = $('bright-carousel-list').down('li', 0);
		var newItem = new Element('li').insert({top:firstElement.innerHTML});
		$('bright-carousel-list').insert({bottom:newItem});
		firstElement.remove();
	},
	slideRight: function() {
		var lastElement = $('bright-carousel-list').select('li').last();
		var newItem = new Element('li').insert({top:lastElement.innerHTML});
		lastElement.remove();
		$('bright-carousel-list').insert({top:newItem})
	}
});

function checkNumberIsDoubleDigit(number) {
	number = '' + number;
	if (number.length == 0) { return '00'; }
	else if (number.length == 1) { return '0' + number; }
	else { return number; }
}

var phoneSwapper = Class.create({
	initialize:function(mainContainer, commonDivName, options) {
		this.mainContainer = mainContainer;
		this.commonDivName = commonDivName;
		this.options = Object.extend({
			afterSwap: Prototype.emptyFunction
		}, options || {});
		$$('.'+this.commonDivName).invoke('hide');
		this.swapPhone($$('.'+this.commonDivName)[0].identify().split('-details').first());
	},

	swapPhone:function(selectedPhone) {
		$$('li.selected').invoke('removeClassName', 'selected');
		$$('li.' + selectedPhone).invoke('addClassName', 'selected');

		// Copy content to go in mainOfferContainer
		if ($(selectedPhone + '-details')) {
			var newDiv = new Element('div');
			// Prototype 1.6.0.3 and ie8 don't play friendly with adding classnames to elements - must add separate div with correct classname inside.
			newDiv.insert({ top: ('<div class="' + this.commonDivName + '">' + $(selectedPhone + '-details').innerHTML + '</div>') });
			$(this.mainContainer).update(newDiv);
		}
		this.notify('afterSwap');
	},

	addHandlerToLinks: function(links) {
		$$(links).each( function(f) {
			f.observe('click', function(g) {
				g.stop();
				var clickedItemType = g.element().tagName;
				var element = (clickedItemType == 'IMG' || clickedItemType == 'SPAN') ? g.element().up('a') : g.element();
				var selectedPhone = element.href.split('#').last().split('?').first().split('-details').first();
				this.swapPhone(selectedPhone);
			}.bind(this));
		}.bind(this));
	},

	notify: function(event_name){
		try{
			if(this.options[event_name])
				return [this.options[event_name].bindAsEventListener(this).apply(this.options[event_name],$A(arguments).slice(1))];
		}catch(e){
			if(e != $break) {
				throw e;
			}
			else
				return false;
		}
	}
});