--- Author: ALXXA
--- Date: 15.08.2025
--- Version: 1.0.0.0

RealWindWheel = {}

local WindCoef = 0.069
local RainCoef = 0.001

local IceCoef = 0.03
local SnowCoef = 0.05

local WaterIndex
local IceIndex
local SnowIndex

local modDir = g_currentModDirectory
local RealWindWheelXmlFile = modDir.."windWheelMediumWater.xml"

function RealWindWheel:loadMap(savegame)	

	for idx, fillType in pairs(g_fillTypeManager.indexToName) do 				
		if fillType == "WATER" then WaterIndex = idx end		
		if fillType == "ICE" then IceIndex = idx end
		if fillType == "SNOW" then SnowIndex = idx end
	end

	PlaceableSystem.addPlaceable = Utils.appendedFunction(PlaceableSystem.addPlaceable,RealWindWheel.addPlaceable)

	for i, item in ipairs(g_storeManager.items) do
		if item.xmlFilename == "data/placeables/mapUS/decoration/windWheelMedium/windWheelMediumWater.xml" then		    
			g_storeManager.items[i] = g_storeManager:loadItem("windWheelMediumWater.xml", modDir, "FS25_RealWindPump", "true", "false", g_i18n:getText("mod_title"), item.extraContentId, true)
	        if g_storeManager.items[i] ~= nil then
				g_storeManager.xmlFilenameToItem[g_storeManager.items[i].xmlFilenameLower] = g_storeManager.items[i]
			end				
		end
	end		

end


function RealWindWheel:addPlaceable(placeable)	

	local placeables = g_currentMission.placeableSystem.placeables

	if placeables ~= nil then
		for _, placeable in pairs(placeables) do 

			if placeable.configFileName == RealWindWheelXmlFile then
				placeable.canBeSold = Utils.overwrittenFunction(placeable.canBeSold, RealWindWheel.canBeSold)
				placeable.onSell = Utils.overwrittenFunction(placeable.onSell, RealWindWheel.onSell)				
			end			
		end
	end
end


function RealWindWheel:canBeSold(superFunc)
	return true, nil
end


function RealWindWheel:onSell()   
end


function RealWindWheel:update(dt)		

	local currentWeather =  g_currentMission.environment.weather.forecast:getCurrentWeather()
	local temperature = currentWeather.temperature
	local rainfallScale = g_currentMission.environment.weather.rainUpdater.rainfallScale
	local snowfallScale = g_currentMission.environment.weather.rainUpdater.snowfallScale
	
	if g_currentMission.placeableSystem.placeables ~= nil then
		for _, placeable in pairs(g_currentMission.placeableSystem.placeables) do 			

			if placeable.configFileName == RealWindWheelXmlFile then
				
				local storage		
				
				if placeable.spec_silo.storages ~= nil then
					storage = placeable.spec_silo.storages[1]									
				else
					return
				end
				
				if storage.fillLevels ~= nil then
					
					if storage:getFreeCapacity(WaterIndex) == 0 and placeable.spec_windTurbine.samples.idle.volumeScale ~= nil then placeable.spec_windTurbine.samples.idle.volumeScale = 0 end
					
					if storage.fillLevels[WaterIndex] > 0 or storage.fillLevels[IceIndex] > 0 or storage.fillLevels[SnowIndex] > 0 then storage:updateFillPlanes() end

					if storage.fillLevels[SnowIndex] < 0 then storage.fillLevels[SnowIndex] = 0 end
					if storage.fillLevels[WaterIndex] < 0 then storage.fillLevels[WaterIndex] = 0 end
					if storage.fillLevels[IceIndex] < 0 then storage.fillLevels[IceIndex] = 0 end
					if storage.fillLevels[SnowIndex] > storage.capacity then storage.fillLevels[SnowIndex] = storage.capacity end					
					if storage.fillLevels[WaterIndex] > storage.capacity then storage.fillLevels[WaterIndex] = storage.capacity end				
					if storage.fillLevels[IceIndex] > storage.capacity then storage.fillLevels[IceIndex] = storage.capacity end								

					if placeable.spec_infoTrigger.hudBox.lines ~= nil then
						for _, line in pairs(placeable.spec_infoTrigger.hudBox.lines) do
							if line.value == g_i18n:getText("infohud_siloEmpty") then line.value = g_i18n:getText("configuration_valueEmpty") end 														
						end
					end

					if snowfallScale > 0 and storage:getFreeCapacity(SnowIndex) > 0 then
						local amountSnow = storage.fillLevels[SnowIndex]										
						amountSnow = amountSnow + 0.00064 * snowfallScale * g_currentMission:getEffectiveTimeScale()					
						storage:setFillLevel(amountSnow, SnowIndex)							
					end					

					if rainfallScale > 0 and storage:getFreeCapacity(WaterIndex) > 0 then			
						local amountWater = storage.fillLevels[WaterIndex]
						amountWater = amountWater + RainCoef * rainfallScale * g_currentMission:getEffectiveTimeScale()						
						storage:setFillLevel(amountWater, WaterIndex)
					end

					if temperature > 0 then	
					
						if storage.fillLevels[SnowIndex] > 0 then
							local amountSnow = storage.fillLevels[SnowIndex]
							local amountBkpSnow = storage.fillLevels[SnowIndex]
							amountSnow = amountSnow - 4 * SnowCoef * temperature * g_currentMission:getEffectiveTimeScale()																		
							storage:setFillLevel(amountSnow, SnowIndex)
							storage.fillLevels[SnowIndex] = amountSnow									
				
							if storage:getFreeCapacity(WaterIndex) > 0 and storage.fillLevels[SnowIndex] > 0 then
								local amountWater = storage.fillLevels[WaterIndex]
								amountWater = amountWater + SnowCoef * temperature * g_currentMission:getEffectiveTimeScale()						
								storage:setFillLevel(amountWater, WaterIndex)
							end
							
							if storage:getFreeCapacity(WaterIndex) > 0 and storage.fillLevels[SnowIndex] < 0 then
								local amountWater = storage.fillLevels[WaterIndex]
								amountWater = amountWater + amountBkpSnow * 0.25 						
								storage:setFillLevel(amountWater, WaterIndex)
							end
						end		
						
						if storage.fillLevels[IceIndex] > 0 then
							local amountIce = storage.fillLevels[IceIndex]
							local amountBkpIce = storage.fillLevels[IceIndex]
							amountIce = amountIce - IceCoef * temperature * g_currentMission:getEffectiveTimeScale()
							storage:setFillLevel(amountIce, IceIndex)
							storage.fillLevels[IceIndex] = amountIce
							
							if storage:getFreeCapacity(WaterIndex) > 0 and storage.fillLevels[IceIndex] > 0 then
								local amountWater = storage.fillLevels[WaterIndex]
								amountWater = amountWater + IceCoef * temperature * g_currentMission:getEffectiveTimeScale()						
								storage:setFillLevel(amountWater, WaterIndex)
							end
							
							if storage:getFreeCapacity(WaterIndex) > 0 and storage.fillLevels[IceIndex] < 0 then
								local amountWater = storage.fillLevels[WaterIndex]
								amountWater = amountWater + amountBkpIce						
								storage:setFillLevel(amountWater, WaterIndex)
							end							
						end

						if storage.fillPlanes[WaterIndex] ~= nil and storage.fillPlanes[SnowIndex] ~= nil then							
							local _, translateIce = getTranslation(storage.fillPlanes[IceIndex].node)
							storage.fillPlanes[WaterIndex].moveMinY = translateIce
							storage.fillPlanes[WaterIndex].moveMaxY = 2 + translateIce
							storage.fillPlanes[SnowIndex].moveMinY = translateIce
							storage.fillPlanes[SnowIndex].moveMaxY = 2 + translateIce
						end						

						if storage:getFreeCapacity(WaterIndex) > 0 then 
							local amountWater = storage.fillLevels[WaterIndex]
							amountWater = amountWater + WindCoef * placeable.spec_windTurbine.rotSpeedFactor * g_currentMission:getEffectiveTimeScale()						
							storage:setFillLevel(amountWater, WaterIndex)
							if placeable.spec_windTurbine.samples.idle.volumeScale ~= nil then placeable.spec_windTurbine.samples.idle.volumeScale = 5 end
						end						
					end

					if temperature < 0 then	
						if storage.fillLevels[WaterIndex] > 0 then
							local amountWater = storage.fillLevels[WaterIndex]
							local amountBkpWater = storage.fillLevels[WaterIndex]
							amountWater = amountWater + IceCoef * temperature * g_currentMission:getEffectiveTimeScale()						
							storage:setFillLevel(amountWater, WaterIndex)
							storage.fillLevels[WaterIndex] = amountWater
							
							if storage:getFreeCapacity(IceIndex) > 0 and storage.fillLevels[WaterIndex] > 0 then
								local amountIce = storage.fillLevels[IceIndex]
								amountIce = amountIce - IceCoef * temperature * g_currentMission:getEffectiveTimeScale()
								storage:setFillLevel(amountIce, IceIndex)
							end
							
							if storage:getFreeCapacity(IceIndex) > 0 and storage.fillLevels[WaterIndex] < 0 then
								local amountIce = storage.fillLevels[IceIndex]
								amountIce = amountIce + amountBkpWater
								storage:setFillLevel(amountIce, IceIndex)
							end
						end	

						if storage.fillPlanes[WaterIndex] ~= nil and storage.fillPlanes[SnowIndex] ~= nil then
							local _, translateIce = getTranslation(storage.fillPlanes[IceIndex].node)												
							storage.fillPlanes[WaterIndex].moveMinY = translateIce						
							storage.fillPlanes[WaterIndex].moveMaxY = 2 + translateIce
							storage.fillPlanes[SnowIndex].moveMinY = translateIce
							storage.fillPlanes[SnowIndex].moveMaxY = 2 + translateIce
						end	

						if placeable.spec_windTurbine.samples.idle.volumeScale ~= nil then placeable.spec_windTurbine.samples.idle.volumeScale = 0 end
					end	
					
					if storage.fillPlanes[WaterIndex] ~= nil and storage.fillPlanes[SnowIndex] ~= nil then						
						local _, translateWater = getTranslation(storage.fillPlanes[WaterIndex].node)						
						if translateWater > 0 then setTranslation(storage.fillPlanes[WaterIndex].node, 0, 0, 0) end
						local _, translateSnow = getTranslation(storage.fillPlanes[SnowIndex].node)						
						if translateSnow > 0 then setTranslation(storage.fillPlanes[SnowIndex].node, 0, 0, 0) end
					end							
				end
			end
		end
	end	
end

addModEventListener(RealWindWheel)