--[[
JohnDeerePackUtil

Utility for my John Deere Pack

	@author:    Ifko[nator]
	@date:      06.12.2020
	@version:	1.0

	History:	v1.0 @ 06.12.2020 - initial implementation in FS 19
]]

JohnDeerePackUtil = {};
JohnDeerePackUtil.currentModName = g_currentModName;

JohnDeerePackUtil.supportetDriveSymbolNames = {
	"FOUR_WHEEL", 
	"DIFF_LOCK_FRONT", 
	"DIFF_LOCK_BACK",
	"PTO_FRONT",
	"PTO_BACK",
	"HANDBRAKE",
	"TIPPING_ACTIVE",
	"TIPPING_INACTIVE",
	"TIPPING_SIDE_LEFT_1",
	"TIPPING_SIDE_RIGHT_1",
	"TIPPING_SIDE_BACK_1",
	"TIPPING_SIDE_GRAINDOOR_1",
	"TIPPING_SIDE_LEFT_2",
	"TIPPING_SIDE_RIGHT_2",
	"TIPPING_SIDE_BACK_2",
	"TIPPING_SIDE_GRAINDOOR_2",
	"TRAILER_1",
	"TRAILER_2",
	"TOOL_FRONT_LOWERED",
	"TOOL_FRONT_LIFTED",
	"TOOL_BACK_LOWERED",
	"TOOL_BACK_LIFTED",
	"CONTROL_LAMP",
	"GPS_ACTIVE",
	"GPS_STEERING_ACTIVE",
	"GPS_LANE_PLUS",
	"GPS_LANE_MINUS",
	"STEERAXLE_IS_LOCKED",
	"RIDGE_MARKER_LEFT",
	"RIDGE_MARKER_RIGHT",
	"RIDGE_MARKER_LEFT_UP",
	"RIDGE_MARKER_RIGHT_UP",
	"RIDGE_MARKER_LEFT_DOWN",
	"RIDGE_MARKER_RIGHT_DOWN",
	"TOOL_FRONT_IS_UNFOLDED",
	"TOOL_FRONT_IS_FOLDED",
	"TOOL_BACK_IS_UNFOLDED",
	"TOOL_BACK_IS_FOLDED",
	"TIPPING_ACTIVE_TRUCK",
	"ABS_TRUCK",
	"ABS_TRAILER",
	"TIPPING_ACTIVE_TRAILER_1",
	"TIPPING_ACTIVE_TRAILER_2",
	"WEARED_OUT_BRAKES",
	"WARNING_BRAKE_COMPRESSOR_FILL_LEVEL_TO_LOW",
	"WARNING_WORKSHOP_1",
	"WARNING_WORKSHOP_2",
	"STOP_IMMINENTLY",
	"MOTOR_NEED_MAINTRACE",
	"LOW_OIL_PRESSURE",
	"OIL_FILL_LEVEL_TO_LOW",
	"VEHICLE_SELECTED",
	"TOOL_FRONT_SELECTED_1",
	"TOOL_FRONT_SELECTED_2",
	"TOOL_BACK_SELECTED_1",
	"TOOL_BACK_SELECTED_2",
	"VEHICLE_UNSELECTED",
	"TOOL_FRONT_UNSELECTED_1",
	"TOOL_FRONT_UNSELECTED_2",
	"TOOL_BACK_UNSELECTED_1",
	"TOOL_BACK_UNSELECTED_2",
	"FRONTLOADER_SELECTED",
	"FRONTLOADER_UNSELECTED",
	"FRONTLOADER_TOOL_SELECTED",
	"FRONTLOADER_TOOL_UNSELECTED",
	"TURN_LIGHT_TRAILER_ANY_1",
	"TURN_LIGHT_TRAILER_LEFT_1",
	"TURN_LIGHT_TRAILER_LEFT_2",
	"TURN_LIGHT_TRAILER_ANY_2",
	"TURN_LIGHT_TRAILER_RIGHT_1", 
	"TURN_LIGHT_TRAILER_RIGHT_2",
	"STRAW_CHOPPER",
	"OVERLOADING_ACTIVE",
	"GRAIN_TANK_UNFOLDED",
	"PIPE_UNFOLDED",
	"CARDINAL_DIRECTION_NORTH",
	"CARDINAL_DIRECTION_EAST",
	"CARDINAL_DIRECTION_SOUTH",
	"CARDINAL_DIRECTION_WEST",
	"CARDINAL_DIRECTION_NORTH_EAST",
	"CARDINAL_DIRECTION_NORTH_WEST",
	"CARDINAL_DIRECTION_SOUTH_EAST",
	"CARDINAL_DIRECTION_SOUTH_WEST",
	"NO_FIELD",
	"PS_MODE_AUTO",
	"PS_MODE_SEMI",
	"PS_MODE_MANUAL",
	"PS_LANE_LEFT",
	"PS_LANE_RIGHT",
	"PS_TRAM_LANE_LEFT",
	"PS_TRAM_LANE_RIGHT",
	"DISABLE_ON_MOTOR_OFF",
	"ADDITIONALLY_SIGN"
};

JohnDeerePackUtil.supportetScaleDirections = {
	"X",
	"Y",
	"Z",
	"ALL"
};

JohnDeerePackUtil.unSupportetFillTypes = {
	"BALETWINE",
	"BALENET",
	"MOLASSES",
	"WATER"
};

JohnDeerePackUtil.radioChannels = {
	"off",
	"rock",
	"pop",
	"electro",
	"country",
	"radio70s",
	"internet"
};

function JohnDeerePackUtil.getDebugPriority(xmlFile, path)
	return Utils.getNoNil(getXMLInt(xmlFile, path), 0);
end;

function JohnDeerePackUtil.getSpecByName(self, specName, currentModName)
    local spec = self["spec_" .. Utils.getNoNil(currentModName, JohnDeerePackUtil.currentModName) .. "." .. specName];

	if spec ~= nil then
        return spec;
    end;

    return self["spec_" .. specName];
end;

function JohnDeerePackUtil.printError(errorMessage, isWarning, isInfo, luaName)
	local prefix = "::ERROR:: ";
	
	if isWarning then
		prefix = "::WARNING:: ";
	elseif isInfo then
		prefix = "::INFO:: ";
	end;
	
	print(prefix .. "from the " .. luaName .. ".lua: " .. tostring(errorMessage));
end;

function JohnDeerePackUtil.printDebug(debugMessage, priority, addString, luaName)
	if priority >= 1 then
		local prefix = "";
		
		if addString then
			prefix = "::DEBUG:: from the " .. luaName .. ".lua: ";
		end;
		
		setFileLogPrefixTimestamp(false);
		print(prefix .. tostring(debugMessage));
		setFileLogPrefixTimestamp(true);
	end;
end;

function JohnDeerePackUtil.getIsSupportetValue(supportetValues, supportetValue)
	for supportetValueNumber = 1, #supportetValues do
		if supportetValues[supportetValueNumber] == supportetValue then 
			return true;
		end;
	end;
	
	return false;
end;

function JohnDeerePackUtil.getSupportetValues(supportetValues)
	local supportetValuesString = "";

	for supportetValueNumber, supportetValue in pairs(supportetValues) do
		if supportetValuesString ~= "" then 
			if supportetValueNumber < #supportetValues then
				supportetValue = "', '" .. supportetValue;
			else
				supportetValue = "' or '" .. supportetValue;
			end;
		end;
		
		supportetValuesString = supportetValuesString .. supportetValue;
	end;
	
	return supportetValuesString;
end;

function JohnDeerePackUtil.getIsValidPalletName(palletName)
	return (not string.find(palletName, "PALLETFORK") and not string.find(palletName, "TRIGGER")) and (string.find(palletName, "PALLET") or string.find(palletName, "BIGBAG") or string.find(palletName, "TANK"));
end;

function JohnDeerePackUtil.getFillLevel(fillUnits)
	local fillLevel = 0;

	for _, fillUnit in pairs(fillUnits) do
		if fillUnit.showOnHud then
			fillLevel = fillLevel + fillUnit.fillLevel;
		end;
	end;

	return fillLevel;
end;

function JohnDeerePackUtil.getCapacity(fillUnits)
	local capacity = 0;

	for _, fillUnit in pairs(fillUnits) do
		if fillUnit.showOnHud then
			capacity = capacity + fillUnit.capacity;
		end;
	end;

	return capacity;
end;

function JohnDeerePackUtil.renderText(posX, posY, textSize, string, priority)
	if priority >= 1 then
		renderText(posX, posY, getCorrectTextSize(textSize), tostring(string));
	end;
end;

function JohnDeerePackUtil.getIsLightActive(light, lightsTypesMask)
	local lightActive = false;

	for _, lightType in pairs(light.lightTypes) do
		if bitAND(lightsTypesMask, 2^lightType) ~= 0 then
			lightActive = true;

			break;
		end;
	end;

	if light.enableDirection ~= nil then
		local reverserDirection = 1;

		if self.getReverserDirection ~= nil then
			reverserDirection = self:getReverserDirection();
		end;

		lightActive = lightActive and light.enableDirection == reverserDirection;
	end;

	if lightActive then
		for _, excludedLightType in pairs(light.excludedLightTypes) do
			if bitAND(lightsTypesMask, 2^excludedLightType) ~= 0 then
				lightActive = false;

				break;
			end;
		end;
	end;

	return lightActive;
end;

function JohnDeerePackUtil.getCurrentFilledTrailer(vehicle, dischargeNode, specPipe)
	local currentFilledTrailer = nil;
	local minDistance = math.huge;
	local checkNode = Utils.getNoNil(dischargeNode.node, vehicle.components[1].node);

	for object, _ in pairs(specPipe.objectsInTriggers) do
		local outputFillType = vehicle:getFillUnitLastValidFillType(dischargeNode.fillUnitIndex);
		
		for fillUnitIndex, fillUnit in ipairs(object.spec_fillUnit.fillUnits) do
			local allowedToFillByPipe = object:getFillUnitSupportsToolType(fillUnitIndex, ToolType.DISCHARGEABLE);
			local supportsFillType = object:getFillUnitSupportsFillType(fillUnitIndex, outputFillType) or outputFillType == FillType.UNKNOWN;
			
			if allowedToFillByPipe and supportsFillType then
				local targetPoint = object:getFillUnitAutoAimTargetNode(fillUnitIndex);
				local exactFillRootNode = object:getFillUnitExactFillRootNode(fillUnitIndex);
				
				if targetPoint == nil then
					targetPoint = exactFillRootNode;
				end;
			
				if targetPoint ~= nil then
					local distance = calcDistanceFrom(checkNode, targetPoint);
				
					if distance < minDistance then
						currentFilledTrailer = object;

						break;
					end;
				end;
			end;
		end;
	end;

	return currentFilledTrailer;
end;

function JohnDeerePackUtil.getL10nText(text)
	if text:sub(1, 6) == "$l10n_" then
		text = g_i18n:getText(text:sub(7));
	elseif g_i18n:hasText(text) then
		text = g_i18n:getText(text);
	end;

	return text;
end;