--[[
	BaseGameFix
	Specialization to fix some issues from the base game!
	
	@author:    Ifko[nator]
	@date:      21.11.2020
	@version:	1.0

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

BaseGameFix = {};

--## LightsFix
function BaseGameFix:setLightsTypesMask(superFunc, lightsTypesMask, force, noEventSend)
	if JohnDeerePackUtil == nil then
		return;
	end;

	local specLights = JohnDeerePackUtil.getSpecByName(self, "lights");

	if lightsTypesMask ~= specLights.lightsTypesMask or force then
		if noEventSend == nil or noEventSend == false then
			if g_server ~= nil then
				g_server:broadcastEvent(VehicleSetLightEvent:new(self, lightsTypesMask), nil, nil, self);
			else
				g_client:getServerConnection():sendEvent(VehicleSetLightEvent:new(self, lightsTypesMask));
			end;
		end;

		if self.isClient and lightsTypesMask ~= specLights.lightsTypesMask then
			g_soundManager:playSample(specLights.samples.toggleLights);
		end;

		local activeLightSetup = specLights.realLights.low;
		local inactiveLightSetup = specLights.realLights.high;

		if self:getUseHighProfile() then
			activeLightSetup = specLights.realLights.high;
			inactiveLightSetup = specLights.realLights.low;
		end;

		for _, light in pairs(inactiveLightSetup.lightTypes) do
			setVisibility(light.node, false);
		end;

		for _, light in pairs(activeLightSetup.lightTypes) do
			local isActive = JohnDeerePackUtil.getIsLightActive(light, lightsTypesMask);

			if isActive then
				setVisibility(light.node, true);
			else
				local active = false;

				if light.brakeLight ~= nil and light.brakeLight.isActive then
					active = true;
				end;

				setVisibility(light.node, active);
			end;

			light.isActive = isActive;
		end;

		for _, light in pairs(specLights.defaultLights) do
			local isActive = JohnDeerePackUtil.getIsLightActive(light, lightsTypesMask);

			setVisibility(light.node, isActive);
		end;

		for _, light in pairs(specLights.shaderDefaultLights) do
			local isActive = JohnDeerePackUtil.getIsLightActive(light, lightsTypesMask);
			local value = 1;

			if not isActive then
				value = 0;
			end;

			local _, y, z, w = getShaderParameter(light.node, "lightControl");

			setShaderParameter(light.node, "lightControl", math.max(value * light.intensity, 0), y, z, w, false);

			if light.toggleVisibility then
				setVisibility(light.node, isActive);
			end;
		end;

		specLights.lightsTypesMask = lightsTypesMask;

		SpecializationUtil.raiseEvent(self, "onLightsTypesMaskChanged", lightsTypesMask);
    end;
    
	return true;
end;

Lights.setLightsTypesMask = Utils.overwrittenFunction(Lights.setLightsTypesMask, BaseGameFix.setLightsTypesMask);

--## MotorizedFix
function BaseGameFix:onWriteUpdateStreamMotorized(streamId, connection, dirtyMask)
    if not connection.isServer then
		if JohnDeerePackUtil == nil then
			return;
		end;
	
		local specMotorized = JohnDeerePackUtil.getSpecByName(self, "motorized");

        if streamWriteBool(streamId, specMotorized.isMotorStarted) then
			streamWriteInt8(streamId, specMotorized.motorTemperature.value, 7);
			streamWriteInt8(streamId, specMotorized.lastFuelUsage, 7);
        end;
    end;
end;

function BaseGameFix:onReadUpdateStreamMotorized(streamId, timestamp, connection)
    if connection.isServer then
        if JohnDeerePackUtil == nil then
			return;
		end;
	
		local specMotorized = JohnDeerePackUtil.getSpecByName(self, "motorized");

        if streamReadBool(streamId) then
			specMotorized.motorTemperature.value = streamReadUInt8(streamId);
			specMotorized.lastFuelUsage = streamReadUInt8(streamId);
        end;
    end;
end;

Motorized.onWriteUpdateStream = Utils.appendedFunction(Motorized.onWriteUpdateStream, BaseGameFix.onWriteUpdateStreamMotorized);
Motorized.onReadUpdateStream = Utils.appendedFunction(Motorized.onReadUpdateStream, BaseGameFix.onReadUpdateStreamMotorized);

--## MaterialUtilFix
function BaseGameFix:onCreateMaterial(superFunc, id)
	local fillTypeStr = getUserAttribute(id, "fillType");

	if fillTypeStr == nil then
		print("Warning: No fillType given in '" .. getName(id) .. "' for MaterialUtil.onCreateMaterial");

		return;
	end;

	local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeStr);
	
	if fillTypeIndex == nil then
		--print("Warning: Unknown fillType '" .. tostring(fillTypeStr) .. "' for MaterialUtil.onCreateMaterial");

		return;
	end;

	local materialTypeName = getUserAttribute(id, "materialType");

	if materialTypeName == nil then
		print("Warning: No materialType given for '" .. getName(id) .. "' for MaterialUtil.onCreateMaterial");
		
		return;
	end;

	local materialType = g_materialManager:getMaterialTypeByName(materialTypeName);

	if materialType == nil then
		print("Warning: Unknown materialType '" .. materialTypeName .. "' given for '" .. getName(id) .. "' for MaterialUtil.onCreateMaterial");
		
		return;
	end;

	local matIdStr = Utils.getNoNil(getUserAttribute(id, "materialIndex"), 1);
	local materialIndex = tonumber(matIdStr);

	if materialIndex == nil then
		print("Warning: Invalid materialIndex '" .. matIdStr .. "' for " .. getName(id) .. "-" .. materialTypeName .. "!");
		
		return;
	end;

	g_materialManager:addMaterial(fillTypeIndex, materialType, materialIndex, getMaterial(id, 0));
end;

MaterialUtil.onCreateMaterial = Utils.overwrittenFunction(MaterialUtil.onCreateMaterial, BaseGameFix.onCreateMaterial);