params ["_heli", ["_action", ""], ["_payloadClass", "BRAF_Rescue_Seat"]];

[_heli, _action, _payloadClass] spawn {
	params ["_heli", "_action", "_payloadClass"];

	private _initialLength = 0.25;
	private _targetLength = 25;
	private _recoveryLength = 3.1;
	private _duration = 16;

	switch (toLower _action) do {
		case "deploy": {
			private _spentPayloads = _heli getVariable ["braf_hoist_spent_payloads", []];

			if (_payloadClass in _spentPayloads) exitWith {
				_heli vehicleChat "Rescue Payload Expended";
			};

			private _oldRope = _heli getVariable ["hoistrope", objNull];
			private _oldPayload = _heli getVariable ["rescueseat", objNull];

			if (!isNull _oldRope) then {
				ropeDestroy _oldRope;
			};

			if (!isNull _oldPayload) then {
				deleteVehicle _oldPayload;
			};

			sleep 1;

			_heli vehicleChat "Deploying Rescue Payload";

			private _payload = _payloadClass createVehicle [0, 0, 0];
			_payload setDir (getDir _heli);
			_payload setPosASL (_heli modelToWorld [0, 0, -1.5]);

			private _rope = ropeCreate [_heli, "rope_start", _payload, "hoist_point", _initialLength];

			_heli setVariable ["rescueseat", _payload];
			_heli setVariable ["hoistrope", _rope];
			_heli setVariable ["braf_hoist_payload_class", _payloadClass];
		};

		case "down": {
			private _rope = _heli getVariable ["hoistrope", objNull];

			if (isNull _rope) exitWith {};

			private _currentLength = ropeLength _rope;
			private _speed = ((_targetLength - _currentLength) max 0.01) / _duration;

			ropeUnwind [_rope, _speed, _targetLength, false];
		};

		case "up": {
			private _rope = _heli getVariable ["hoistrope", objNull];

			if (isNull _rope) exitWith {};

			private _currentLength = ropeLength _rope;
			private _speed = ((_currentLength - _initialLength) max 0.01) / _duration;

			ropeUnwind [_rope, _speed, _initialLength, false];
		};

		case "recover": {
			private _payload = _heli getVariable ["rescueseat", objNull];
			private _rope = _heli getVariable ["hoistrope", objNull];
			private _currentPayloadClass = _heli getVariable ["braf_hoist_payload_class", ""];

			if (isNull _rope) exitWith {
				_heli vehicleChat "no rope!";
			};

			if ((ropeLength _rope) <= _recoveryLength) then {
				if (!isNull _payload) then {
					{
						if (!isNil "_x") then {
							_x leaveVehicle _payload;
							_x action ["GetOut", _payload];
							sleep 0.1;
							_payload lock 0;
							[_x, _heli] remoteExec ["moveInCargo", _x];
							_x assignAsCargo _heli;
						};
					} forEach crew _payload;

					ropeDestroy _rope;
					deleteVehicle _payload;
				} else {
					ropeDestroy _rope;
				};

				_heli setVariable ["rescueseat", nil];
				_heli setVariable ["hoistrope", nil];
				_heli setVariable ["braf_hoist_payload_class", nil];

				if (_currentPayloadClass != "") then {
					private _spentPayloads = _heli getVariable ["braf_hoist_spent_payloads", []];
					_spentPayloads = _spentPayloads - [_currentPayloadClass];
					_heli setVariable ["braf_hoist_spent_payloads", _spentPayloads];
				};

				_heli vehicleChat "Rescue Payload In Cabin";
			} else {
				_heli vehicleChat "First Raise The Rescue Payload To Cabin Door";
			};
		};

		case "cut": {
			private _rope = _heli getVariable ["hoistrope", objNull];
			private _currentPayloadClass = _heli getVariable ["braf_hoist_payload_class", ""];

			if (isNull _rope) exitWith {
				_heli vehicleChat "no rope!";
			};

			ropeCut [_rope, 0];
			ropeDestroy _rope;
			_heli setVariable ["hoistrope", nil];

			if (_currentPayloadClass != "") then {
				private _spentPayloads = _heli getVariable ["braf_hoist_spent_payloads", []];

				if !(_currentPayloadClass in _spentPayloads) then {
					_spentPayloads pushBack _currentPayloadClass;
					_heli setVariable ["braf_hoist_spent_payloads", _spentPayloads];
				};
			};
		};
	};
};
