var UserInterface = new Class({
							  
	classes: new Hash({
		'Button'		: {
			'selectors'	: ['.button']	
		},						  
		'Table'		: {
			'selectors'	: ['table.grid']	
		},					  
		'Placeholder'	: {
			'selectors'	: ['.placeholder']	
		}		
	}),
	
	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 Placeholder = new Class({
	
	Implements: [Attachments, Initialize],
					  
	attachments	: [],
	selectors	: ['input.placeholder'],		
	name		: 'Placeholder',

	initialize: function(element) {
		
		// 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.placeholder = new Element('div', {
			'text'		: this.element.get('data-placeholder'),
			'class'		: 'placeholder',
			'styles'	: {
				'position'		: 'absolute',
				'font-size'		: this.element.getStyle('font-size'),
				'top'			: this.element.getPosition(this.element.getOffsetParent()).y,
				'left'			: this.element.getPosition(this.element.getOffsetParent()).x,
				'height'		: this.element.getSize().y,
				'width'			: this.element.getSize().x,
				'line-height'	: this.element.getSize().y + 2
			},
			'events'	: {
				'click'		: function(e) {
					e.stop();
					this.hide();
					this.element.focus();
				}.bind(this)
			}
		}).inject(this.element, 'after');
		
		this.element.addEvent('blur', function(e) {
			if (this.element.value == '') {
				this.show();	
			}
		}.bind(this));
		
		this.element.addEvent('focus', function(e) {
			this.hide();
		}.bind(this));
		
		if (this.element.value != '') {
			this.hide();	
		}
	},
	
	hide: function() {
		this.placeholder.setStyle('display','none');	
	},
	
	show: function() {
		this.placeholder.setStyle('display','block');	
	}
});

var Table = new Class({
					  
	Implements: [Attachments, Initialize],
					  
	attachments	: ['stripe','test','roar'],
	name		: 'Table',

	initialize: function(element) {
		
		// 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);
		
		if (!element.id) {
			// If the table has not been assigned an ID, we have to give
			// it one so the sort function works.
			this.generateID();
		}
		
		this.setColumns();
		this.stripe();
		this.setSortable();
		
	},
	
	setColumns: function() {
		var headings = this.element.getElements('th');
		
		if (headings.length > 0) {
			headings[0].addClass('first');
			headings[headings.length - 1].addClass('last');
		}
	},
	
	roar: function(text) {
		alert(text);
	},
	
	test: function() {
		alert('test');
	},
	
	setSortable: function() {
		if (this.element.hasClass('sortable')) {
			var mysortable = new SortingTable(this.element.get('id'), {
				forward_sort_class: 'down',
				reverse_sort_class: 'up'
			});	
		}
		
		this.stripe();
	},
	
	stripe: function() {
		var count = 0;
		if (this.element.hasClass('grid') && !this.element.hasClass('no-stripes')) {
			this.element.getElements('tbody tr').each(function(row) {
				if (row.hasClass('spacer')) {
					return;
				}
				count++;
				row.removeClass('even');
				if (count % 2 == 0) {
					row.addClass('even');
				}
			});
		}		
	},
	
	toElement: function() {
		return this.element;	
	}

});

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

	initialize: function(element) {
		
		// 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);

		// If the button needs an image, and we can add one in - do it!
		if (this.element.tagName.toLowerCase().match(/a|button/)) {
			new Element('img', {
				'src'		: this.element.hasClass('red') ? '/assets/images/template/button-arrow2.png' : '/assets/images/template/button-arrow.png',
				'styles'	: {
					'position'		: 'relative',
					'left'			: '-5px'
				}
			}).inject(this.element, 'top');
		}

		if (Browser.ie) {
			var content = this.element.get('html');
			this.element.set('html','');
			
			new Element('span.left').inject(this.element, 'top');
			new Element('span.right', {
				'html'		: content			
			}).inject(this.element, 'bottom');
			
			this.element.addClass('ie');
		}
		
	}
	
});


var UI = new UserInterface();

