function Movement(oMov, timer){
	this.moveable = moveable.detectMoveable(oMov);
	this.moveable.movement = this;
	this.stepX = 0;
	this.stepY = 0;
	this.timer = Timer.detectTimer(timer);
	this.distance = false;
	this.moveSpace = false;
	this.STOP_ON_FIRST = true;
	this.direction = "";
	this._events = [
		{name: "start", func_name: "start"},	
		{name: "stop", func_name: "stop"},
		{name: "movetostart", func_name: "_moveTo"}
	];
	this.refreshCount = 0;
	this.IS_MOVING = false;
	this.onreach = new DOMEvent();
	this.onreach.register(
		Movement.defaultOnReach.name,
		Movement.defaultOnReach.func.bind(this)
	);
	this.init();
	if(this.constructor._TO_INSTANCES){
		this.constructor._instances.push(this);
	}
}
Movement.prototype.initEvents = _initEvents;
Movement.prototype.init = function(){
	this.initEvents();
	this.onmove = DOMEvent.cloneEvent(this.moveable.onmove, this);
	if(this.timer._MUTUAL){
		if(this.timer.registerMovement){
			this.timer.registerMovement(this);
		}else{	
			Movement.handleMutualTimer(this.timer);
			this.timer.registerMovement(this);
		}
	}else{
		this.timer.registerEvent(
		{
			name: "Movement",
			func: function(objMoveable){
				objMoveable.moveBy(this.stepX, this.stepY);
			},
			oThis: this,
			args: [this.moveable]
		}
		);
	}
};
Movement.prototype.start = function(){
	this.IS_MOVING = true;
	if(!this.timer._MUTUAL){
		this.timer.start();
	}
};
Movement.prototype.stop = function(){
	this.IS_MOVING = false;
	if(!this.timer._MUTUAL){
		this.timer.clear();
	}
};
Movement.prototype.toggle = function(){
	if(this.IS_MOVING){
		this.stop();
	}else{
		this.start();
	}
};
Movement.prototype.setSteps = function(x, y){
	this.stepX = x ? x : 0;
	this.stepY = y ? y : 0;
	var d1, d2;
	with(Movement._directions){
		d1 = x >= 0 ? east.dir : west.dir;
		d2 = y >= 0 ? south.dir : north.dir;
	}
	this.direction = d1 + "-" + d2;
};
Movement.prototype.setLimits = function(type, value, startValue){
	this.moveable.setLimits(type, value, startValue);
	var PRESETS = moveable.LIMITS[type];
	this[PRESETS.onless] = DOMEvent.cloneEvent(this.moveable[PRESETS.onless], this);
	this[PRESETS.onmore] = DOMEvent.cloneEvent(this.moveable[PRESETS.onmore], this);
};
Movement.prototype.unsetLimits = function(type){
	this.moveable.unsetLimits(type);
};
Movement.prototype.setMoveSpace = function(X, Y, sX, sY){
	this.moveSpace = this.moveable.setMoveSpace(X, Y, sX, sY);
	if(!this.onmovespacereach){
		this.onmovespacereach = DOMEvent.cloneEvent(this.moveable.onmovespacereach, this);
	}
};
Movement.prototype.moveTo = function(x, y, speed){
	speed = speed ? speed : 3;
	var curLeft = this.moveable.left;
	var curTop = this.moveable.top;
	var nextLeft = x;
	var nextTop = y;
	var distX = nextLeft - curLeft;
	var distY = nextTop - curTop;
	var biggerDist = Math.abs(distX) > Math.abs(distY) ? distX : distY;
	var numOfSteps = Math.abs(Math.round(biggerDist / speed));
	if(numOfSteps == 0){
		return false;
	}
	var stepX = distX / numOfSteps;
	var stepY = distY / numOfSteps;
	this.mt_stepCount = 0;
	this.mt_numOfSteps = numOfSteps;
	this.distY = distY;
	this.distX = distX;
	this.moveToX = nextLeft;
	this.moveToY = nextTop;
	this.setSteps(stepX, stepY);
	this.X_REACHED = false;
	this.Y_REACHED = false;
	this.moveable.onmove._break = this.stopMoveTo.bind(this);
	this._moveTo();

};
Movement.prototype._moveTo = function(){
	this.moveable.movedToX = 0;
	this.moveable.movedToY = 0;
	this.moveable.onmove.remove('move-to');
	this.moveable.onmove.register(
		'move-to',
		function(oM){
			if(Math.abs(this.movedToX + this.moveX ) >= Math.abs(oM.distX)){
				var mX = this.moveX;
				this.moveX = Math.floor((Math.abs(oM.distX) - Math.abs(this.movedToX))) * this.moveX.signOf();
				oM.X_REACHED = true;
				this.correctLimit("X", mX);
			}
			if(Math.abs(this.movedToY + this.moveY ) >= Math.abs(oM.distY)){
				var mY = this.moveY;
				this.moveY = Math.floor((Math.abs(oM.distY) - Math.abs(this.movedToY))) * this.moveY.signOf();
				oM.Y_REACHED = true;
				this.correctLimit("Y", mY);
			}
			this.movedToX += this.moveX;
			this.movedToY += this.moveY;
			oM.mt_stepCount++;
			if(oM.X_REACHED && oM.Y_REACHED){
				this.onaftermove.register(
					'move-to-stop',
					function(){
						this.onreach.fire();
					}.bind(oM),
					1
				);
			}
		}.bind(this.moveable, this)
	);
	if(!this.IS_MOVING){
		this.start();
	}
};
Movement.prototype.stopMoveTo = function(){
	this.moveable.onmove.remove('move-to');
	this.stop();
};
Movement.prototype.moveDistance = function(distance, direction, numOfSteps){
	this.distanceMoved = 0;
	this.Distance = distance;
	this.DistanceStep = this.Distance / numOfSteps;
	this.stepType = (direction == "left" || direction == "right" ) ? "X" : "Y";
	if(direction == 'left'){
		this.setSteps(-this.DistanceStep, 0);
	}else if(direction == 'right'){
		this.setSteps(this.DistanceStep, 0);
	}else if(direction == 'top'){
		this.setSteps(0, -this.DistanceStep);
	}else if(direction == 'bottom'){
		this.setSteps(0, this.DistanceStep);
	}
	this.onmove.register("distance-check", function(oM){
		var step_sign = oM["move" + this.stepType].signOf();
		var step = Math.abs(oM["move" + this.stepType]);
		if(this.distanceMoved + step >= this.Distance){
			var new_step = this.Distance - this.distanceMoved;
			oM["move" + this.stepType] = new_step * step_sign;
			oM.onaftermove.register("stop", function(){
				this.stop();
				this.onmove.remove("distance-check");
			}.bind(this), 1);
			step = new_step;
		}
		this.distanceMoved += step;

	}.bind(this, this.moveable));
	this.start();
};
Movement.prototype.__name = "Movement";
Movement.prototype.toString = __toString;
Movement.defaultOnReach = {
	name: 'onreach',
	func: function(){
		this.stopMoveTo();
	}
};
Movement.mutualTimer = null;
Movement.handleMutualTimer = function(oTimer){
	oTimer.movements = [];
	oTimer.registerMovement = function(objMovement){
		this.movements.push(objMovement)
	};
	oTimer.registerEvent(
		{
			name: "Movement",
			func: function(){
				this.movements.each(function(mov){
					if(mov.IS_MOVING){
						mov.moveable.moveBy(mov.stepX, mov.stepY);
					}
				});
			},
			oThis: oTimer,
			args: []
		}
	);	
};
Movement._directions = {
	west: {geo: "W", dir: "left", num: 4},
	north: {geo: "N", dir: "top", num: 1},
	east: {geo: "E", dir: "right", num: 2},
	south: {geo: "S", dir: "bottom", num: 2}
};
Movement._TO_INSTANCES = true;
Movement._instances = [];