var UserInterface = new Class({
							  
	classes: new Hash({
	
	}),
	
	initialize: function() {
		window.addEvent('domready', function() {
			
			// Loads all the objects
			this.loadClasses();
			
			// Load calendars
			//this.loadCalendars();
		}.bind(this));
	},
	
	loadClasses: function(selectorPrefix) {
		var selectorPrefix = selectorPrefix || '';
		
		// Finds all the elements for each class as defined by the selectors
		// property of the classes Hash, then creates an instance of that class 
		// which binds the instance to the element.
		this.classes.each(function(options, className) {
			options.selectors.each(function(selector) {
				$$(selectorPrefix + selector).each(function(element) {
					// Check to ensure the class has not already been defined to the element.
					if (!element.retrieve(className)) {
						new	window[className](element);				   
					}
				});
			}.bind(this));
		}.bind(this));		
	},
	
	loadCalendars: function() {
		//new Calendar({ start_date: 'Y-m-d', end_date: 'Y-m-d' }, { navigation: 1, classes: ['dashboard']}); 
		var elements 	= $$('.calendar');
		var obj			= {};
		elements.each(function(element) {
			if (!element.id) {
				element.id = 'calendar-' + $random(1, 10000);	
			}
			obj[element.id] = 'Y-m-d'
		});
		
		new Calendar(obj, {navigation: 1, classes: ['dashboard']});
	}
	
});

Element.implement({
	reveal: function() {
		this.setStyles({
			'display' 		: 'block',
			'opacity'		: 0
		});
		this.fade('in');		
	}
});

Array.implement({
	shuffle: function() {
		this.sort(function (x,y) { 
			return Math.floor(Math.random()*3)-1; 
		});
		
		return this;	
	}
});

var Attachments = new Class({
	
	attach: function() {
		if (this.attachments && this.element) {
			this.attachments.each(function(name) {
				this.element[name] = function() {
					this[name].apply(this, arguments);	
				}.bind(this);
			}.bind(this));		
		}
	}
	
});

var Initialize = new Class({

	prepare: function(element) {
		this.element = element;
		this.element.store(this.name, this);
		this.attach();
	},
	
	generateID: function() {
		if (this.element.id) {
			return;	
		}
		
		var chars 			= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
		var randomstring 	= this.name + '-';
		for (var i=0; i<10; i++) {
			var rnum = Math.floor(Math.random() * chars.length);
			randomstring += chars.substring(rnum,rnum+1);
		}
		this.element.id = randomstring;		
	}
});


var FeatureController = new Class({
	
	Implements: [Initialize],
					  
	attachments	: [],
	selectors	: [],		
	name		: 'FeatureController',

	initialize: function() {
		
		if (!$('feature-container')) {
			return;	
		}
		
		this.features			= [];
		this.navElements		= [];
		this.container			= $('feature-container');
		this.controlContainer	= this.container.getElement('.feature-nav-container');
		this.leftButton			= this.controlContainer.getElement('.feature-left-button');
		this.rightButton		= this.controlContainer.getElement('.feature-right-button');		
		this.navBar				= this.controlContainer.getElement('.feature-nav');
		this.featuresContainer	= this.container.getElement('.features');
		this.centreFrame		= this.featuresContainer.getElement('.centred');
		this.slider				= this.centreFrame.getElement('.feature-slider');
		this.active				= 0;
		this.timer				= null;
		this.featureWidth		= 960;
		
		$$('.feature').each(function(feature) {
			this.features.push(new Feature(feature, this));							 
		}.bind(this));
	
		this.setNav();
		this.startSlideshow();
	},
	
	setNav: function() {
		this.leftButton.addEvents({
			'click'			: function(e) {
				e.preventDefault();
				this.previous();
			}.bind(this),
			'mouseenter' 	: function(e) {
				e.stop();
				this.stopSlideshow();
			}.bind(this),
			'mouseleave'	: function(e) {
				e.stop();
				this.startSlideshow();
			}.bind(this)
		});
		
		this.rightButton.addEvents({
			'click'			: function(e) {
				e.preventDefault();
				this.next();
			}.bind(this),
			'mouseenter' 	: function(e) {
				e.stop();
				this.stopSlideshow();
			}.bind(this),
			'mouseleave'	: function(e) {
				e.stop();
				this.startSlideshow();
			}.bind(this)
		});
		
		if (this.navBar != null) {
			this.navBar.addEvents({
				'mouseenter' 	: function(e) {
					e.stop();
					this.stopSlideshow();
				}.bind(this),
				'mouseleave'	: function(e) {
					e.stop();
					this.startSlideshow();
				}.bind(this)							  
			});
			
			this.navElements = this.navBar.getElements('div');
			
			this.navElements.each(function(element, index) {
				element.addEvents({
					'click'	: function(e) {
						e.preventDefault();
						this.activate(index);
					}.bind(this)
				});
			}.bind(this));
		}
	},
	
	resetTimer: function() {
		$clear(this.timer);		

		this.timer = (function() {
			this.next();
		}.bind(this)).periodical(6000);
	},
	
	startSlideshow: function() {
		this.stopSlideshow();
		this.timer = (function() {
			this.next();
		}.bind(this)).periodical(6000);
	},
	
	stopSlideshow: function() {
		$clear(this.timer);
	},
	
	activate: function(index) {
		var position 	= this.featureWidth * index * -1;
		this.active		= index;
		
		this.navElements.each(function(element) {
			element.removeClass('active');							   
		});
		
		if (this.navElements[this.active]) {
			this.navElements[this.active].addClass('active');
		}

		this.slider.tween('left', position);
	},
	
	next: function() {
		this.active++;
		
		if (this.active >= this.features.length) {
			this.active = 0;	
		}
		
		this.activate(this.active);
	},
	
	previous: function() {
		this.active--;
		
		if (this.active < 0) {
			this.active = this.features.length - 1;	
		}
		
		this.activate(this.active);		
	}
	
});

var Feature = new Class({
	
	Implements: [Attachments, Initialize],
					  
	attachments	: [],
	selectors	: ['.feature'],		
	name		: 'Feature',

	initialize: function(element, controller) {
		
		// The prepare method of the Initialize class sets this.element, stores the current
		// class instance against the element, and attaches any functions to the element.
		this.prepare(element);
		
		this.controller			= controller;
		this.index				= this.controller.features.length;
		
		this.element.addEvents({
			'mouseenter' 	: function(e) {
				e.stop();
				this.controller.stopSlideshow();
			}.bind(this),
			'mouseleave'	: function(e) {
				e.stop();
				this.controller.startSlideshow();
			}.bind(this)
		});
	},
	
	activate: function() {
		this.controller.activate(this.index);
	}

});

window.addEvent('domready', function() {
	var featureController = new FeatureController();
	
	// remove primary menu links for mobile devices to enable submenus.
	if (Browser.Platform.ios || Browser.Platform.android) {
		$$('#menu .has-sub-menu').each(function(element) {
			element.getElement('a').set('href','#');									 
		});
	}
});

var UI = new UserInterface();
