var Engine = new Class({
	Implements: [Options, Events],
	options: {},
	
	initialize: function(options) {
		this.amount = 1;
		this.username;
		this.widgetStyle;
		this.tweets = {};
		this.timer;
		
		this.usernameEl = $('username');
		this.amountEl 	= $('amount');
		this.pluralEl 	= $('plural');
		this.widgetEl 	= $('widget-content');
		this.widgets 	= $$('#widgets a');
		this.copyWidget = $('copy-widget');
		this.modal 		= $('widget-modal');
		this.close 		= $('close-modal');
		this.key 		= $('dummy-helper');
		// this.sig 		= $$('.widgetSig');
		this.text 		= $$('.widgetText');
		this.generator 	= $('generator');
		this.step 		= {
			first: 	$('step-1'),
			second: $('step-2'),
			third: 	$('step-3')
		};
		this.allSteps 	= $$(this.step.first, this.step.second, this.step.third);

		this.prepareTurkey();
		this.setTweetAmount();
		this.setUsername();
		this.setWidget();
		this.showWidget();
		this.closeModal();
	},
	
	// set all styles and states that can't be set from within the css/structure
	prepareTurkey: function() {
	
		// reset plural element
		this.pluralEl.setStyle('opacity', 0);
		
		// reset the amount value
		this.amountEl.set('value', 1);
		
		// reset the username element value
		this.usernameEl.set('value', '');
		
		// focus the username element on load
		this.usernameEl.focus();
		
		// hide non-initial steps
		$$(this.step.second, this.step.third).set('styles', {
			opacity: 0,
			top: -20
		});
		
		// hide modal
		this.modal.setStyle('opacity', 0);
		
		// set the transition
		$$(this.step.second, this.step.third, this.modal).set('morph', {transition: 'quad:out'});
		
		// check if we're dealing with windows loosers
		if(Browser.Platform.mac) this.key.set('text', 'CMD');
		
		// void submits
		this.generator.addEvent('submit', function(e){e.stop();});
		
		// injects the enhanced mac version
		if(Browser.Platform.mac) {
			new Asset.css('static/css/mac.css');
		}
	},
	
	// store the tweets
	requestedTweets: function(tweets) {
		this.tweets = tweets;
	},
	
	// fetch the JSON
	requestTweet: function() {
		new Asset.javascript('http://twitter.com/statuses/user_timeline/'+this.username+'.json?callback=LastTweet.requestedTweets&count=1', {
			onload: function() {
						
				// hide the text
				$$(this.text).fade('out');
				
				// change the tweet and fade in, with a delay
				(function() {
					// this.sig.set('text', this.tweets[0].user.name);
					this.text.set('text', this.tweets[0].text);
					$$(this.text).fade('in');
				}).delay(500, this);
			}.bind(this)
		});
	},
	
	// store the amount of tweets
	setTweetAmount: function() {
		this.amountEl.addEvent('change', function(el) {
		
			// store the amount
			this.amount = $(el.target).value;
			
			// add plural version if needed
			this.pluralEl.fade((this.amount > 1 ? 'in' : 'out'));
		}.bind(this));
	},
	
	// store the username
	setUsername: function() {
		this.usernameEl.addEvent('keyup', function(el) {
	
			// store the username
			this.username = $(el.target).value;
						
			if(this.username.length >= 1) {
				$clear(this.timer);
				
				this.timer = this.requestTweet.delay(2000, this);
				
				//console.log(this.tweets)
			
				// show the second step
				this.step.second.morph({
					opacity: 1,
					top: 0
				});	
				
				// update the sig with the username
				// this.sig.set('text', this.username);				
			} else {
			
				// hide 2nd and 3rd step when no username
				$$(this.step.second, this.step.third).morph({
					opacity: 0,
					top: -20
				});	
				
				// activate the second step
				$$('h3')[1].tween('opacity', 1);
			}
			
			// toggle steps
			$$('h3')[0].tween('opacity', (this.username.length >= 2 ? 0.3 : 1));
		}.bind(this));
	},
	
	setWidget: function() {
		this.widgets.each(function(widget) {
		
			// get the container
			var widgetCont = widget.getParent();	
			
			// show the final step
			widget.addEvent('click', function(e) {				
				switch(widgetCont.get('id')) {
					case 'widget-1':
						this.widgetStyle = '1';
						break;
					case 'widget-2':
						this.widgetStyle = '2';
						break;
					case 'widget-3':
						this.widgetStyle = '3';
						break;
					case 'widget-4':
						this.widgetStyle = '4';
						break;
					default:
						this.widgetStyle = '1';
				}
				
				this.widgets.each(function(w) {
					if(widget != w) {
						if(Browser.Engine.webkit) {
							w.getParent().style['-webkit-transform'] = 'scale(0.8)';
							w.getParent().style.opacity = '.4';
						} else {
							w.tween('opacity', 0.4);
						}
					} else {
						if(Browser.Engine.webkit) {
							w.getParent().style['-webkit-transform'] = 'scale(1) rotate(' + $random(-4, 4) + 'deg)';
							w.getParent().style.opacity = '1';
						} else {
							w.tween('opacity', 1);
						}
					}
				});
				
				this.showFinalStep();
				e.stop();
			}.bind(this));
		}, this);
	},
	
	// fade in the final step when all conditions are a-ok
	showFinalStep: function() {
		if(this.amount && this.username && this.widgetStyle) {
		
			// dim out the second step
			$$('h3')[1].tween('opacity', 0.3);
			
			// show the third step
			this.step.third.morph({
				opacity: 1,
				top: 0
			});
		}
	},
	
	// generate the freaking widget
	generateWidget: function() {
		
		this.widgetStyle = this.widgetStyle.replace(/(widget-)/g, "");

		new Request({
			url: 'get-widget/' + this.username + '/' + this.amount + '/' + this.widgetStyle,
			method: 'post',
			onComplete: function(response) {

				// print the widget inside the textarea
				this.widgetEl.set('value', response);
				
				// we need to delay that, otherwise it'll try to focus a non-existant element
				(function() {
					this.widgetEl.focus();
					this.widgetEl.select();
				}).delay(100, this);
				
			}.bind(this)
		}).send();		
	},
	
	// appear the modal with the widget - WHATUP!
	showWidget: function() {
		this.copyWidget.addEvent('click', function(e) {
		
			// generate the widget
			this.generateWidget();
			
			// show the modal
			this.modal.morph({
				top: [150, 200],
				opacity: 1
			});
			
			// hide the steps
			this.allSteps.morph({
				opacity: 0,
				top: 0
			});	
			e.stop();
		}.bind(this));
	},
	
	closeModal: function() {
		this.close.addEvent('click', function(e) {
		
			// focus the username input
			(function() {
				this.usernameEl.focus();
				this.usernameEl.select();
			}).delay(100, this);
			
		
			// hide the modal
			this.modal.morph({
				top: [200, 250],
				opacity: 0
			});

			// show the steps
			this.allSteps.tween('opacity', 1);	
			
			// this is clearly a MooTools bug as EVENT should be passed when fired remotely
			if(e) e.stop();
		}.bind(this));
		
		// close the modal when ESCAPE is pressed
		window.addEvent('keyup', function(e) {
			if(e.key.contains('esc')) {
				this.close.fireEvent('click');
			}
		}.bind(this));
	}
});