
// ----- WARNING ----- \\
// COPYRIGHTED CONTENT \\
//  COPYRIGHT © NERVA  \\
//   nerva@nerva.ee    \\
// All rights reserved \\
// ------------------- \\

var mov_objects = new Array();

function mov_getposition(obj) { // returns rect(left, top, width, height)
	var pos = new Array(0, 0, 0, 0);
	if (obj != null) {
		pos[2] = obj.offsetWidth;
		pos[3] = obj.offsetHeight;
	  }
	while (obj != null) {
		pos[0] += obj.offsetLeft;
		pos[1] += obj.offsetTop;
		obj = obj.offsetParent;
		}
	return pos;
  }

function mov_object(object) { // object must have absolute position calculated from the page (position must be set by style's left and top)
	this.object = object;
	this.friend = null;
	this.destx = 0;
	this.desty = 0;
	this.x = 0;
	this.y = 0;
	this.w = this.object.offsetWidth;
	this.h = this.object.offsetHeight;
	this.line = 0;
	this.active = false;
	this.speed = 6;
	this.readposition = mov_object_readposition;
	this.movecloser = mov_object_movecloser;
	this.loop = mov_object_loop;
	this.calculatestep = mov_object_calculatestep;
	this.move = mov_object_move;
	this.movenow = mov_object_movenow; // for immediate move (no animation)
	this.emptyx = mov_object_emptyx;
  }

function mov_object_readposition() {
	this.x = 0;
	this.y = 0;
	var obj = this.object;
	while (obj != null) {
		this.x += obj.offsetLeft;
		this.y += obj.offsetTop;
		obj = obj.offsetParent;
		}
  }

function mov_object_calculatestep(z, destz) {
	if (z < destz) return Math.max(Math.ceil(((destz - z) * this.speed) / 16), 1);
	if (z > destz) return -Math.max(Math.ceil(((z - destz) * this.speed) / 16), 1);
	return 0;
  }

function mov_object_movecloser() { // returns true if object was moved
  var m = false;
	var z = this.calculatestep(this.y, this.desty);
	if (z != 0) {
		this.y += z;
		this.object.style.top = "" + this.y + "px";
		m = true;
	  }
	z = this.calculatestep(this.x, this.destx);
	if (z != 0) {
		this.x += z;
		this.object.style.left = "" + this.x + "px";
		m = true;
	  }
  return m;
  }

function mov_object_loop() {
	if (this.movecloser()) {
		var thisObj = this;
		setTimeout(function() { thisObj.loop.call(thisObj); }, 1);
	  }
	else {
		this.active = false;
	  }
  }

function mov_object_move(destx, desty, line, friend) {
	this.destx = destx;
	this.desty = desty;
	this.line = ((line != null) ? line : null);
	this.friend = ((friend != null) ? friend : null);
	if (!this.active) {
	  this.active = true;
		this.readposition();
		this.loop();
	  }
  }

function mov_object_movenow(destx, desty, line, friend) {
	this.destx = destx;
	this.desty = desty;
	this.line = ((line != null) ? line : null);
	this.friend = ((friend != null) ? friend : null);
	if (this.active) this.active = false;
	this.x = destx;
	this.y = desty;
	this.object.style.left = "" + this.x + "px";
	this.object.style.top = "" + this.y + "px";
  }

function rect_collapse(x1, y1, w1, h1, x2, y2, w2, h2) {
	return (((x1 + w1) > x2) && (x1 < (x2 + w2)) && ((y1 + h1) > y2) && (y1 < (y2 + h2)));
  }

function line_collapse(z1, l1, z2, l2) {
	return (((z1 + l1) > z2) && (z1 < (z2 + l2)));
  }

function mov_object_emptyx(left, right, line) {
	var i, j, x, o, collapse;
	for (j = 0; j < 100; j++) { // limit searching up to 100 attempts, to avoid infinite loop in case of small windows
	  x = (left + Math.round(Math.random() * (right - left - this.w)));
		collapse = false;
		for (i = 0; i < mov_objects.length; i++) {
			o = mov_objects[i];
			if (i == this) continue;
			if (o.line != line) continue;
			if (line_collapse(x, this.w, o.destx, o.w)) {
				collapse = true;
				break;
			  }
			}
		if (!collapse) return x;
	  }
	return x;
  }

function mov_anyactive() {
	var i;
	for (i = 0; i < mov_objects.length; i++) {
		if (mov_objects[i].active) return true;
	  }
	return false;
  }

function mov_find(object) {
	var i;
	for (i = 0; i < mov_objects.length; i++) {
		if (mov_objects[i].object == object) return mov_objects[i];
	  }
	return null;
  }

function mov_add(object) {
	var mov = new mov_object(object);
	mov_objects[mov_objects.length] = mov;
  return mov;
  }

function mov_move(object, destx, desty, immediately) { // a simple all-in-one method (not used for moving creatures)
	if (object == null) return false;
	var mov = mov_find(object);
	if (mov == null) mov = mov_add(object);
	if (immediately) {
	  mov.movenow(destx, desty, null, null);
	  }
	else {
	  mov.move(destx, desty, null, null);
	  }
  }

