/**
 * @author bentaber
 * @requires Events, Element, WSODPeople, QuoteRotator, Fader
 */

 var Speedometer = function() {
 	this.currentSpeed = 0;
	this.currentSpeedIdx = 0;
	this.vehicles = [];
	this.timeouts = [];
	this.fader = new Fader();
	
	this.elSpeedometer = Element.get(this.EL_SPEEDOMETER_ID);
	this.elSpeedometerPos = Element.getXY(this.elSpeedometer);
	this.elSpeedometerSize = Element.getSize(this.elSpeedometer);
	
	this.attachEventHandlers();
 };
 
 Speedometer.prototype.EL_SPEEDOMETER_ID = "speedometer";
 Speedometer.prototype.DISPLAY_TIME = 1500;
 Speedometer.prototype.MOUSEOUT_WAIT_TIME = 10;
 
 Speedometer.prototype.SPEEDS = [{
	label: "Slow",
	cssClass: "speed-0",
	interval: Fader.prototype.INTERVAL,
	frameTime: Fader.prototype.FRAME_TIME,
	peopleMinFaceTime: WSODPeople.prototype.MIN_FACE_TIME,
	peopleMaxFaceTime: WSODPeople.prototype.MAX_FACE_TIME,
	quoteInterval: QuoteRotator.prototype.FADER_INTERVAL,
	quoteFrameTime: QuoteRotator.prototype.FADER_FRAME_TIME,
	quoteDisplayTime: QuoteRotator.prototype.QUOTE_DISPLAY_TIME
}, {
	label: "Medium",
	cssClass: "speed-3",
	interval: 25,
	frameTime: 5,
	peopleMinFaceTime: 3,
	peopleMaxFaceTime: 9,
	quoteDisplayTime: 2500
}, {
	label: "Fast",
	cssClass: "speed-6",
	interval: 25,
	frameTime: 2,
	peopleMinFaceTime: 1,
	peopleMaxFaceTime: 5,
	quoteDisplayTime: 1000
}, {
	label: "Really fast",
	cssClass: "speed-9",
	interval: 100,
	frameTime: 1,
	peopleMinFaceTime: 0,
	peopleMaxFaceTime: 2,
	quoteDisplayTime: 500
}, {
	label: "But it goes to eleven",
	cssClass: "speed-11",
	interval: 100,
	frameTime: 1,
	peopleMinFaceTime: 0,
	peopleMaxFaceTime: .5,
	quoteDisplayTime: 100
}];

Speedometer.prototype.attachEventHandlers = function() {
	/*
	Events.add({
		element: document,
		type: "click",
		handler: this.accelerate,
		context: this
	});
	*/
	Events.add({
		element: this.elSpeedometer,
		type: "mouseover",
		handler: this.show,
		context: this
	});
	
	Events.add({
		element: this.elSpeedometer,
		type: "mouseout",
		handler: this.hide,
		data: { time: this.MOUSEOUT_WAIT_TIME },
		context: this
	});
	
	Events.add({
		element: this.elSpeedometer,
		type: "mousedown",
		handler: this.startKnobTurn,
		context: this
	});
};

Speedometer.prototype.addVehicle = function(vehicle) {
	this.vehicles.push(vehicle);
};

Speedometer.prototype.accelerate = function(direction) {
	if (isNaN(direction)) {
		Events.cancel(direction);
		direction = 1;	
	}
	
	this.reset();
	this.currentSpeedIdx = Math.abs((this.currentSpeed += direction) % this.SPEEDS.length);
	var speed = this.SPEEDS[this.currentSpeedIdx];
	
	Element.removeClass(this.elSpeedometer, this.elSpeedometer.className);
	Element.addClass(this.elSpeedometer, speed.cssClass);
	this.show();
	
	for (var i=0; i<this.vehicles.length; i++) {
		this.vehicles[i].setSpeed(speed);
	}
	
	if (!this.isMousedOver) {
		this.hide(null, null, { time: this.DISPLAY_TIME });
	}
};

Speedometer.prototype.startKnobTurn = function(e, el, data) {
	Events.cancel(e);
	
	Events.disableTextSelect();
	
	this.lastMousePos =  {
		x: e.clientX - this.elSpeedometerPos.x,
		y: e.clientY - this.elSpeedometerPos.y
	};
	
	Events.add({
		element: document,
		type: "mousemove",
		handler: this.turnKnob,
		context: this	
	});
	
	Events.add({
		element: document,
		type: "mouseup",
		handler: this.stopKnobTurn,
		context: this
	});
	
};

Speedometer.prototype.turnKnob = function(e, el, data) {
	var pos = {
		x: e.clientX - this.elSpeedometerPos.x,
		y: e.clientY - this.elSpeedometerPos.y
	};
	
	if (Math.abs(pos.y - this.lastMousePos.y) < 7) { //} && Math.abs(pos.x - this.lastMousePos.x) < 10) {
		return;
	}
	
	var isLeftHalf = (pos.x <= (this.elSpeedometerSize.width*.5));
	//var movementLeft = (pos.x <= this.lastMousePos.x);
	var movementUp = (pos.y <= this.lastMousePos.y);
	
	var knobIsLeftHalf = (this.currentSpeedIdx+1) < (this.SPEEDS.length/2);
	
	if (isLeftHalf) {
		this.accelerate((movementUp) ? 1 : -1); 
	}
	else {
		this.accelerate((!movementUp) ? 1 : -1); 
	}
	
	this.lastMousePos = pos;
};

Speedometer.prototype.stopKnobTurn = function(e, el, data) {
	Events.cancel(e); // prevent click from firing?
	
	Events.enableTextSelect();
	Events.remove(document, "mousemove");
	Events.remove(document, "mouseup");
};

Speedometer.prototype.show = function(e, el, data) {
	if (el == this.elSpeedometer) {	
		this.isMousedOver = true;
	}
	
	this.reset();	
	Element.setOpacity(this.elSpeedometer, this.fader.FINISH_OPACITY);
};

Speedometer.prototype.hide = function(e, el, data) {
	if (el == this.elSpeedometer) {
		this.isMousedOver = false;
	}
	
	if (!this.isMousedOver) {
		var theSpeedometer = this;
		this.timeouts.push(setTimeout(
			function() {
				theSpeedometer.fader.fadeOut(theSpeedometer.elSpeedometer);
			},
			data.time
		));
	}
};

Speedometer.prototype.reset = function() {
	this.fader.clearFadeTimeouts();
	
	for (var i=0; i<this.timeouts.length; i++) {
		clearTimeout(this.timeouts[i]);
	}
	this.timeouts = [];
};
