/**
 * @author Lukas Goldschmift
 */

Namespace.Manager.Register("LG.THREE");

/**
 *
 * @class
 * A little more clever Object ... This class creates a new Object3D.
 * @constructor
 */
LG.THREE.Object3D = new Class({
	Implements : [Options, Events],
	initialize : function() {
		THREE.Object3D.call(this);
	}
});

LG.THREE.Camera = new Class({
	Extends : LG.THREE.Object3D,
	initialize : function(parameters) {
		THREE.Camera.call(this, parameters.fov, parameters.aspect, parameters.near, parameters.far, parameters.target);
	},
	update : function() {

		this.supr.update.call(this);

	}
});

LG.THREE.Camera.prototype = new THREE.Camera();
LG.THREE.Camera.prototype.constructor = LG.THREE.Camera;
LG.THREE.Camera.prototype.supr = THREE.Camera.prototype;
/*
 *
 */
LG.THREE.Controller = new Class({
	Implements : [Options, Events],
	initialize : function() {
		this.domElement.addEventListener('contextmenu', function(event) {
			event.preventDefault();
		}, false);

		this.domElement.addEventListener('mousemove', bind(this, this.onMouseMove), false);
		this.domElement.addEventListener('mousedown', bind(this, this.onMouseDown), false);
		this.domElement.addEventListener('mouseup', bind(this, this.onMouseUp), false);
		this.domElement.addEventListener('keydown', bind(this, this.onKeyDown), false);
		this.domElement.addEventListener('keyup', bind(this, this.onKeyUp), false);

		function bind(scope, fn) {

			return function() {

				fn.apply(scope, arguments);

			};
		};

	},
	onMouseDown : function(event) {
		if(event.clientX > this.Browser.offset.left && event.clientX < this.Browser.offset.left + this.Browser.width) {
			if(event.clientY > this.Browser.offset.top && event.clientY < this.Browser.offset.top + this.Browser.height) {
				event.preventDefault();
				event.stopPropagation();
				this.onMouseDownTheta = this.theta;
				this.onMouseDownPhi = this.phi;
				//this.onMouseDownPosition.x = event.clientX - this.Browser.offset.left ;
				//this.onMouseDownPosition.y = event.clientY - this.Browser.offset.top;
				//		event.preventDefault();
				//this.activeLook=true;

				if(this.activeLook) {

					switch ( event.button ) {

						case 0:
							this.moveForward = true;
							break;
						case 2:
							this.moveBackward = true;
							break;

					}

				}

				this.mouseDragOn = true;
			} else {
				return;
			}
		} else {
			return;
		}

		//		this.mouseDragOn = true;

	},
	onMouseUp : function(event) {

		event.preventDefault();
		//		event.stopPropagation();

		if(this.activeLook) {

			switch ( event.button ) {

				case 0:
					this.moveForward = false;
					break;
				case 2:
					this.moveBackward = false;
					break;

			}

		}

		this.mouseDragOn = false;
	},
	onMouseMove : function(event) {
		this.mouseX = event.clientX - this.Browser.offset.left - this.Browser.width / 2;
		this.mouseY = event.clientY - this.Browser.offset.top - this.Browser.height / 2;

	},
	onKeyDown : function(event) {

		switch( event.keyCode ) {

			case 38:
			/*up*/
			case 87:
				/*W*/
				this.moveForward = true;
				break;

			case 37:
			/*left*/
			case 65:
				/*A*/
				this.moveLeft = true;
				break;

			case 40:
			/*down*/
			case 83:
				/*S*/
				this.moveBackward = true;
				break;

			case 39:
			/*right*/
			case 68:
				/*D*/
				this.moveRight = true;
				break;

			case 81:
				this.freeze = !this.freeze;
				break;
			case 16:
				this.isShiftDown = true;
				this.activeLook = true;
				break;
		}

	},
	onKeyUp : function(event) {

		switch( event.keyCode ) {

			case 38:
			/*up*/
			case 87:
				/*W*/
				this.moveForward = false;
				break;

			case 37:
			/*left*/
			case 65:
				/*A*/
				this.moveLeft = false;
				break;

			case 40:
			/*down*/
			case 83:
				/*S*/
				this.moveBackward = false;
				break;

			case 39:
			/*right*/
			case 68:
				/*D*/
				this.moveRight = false;
				break;
			case 16:
				this.isShiftDown = false;
				this.activeLook = false;
				break;

		}

	},
});

function bind(scope, fn) {

	return function() {

		fn.apply(scope, arguments);

	};
};

function map_linear(x, sa, sb, ea, eb) {

	return (x - sa ) * (eb - ea ) / (sb - sa ) + ea;

};

function clamp_bottom(x, a) {

	return x < a ? a : x;

};

function clamp(x, a, b) {

	return x < a ? a : (x > b ? b : x );

};