;var craneClass = function(options){

	var _this = this;
	this.port = options.port;
	this.id = options.id;
	var crane = {} // Вся информация о кране (изменяется в процессе)
	this.stack = []; // Стек работы крана (обнуляется с каждым новым кораблем)
	this.lastCallback = function(){};
	this.craneOffset = false;
	this.stackInit = function(){
	}
	
	this.clearStack = function(){
		this.stack = [];
	}
	
	this.processingStack = function(callback){
		_this.craneOffset = false;
		if(this.stack.length < 1){
			if(typeof callback == 'function') callback();
			this.goToSleep();
			return;
		}
		var $cargo = this.stack.shift();
		var target_holder_id = $cargo.data('target_holder_id');
		if(typeof target_holder_id == 'string'){
			var $target = $(target_holder_id+':first');
		}else{
			if($cargo.hasClass('type4')){
				var $target = $('#'+$cargo.data('target')+' .cargo-holder:first');
			}else{
				var $target = $('#'+$cargo.data('target')+' .cargo-holder:empty:first');		
			}
		}
		if($target.length < 1){ // Если есть цель отвеозим на нее груз
			this.processingStack(callback);
			return;	
		}
		_this.goToCargo($cargo,function(){ // Едем за грузом
			_this.grabCargo($cargo, function(){ // Берем груз
				if($cargo.hasClass('type4')) _this.craneOffset = ($cargo.hasClass('position0')) ? -42 : ($cargo.hasClass('position1')) ? -12 : ($cargo.hasClass('position2')) ? +24 : false;

				_this.goToCargo($target,function(){ // Едем за грузом
					_this.dropCargo($cargo, $target, function(){
						$cargo.removeClass('unfinished');
						_this.processingStack(callback);
					});
				});
			});
		});
	}
	return this.init(); // Инициируем кран
}

craneClass.prototype = {
	craneArrowMaxHeight: 247,
	craneArrowMinHeight: 147,

	craneArrowPositionSpeed: 1000, // 3000
	craneArrowPositionEasing: 'linear', //'swing'

	craneRotateSpeed: 8000, // Время полного оборота
	craneStartX: 0,
	craneHolderHeight: 125,
	craneHolderWidth: 125,
	craneMovingEasing: 'easeInOutQuad',
	cargoArrowOffset: 8, // Отступ от конца стрелы
	craneMovingSpeed: 20,


	createCrane: function(id){
		this.$crane = $('<div/>',{'class':'crane-holder','id':this.id});
		this.$craneBase = $('<div/>',{'class':'crane-base'}).appendTo(this.$crane);
		this.$craneShadows = $('<div/>',{'class':'crane-shadows'}).appendTo(this.$crane);
		this.$craneBaseShadow = $('<div/>',{'class':'crane-base-shadow'}).appendTo(this.$craneShadows);
		this.$craneShadowRotator = $('<div/>',{'class':'crane-shadow-rotator'}).appendTo(this.$craneShadows);
		this.$craneArrowShadowHolder = $('<div/>',{'class':'crane-arrow-shadow-holder'}).appendTo(this.$craneShadowRotator);
		this.$craneTowerShadow = $('<div/>',{'class':'crane-tower-shadow'}).appendTo(this.$craneArrowShadowHolder);
		this.$craneArrowShadow = $('<img/>',{'class':'crane-arrow-shadow', 'src':'i/crane-arrow-shadow.png'}).appendTo(this.$craneArrowShadowHolder)
		this.$craneRotator = $('<div/>',{'class':'crane-rotator'}).appendTo(this.$crane);
		this.$craneTowerHolder = $('<div/>',{'class':'crane-tower-holder'}).appendTo(this.$craneRotator);
		this.$craneTower = $('<div/>',{'class':'crane-tower'}).appendTo(this.$craneTowerHolder);
		this.$craneArrow = $('<img/>',{'class':'crane-arrow', 'src':'i/crane-arrow.png'}).appendTo(this.$craneTowerHolder);
		this.$craneGrabber = $('<div/>',{'class':'crane-grabber'}).appendTo(this.$craneTowerHolder);
		this.$craneGrabberShadow = $('<div/>',{'class':'crane-grabber-shadow'}).appendTo(this.$craneArrowShadowHolder);
		this.$crane.appendTo('#crane-moving-area'); // Добавляем кран на страницу
	},	
	init: function(){ // Инициализация крана
		this.createCrane(this.id);
		this.crane = {
			centerOffset: {
				x: this.$craneBase.width() / 2,
				y: this.$craneBase.width() / 2
			},
			base: {
				width: this.$craneBase.width(),
				height: this.$craneBase.height(),
				center: {}
			}
		}
		this.crane.base.center = {
			offsetLeft: this.crane.base.width / 2,
			offsetTop: this.crane.base.height / 2
		}
		var craneStartPosition = 0-300-this.port.globalOffset;
		craneStartPosition = 130; // Начальная позиция крана
		this.$crane.css({left:craneStartPosition});
	},

	arrowPosition: function(pos, callback){
		var newHeight = this.craneArrowMaxHeight - parseInt(pos);
		var speed = this.port.speed(parseInt(this.craneArrowPositionSpeed / (this.craneArrowMaxHeight - this.craneArrowMinHeight)) * Math.abs(this.$craneArrow.height() - pos));
		this.$craneArrowShadow.animate({height: newHeight}, {duration:speed, easing: this.craneArrowPositionEasing});
		this.$craneArrow.animate({height: newHeight}, {duration:speed, easing: this.craneArrowPositionEasing, complete: callback});
	},
	stop: function(){
		this.$craneArrow.stop();
	},
	rotate: function(angle,callback,speed){
		if(typeof speed == 'undefined'){
			var speed = _this.port.speed(parseInt(this.craneRotateSpeed / 360) * angle);
		}
		this.$craneShadowRotator.add(this.$craneRotator).rotate({animateTo:angle, duration: speed, easing: $.easing.easeOutBack });
		this.$craneGrabber.add(this.$craneGrabberShadow).rotate({animateTo:360-angle, duration: speed, easing: $.easing.easeOutQuart });
	},
	grabCargo: function($cargo, callback){
		var _this = this;
		this.$craneGrabber.rotate(this.arrowAngle+90); // Поворачиваем держатель груза под нужный угол
		
		var left = (this.arrowAngle > 90) ? -1 : -1;
		var top = (this.arrowAngle > 90) ? -1 : 0;

		var grabber_offset = this.$craneGrabberShadow.offset();
		
		var $cargo_shadow = $cargo.children('.cargo-shadow');
		var shadow_offset = $cargo_shadow.offset();
		var shadow = {
				width: $cargo_shadow.width(),
				height: $cargo_shadow.height()
			}
			

		var f = {
			left:(grabber_offset.left-shadow_offset.left)-(shadow.width/2),
			top:(grabber_offset.top-shadow_offset.top)-(shadow.height/2),
			opacity:0.7
		}
		var f2 = {
			position:'relative',
			left:0-shadow.width/2,
			top: 0-shadow.height/2,
			opacity:1
		}

		this.currentShadow = $cargo_shadow;

		$cargo_shadow
			.animate(f,_this.port.speed(5000),function(){
				$cargo_shadow.appendTo(_this.$craneGrabberShadow).css(f2);
				if(typeof callback == 'function') callback();
			});

		$cargo
			.css({
				left: left-this.r.cargoCoords.center.x-1,
				top: top-this.r.cargoCoords.center.y + this.cargoArrowOffset-6
			})
			.appendTo(this.$craneGrabber) // Перемещаем груз в держатель груза на кране

		return;
	},
	dropCargo: function($cargo, $target, callback){
		var _this = this;



		var shadow = {
				left: this.currentShadow.width()/2,
				top: this.currentShadow.height()/2
			}

		var current_shadow_offset = this.currentShadow.offset();
		var current_cargo_offset = $cargo.offset();

		var f = {
			left: 0-shadow.left-(current_shadow_offset.left-current_cargo_offset.left),
			top: 0-shadow.top-(current_shadow_offset.top-current_cargo_offset.top)
		};
		
		this.currentShadow.animate(f,_this.port.speed(5000),function(){
			_this.currentShadow.css({left:'',top:''}).removeAttr('style').appendTo($cargo);
			setTimeout(function(){
			if(typeof callback == 'function') callback();
			}, 300);
			

			if($target.parent().hasClass('truck')){
				var $truck = $target.parent();
				var truck = $target.parent().data('class');
//				if($cargo);
				if($cargo.hasClass('type4')){
				
					log('TYPE 4')
					$cargo
						.css({
							left: '',
							top: ''
						})
						.appendTo($target) // Перемещаем груз в держатель груза на кране
					if($truck.find('.cargo.type4').length < 3) return;				
				}
				truck.hide(function(){
					setTimeout(function(){
						if($('.cargo.target-'+truck.id,'#ship').length > 0){
							$target.find('.cargo').remove();
							truck.show();
						}
					}, _this.port.speed(4000));
				});
			}
			$cargo
				.css({
					left: '',
					top: ''
				})
				.appendTo($target) // Перемещаем груз в держатель груза на кране
		})
	},
	thinking: function($cargo){ // Возвращает всю необходимую информацию для позиционирования крана относительно груза
		var _this = this;
		var r = {
			craneCoords: _this.getCraneCoords(), // Получаем координаты центра оси крана
			cargoCoords: _this.getObjectCoords($cargo), // Получаем координаты центра груза
		}
		r.toCargo = {
			distance: Math.floor(Math.abs( this.$craneRotator.height()/2 - this.cargoArrowOffset )), // Расчитываем расстояние от оси крана до центра груза
			y:  r.craneCoords.y - r.cargoCoords.y , // Дистанция до груза по оси Y
		}

		var minArrowLength = (Math.abs(r.toCargo.y) > 155) ? r.toCargo.y : 155;
		var craneArrowRandomLength = Math.randomFromTo(minArrowLength,247);
		r.toCargo.distance = craneArrowRandomLength + this.cargoArrowOffset;
		if(r.toCargo.distance <= Math.abs(r.toCargo.y) ) r.toCargo.distance = Math.randomFromTo(Math.abs(r.toCargo.y),247);
		_this.arrowPosition(this.craneArrowMaxHeight - r.toCargo.distance + this.cargoArrowOffset +11); // Анимируем перемещение крана к грузу

		r.toCargo.x = Math.sqrt( ( r.toCargo.distance * r.toCargo.distance ) - ( r.toCargo.y * r.toCargo.y ) ); // Вычисляем расстояние до центра груза по оси X (квадратный корень гипотенузы равен сумме квадратов катетов)
		this.arrowAngle = ra_de( Math.asin( r.toCargo.y / r.toCargo.distance ) ); // Вычисляем необходимый угол поворота стрелы крана
		r.toCargo.y = Math.abs(r.toCargo.y);
		r.craneDestination = { 
			x: r.cargoCoords.x - r.toCargo.x - this.port.offset.left // Находим нужное положение центра крана на необходимом расстоянии до груза по оси Х
		}

		r.currentCargo = $cargo;
		if(r.cargoCoords.x < r.craneCoords.x){ // Если груз находится левее крана
			this.arrowAngle = Math.abs(this.arrowAngle-180); // Разворачиваем стрелу зеркально относительно горизонтали
			r.craneDestination.x += r.toCargo.x*2; // И сдвигаем кран вправо
		}
		this.r = r;
		return r; // Возвращаемый результат
	},
	goToSleep: function(callback){ // Отправляем кран на позицию для сна
		var _this = this;
		this.arrowAngle = 270; // Задаем поворток крана в позиции для сна
		_this.goTo(130,function(){
			_this.arrowPosition(100,callback); // Анимируем перемещение крана к грузу
		});
	},
	findNextRandomCargo: function(){
		var $cargos = $('#sandbox .cargo');
		var count = $cargos.length;
		return;
	},
	goTo: function(x,callback){
		var offset = this.$crane.position();
		var distance = Math.abs(offset.left - x);
		var speed = this.port.getSpeed(distance, this.craneMovingSpeed);
		var min_speed = this.port.speed(4000);
		if(speed < min_speed) speed = min_speed; // Делаем перемещение не менее 4-х сек
		this.rotate(270-this.arrowAngle,function(){
//			_this.grabCargo();
		},speed);
		this.$crane.animate({left: x}, {duration:speed, easing: this.craneMovingEasing, complete: callback});
	},
	goToCargo: function($cargo, callback){
		var _this = this;
		this.lastCallback = callback;
		if($cargo.length < 1){
			if(typeof callback == 'function') callback();
			return false;
		}
		var i = _this.thinking($cargo); // Расчитываем все данные для анимации
		_this.goTo(i.craneDestination.x-(this.craneHolderWidth / 2 ),function(){
			setTimeout(function(){
				if(typeof callback == 'function') callback();
			}, _this.port.speed(500));
		});
	},
	getCraneCoords: function(){
		var craneOffset = this.$crane.offset();
		var craneCoords = {
			x: parseInt( this.craneStartX + craneOffset.left + ( this.craneHolderWidth  / 2 ) ), // - this.craneStartX
			y: parseInt( craneOffset.top  + ( this.craneHolderHeight / 2 ) )
		};
		return craneCoords;
	},	
	getObjectCoords: function($obj){
		var offset = $obj.offset();
		var center = {
			x: Math.floor($obj.width()/2),
			y: Math.floor($obj.height()/2)
		}
		if(this.craneOffset) center.x += this.craneOffset;
		return {
			'offset': offset,
			'center': center,
			x: parseInt( offset.left + center.x ),
			y: parseInt( offset.top  + center.y )
		};
	}
}
