AdditionalContractsLoading = {};

local AdditionalContractsLoading_mt = Class(AdditionalContractsLoading);

function AdditionalContractsLoading.new()	
	local self = {};
	setmetatable(self, AdditionalContractsLoading_mt);	
	self.pendingLoadingData = {};
	self.vehiclesLoad = {};
	self.vehiclesToLoading = {};	
	return self;
end;

function AdditionalContractsLoading:spawnObject(mission, spawnPosition, trigger, objectConfig)
	local x, y, z, rx, ry, rz = unpack(spawnPosition);
	local data = VehicleLoadingData.new();
	data:setFilename(objectConfig.filename);
	
	if data.isValid then	
		if objectConfig.configuration ~= nil then
			data:setConfigurations(objectConfig.configuration);
		end;
		if objectConfig.storeSpawn ~= nil and objectConfig.storeSpawn then
			data:setLoadingPlace(g_currentMission.storeSpawnPlaces, g_currentMission.usedStorePlaces);
		else
			data:setPosition(x, y, z);
			data:setRotation(trigger.rx or rx or 0, trigger.rotY or ry or 0, trigger.rz or rz or 0);
		end;
		if objectConfig.propertyState ~= nil then
			data:setPropertyState(objectConfig.propertyState);
		else
			data:setPropertyState(VehiclePropertyState.MISSION);
		end;
		if objectConfig.access ~= nil and objectConfig.access then
			data:setOwnerFarmId(mission.farmId); 
		else		
			data:setOwnerFarmId(AccessHandler.NOBODY);
		end;	
		
		data.mission = mission;	
		
		table.insert(self.pendingLoadingData, data)
		data:load(self.onLoadSpawnedVehicle, self, {
			["loadingData"] = data,
			["objectConfig"] = objectConfig,
			["mission"] = mission
		})
	end;	
end;

function AdditionalContractsLoading:onLoadSpawnedVehicle(vehicles, vehicleLoadState, loadingInfo)
	table.removeElement(self.pendingLoadingData, loadingInfo.loadingData)
	if self.failedToLoadVehicles then
		for _, vehicle in ipairs(vehicles) do
			vehicle:delete();
		end;
		return;
	elseif vehicleLoadState == VehicleLoadingState.OK then
		local objectConfig = loadingInfo.objectConfig;
		local mission = loadingInfo.mission;	
		for _, vehicle in ipairs(vehicles) do
			self:setWearPercent(objectConfig, vehicle);			
			
			self:setDamagePercent(objectConfig, vehicle);
			
			self:setDirtPercent(objectConfig, vehicle);
			
			self:setMaxSpeed(objectConfig, vehicle);
			
			self:setCanBeReset(objectConfig, vehicle);
			
			self:setOperatingTime(objectConfig, vehicle);
			
			self:setMapHotspotAvailable(objectConfig, vehicle);
			
			self:setFuelPercent(objectConfig, vehicle);
			
			self:setFillPercent(objectConfig, vehicle);			
			
			table.insert(self.vehiclesLoad, vehicle);
			local nodeId = vehicle.rootNode or vehicle.nodeId;			
			mission.objects[nodeId] = vehicle;					
		end;
	else
		self.failedToLoadVehicles = true;
		for _, vehicle in ipairs(vehicles) do
			vehicle:delete();
		end;
		for _, data in ipairs(self.pendingLoadingData) do
			data:cancelLoading();
		end;
		table.clear(self.pendingLoadingData);
		table.clear(self.vehiclesToLoading);
		self.spawnedVehicles = false;
		for _, vehicle in ipairs(self.vehiclesLoad) do
			vehicle:delete();
		end;
		table.clear(self.vehiclesLoad);
	end;
end;

function AdditionalContractsLoading:setWearPercent(objectConfig, vehicle)
	if objectConfig.wearPercent ~= nil then 
		local wearPercent = g_additionalContractUtils:getIntegerToVector(objectConfig.wearPercent)/100;
		vehicle:addWearAmount(wearPercent, true);
	end;
end;

function AdditionalContractsLoading:setDamagePercent(objectConfig, vehicle)
	if objectConfig.damagePercent ~= nil then 
		local damagePercent = g_additionalContractUtils:getIntegerToVector(objectConfig.damagePercent)/100;
		vehicle:addDamageAmount(damagePercent, true);
	end;
end;

function AdditionalContractsLoading:setDirtPercent(objectConfig, vehicle)
	if objectConfig.dirtPercent ~= nil then 
		local dirtPercent = g_additionalContractUtils:getIntegerToVector(objectConfig.dirtPercent)/100;
		vehicle:addDirtAmount(dirtPercent, true);
	end;
end;

function AdditionalContractsLoading:setMaxSpeed(objectConfig, vehicle)
	if objectConfig.maxSpeed ~= nil and vehicle.getMotor ~= nil then 
		local maxSpeed = g_additionalContractUtils:getIntegerToVector(objectConfig.maxSpeed);
		vehicle:getMotor().maxForwardSpeed = maxSpeed;vehicle:getMotor().maxBackwardSpeed = maxSpeed;
	end;
end;

function AdditionalContractsLoading:setCanBeReset(objectConfig, vehicle)
	vehicle.canBeReset = objectConfig.canBeReset or false;
end;

function AdditionalContractsLoading:setOperatingTime(objectConfig, vehicle)
	if objectConfig.setOperatingTime == nil or objectConfig.setOperatingTime then vehicle:setOperatingTime(3600000 * (math.random() * 40 + 30));end;
end;

function AdditionalContractsLoading:setMapHotspotAvailable(objectConfig, vehicle)
	if objectConfig.mapHotspotAvailable == nil or objectConfig.mapHotspotAvailable then
		vehicle.mapHotspotAvailable = true;
		vehicle.mapHotspotType = VehicleHotspot.TYPE.OTHER;
	end;
end;

function AdditionalContractsLoading:setFuelPercent(objectConfig, vehicle)
	if objectConfig.fuelPercent ~= nil and vehicle.getConsumerFillUnitIndex ~= nil then				
		local fuelUnitIndex = vehicle:getConsumerFillUnitIndex(FillType.DIESEL) or (vehicle:getConsumerFillUnitIndex(FillType.ELECTRICCHARGE) or vehicle:getConsumerFillUnitIndex(FillType.METHANE));
		if fuelUnitIndex ~= nil then						
			local capacity = vehicle:getFillUnitCapacity(fuelUnitIndex);					
			local fuelPercent = g_additionalContractUtils:getIntegerToVector(objectConfig.fuelPercent);					
			local fillDelta = (capacity*fuelPercent)/100 - vehicle:getFillUnitFillLevel(fuelUnitIndex);						
			vehicle:addFillUnitFillLevel(vehicle:getOwnerFarmId(), fuelUnitIndex, fillDelta, vehicle:getFillUnitFirstSupportedFillType(fuelUnitIndex), ToolType.UNDEFINED, nil);
		end;			
	end;
end;

function AdditionalContractsLoading:setFillPercent(objectConfig, vehicle)
	if objectConfig.fillPercent ~= nil and objectConfig.fillType ~= nil then										
		local fillType = nil;
		if objectConfig.fillType:upper() == "RANDOM" then 
			local randomFillUnits = {};
			for _, fillUnit in ipairs(vehicle:getFillUnits()) do
				local fillTypes = vehicle:getFillUnitSupportedFillTypes(fillUnit.fillUnitIndex);				
				for index, available in pairs(fillTypes) do
					local consumerFillUnit = vehicle.getConsumerFillUnitIndex ~= nil and vehicle:getConsumerFillUnitIndex(index);
					if (consumerFillUnit == nil or not consumerFillUnit) and available then
						table.insert(randomFillUnits, index);
					end;
				end;
			end;
			local fillTyp = table.getRandomElement(randomFillUnits);			
			fillType = g_fillTypeManager:getFillTypeByIndex(fillTyp);
			if fillType == nil or fillType.index == FillType.UNKNOWN then fillType = g_fillTypeManager:getFillTypeByIndex(2);end; --change
		else 
			fillType = g_fillTypeManager:getFillTypeByName(objectConfig.fillType);
		end;		
		if fillType ~= nil and fillType.index ~= FillType.UNKNOWN then					
			local fillPercent = g_additionalContractUtils:getIntegerToVector(objectConfig.fillPercent);					
			for _, fillUnit in ipairs(vehicle:getFillUnits()) do				
				if vehicle:getFillUnitSupportsFillType(fillUnit.fillUnitIndex, fillType.index) then
					local capacity = vehicle:getFillUnitCapacity(fillUnit.fillUnitIndex);
					local fillDelta = (capacity*fillPercent)/100 - vehicle:getFillUnitFillLevel(fillUnit.fillUnitIndex);
					vehicle:addFillUnitFillLevel(vehicle:getOwnerFarmId(), fillUnit.fillUnitIndex, fillDelta, fillType.index, ToolType.UNDEFINED, nil);
					break;
				end;						
			end;				
		end;
		
	end;
end;