var Modes = new Abstract({

	start: function() {
		this.element = $('jdModes');
		this.parent = this.element.getParent();
		this.children = this.element.getChildren().clone();
		this.step = 0;
		this.descrip = $('descrip');
		this.nextModeButton = $('nextModeButton');
		this.nextModeButtonTitle = $('nextModeButtonTitle');
		
		this.modes = [{
			desc: '<h3>Cycle Mode</h3><br />A slow progression through the entire spectrum.<dl><dt>Customize speed:</dt><dd>slow</dd><dd>medium</dd><dd>fast</dd><dt>Customize brightness</dt><dd>3 brightness levels</dd></dl>',
			title: 'next is rainbow mode',
			func: this.showCycle
		}, {
			desc: '<h3>Rainbow mode</h3><br />All the colors of the rainbow, slowly flowing from the base to the top.<dl><dt>Customize:</dt><dd>freeze the rainbow on your favorite blend</dd><dd>resume the rainbow</dd><dt>Customize brightness</dt><dd>3 brightness levels</dd></dl>',
			title: 'next is eq mode',
			func: this.showRainbow
		}, {
			desc: '<h3>EQ mode</h3><br />An exciting, pulsing level meter tuned to the volume of the music playing through your iPod.',
			title: 'next is steady mode',
			func: this.showEq
		}, {
			desc: '<h3>Steady mode</h3><br />Just your favorite, steady color. Customize by scanning through all the colors in JukeDock\'s spectrum.  Experiment online by sliding the knob below to tune.<div class="track"><div class="knob"></div></div><dt>Customize brightness</dt><dd>3 brightness levels</dd>',
			title: 'next is all JukeDoc lights off',
			func: this.showSteady
		}, {
			desc: '<h3>Off mode</h3><br />When you\'re not in the mood to be entertained or relaxed by JukeDock\'s lights, simply turn them off.  All iPod-related features continue uninterrupted.',
			title: 'next is cycle mode',
			func: this.showOff
		}];

		this.nextModeButton.addEvent('click', this.showNextMode.bindWithEvent(this)); 
		this.showCycle();
	},
	
	showCycle: function() {
		this.fx = new Fx.Rainbow(this.parent, 'background-color').set('#00f');
		this.func = function() {
			this.fx.start().chain(this.func);
		}.bind(this);
		this.timer = this.func.delay(0);
	},
	
	showRainbow: function() {
		var rainbow = this.children.clone().injectInside(this.element);

		this.fx = [];
		this.func = [];
		this.timer = [];
		rainbow.each(function(el, i) {
			this.fx[i] = el.fx = new Fx.Rainbow(el, 'background-color');
			this.func[i] = function() {
				el.fx.set(el.fx.now || this.parent.getStyle('background-color')).start().chain(this.func[i]);
			}.bind(this);
			this.timer[i] = this.func[i].delay(1350 - 400 * i);
		}, this);
	},
	
	showEq: function() {
		var eqs = this.children.clone().injectInside(this.element);
		var states = ['#fff', '#0f0','#ff0','#f00'];
		var that = this;
		this.func = function() {
			for(var i = 0; i < $random(0,3); i++) {
				eqs[2 - i].setStyle('background-color', states[i + 1]);
			}
			for(var j = i; j < 3; j++) {
				eqs[2 - j].setStyle('background-color', states[0]);
			}
			
			that.timer = that.func.delay(250);
		};
		this.func();
	},

	showSteady: function() {
		var transition =  function(p, d) {
			p = (p + d) % .4;
			var m = 10, yint = 0;
			if(p > .2) m = -10, yint = 3;
			return (256*(m * p + yint)).limit(0,255);
		};
		var steady = this.parent.setStyle('background-color', [ 
			Math.round(transition(0, 0.1)),
			Math.round(transition(0, 0.0)),
			Math.round(transition(0, 0.3))
		].rgbToHex());
		var track = this.descrip.getElement('.track');
		var knob = this.descrip.getElement('.knob');
		
		this.slider = new Slider(track, knob, {
			steps: 100,	
			onChange: function(pos) {
				pos /= 250;
				this.parent.setStyle('background-color', [ 
					Math.round(transition(pos, 0.1)),
					Math.round(transition(pos, 0.0)),
					Math.round(transition(pos, 0.3))
				].rgbToHex());
			}.bind(this)
		});
	},
	
	showOff: function() {
		this.element.getParent().setStyle('background-color', '#000');
	},
	
	showNextMode: function(e) {
		e.stop();
		this.step = ++this.step % this.modes.length;
		this.clear();
		var curState = this.modes[this.step];
		this.descrip.setHTML(curState.desc);
		this.nextModeButtonTitle.setProperty('title', curState.title);
		this.element.empty();
		curState.func.call(this);
	},
	
	clear: function() {
		if(this.timer) {
			if(!this.timer.push) $clear(this.timer);
			else this.timer.each(function(timer, i) { $clear(this.timer[i]); }, this);
		}
		
		if(this.fx) {
			if(!this.fx.push) this.fx.stop();
			else this.fx.each(function(fx, i) { this.fx[i].stop(); }, this);
		}
		this.fx = null;
		if(!this.func.push) this.func = Class.empty;
		else this.func.each(function(func, i) { this.func[i] = Class.empty; }, this);
	}
	
});

window.addEvent('domready', function(){
	Modes.start();
});
