-- SPDX-FileCopyrightText: (c) 2024 Silverlan <opensource@pragma-engine.com>
-- SPDX-License-Identifier: MIT

local Component = ents.LightmapBaker

function Component:WriteLightmapInformationToMap(mapFilePath, mapName, lightmapDataCache, lightmapMaterial)
	local worldData, err = util.WorldData.load(mapFilePath)
	if worldData == nil then
		self:LogErr("Failed to load world data '{}': {}", mapFilePath, err)
		return false
	end
	local entWorld = worldData:FindWorld()
	if entWorld == nil then
		self:LogErr("No world entity exists in world data!")
		return false
	end
	local lightmapDataCacheC = entWorld:AddComponent("light_map_data_cache")
	lightmapDataCacheC:SetFlags(
		bit.bor(lightmapDataCacheC:GetFlags(), util.WorldData.ComponentData.FLAG_CLIENTSIDE_ONLY_BIT)
	)
	local data = lightmapDataCacheC:GetData()
	data:SetValue("lightmapDataCache", udm.TYPE_STRING, lightmapDataCache)

	local lightmapC = entWorld:AddComponent("light_map")
	lightmapC:SetFlags(bit.bor(lightmapC:GetFlags(), util.WorldData.ComponentData.FLAG_CLIENTSIDE_ONLY_BIT))
	local data = lightmapC:GetData()
	data:SetValue("lightmapMaterial", udm.TYPE_STRING, lightmapMaterial)

	local lightmapReceiverC = entWorld:AddComponent("light_map_receiver")
	lightmapReceiverC:SetFlags(
		bit.bor(lightmapReceiverC:GetFlags(), util.WorldData.ComponentData.FLAG_CLIENTSIDE_ONLY_BIT)
	)
	local res, err = worldData:Save(mapFilePath, mapName)
	if res == false then
		self:LogErr("Failed to save world data as '{}': {}", mapFilePath, err)
		return false
	end
	return true
end

function Component:BakeMapLightmaps()
	local mapName = game.get_map_name()
	local fileName = asset.find_file(mapName, asset.TYPE_MAP)
	local absFilePath = (fileName ~= nil) and asset.relative_path_to_absolute_path(fileName, asset.TYPE_MAP) or nil
	if absFilePath == nil then
		self:LogErr("Failed to determine file location of map '{}'!", mapName)
		return false
	end

	local ent = ents.get_world()
	if ent == nil then
		self:LogErr("No world entity found!")
		return false
	end

	self:UpdateLightmapTargets()

	if self:GenerateLightmapUvs() == false then
		self:LogErr("Failed to generate lightmap UVs.")
		return false
	end
	self.m_bakeQueue = {
		{
			type = "directional",
		},
		{
			type = "diffuse",
		},
	}
	--[[local dirLightmapJob = self:GenerateDirectionalLightmaps()
	if dirLightmapJob == nil then
		self:LogErr("Failed to generate directional lightmaps.")
		return false
	end
	local lightmapJob = self:GenerateLightmaps()
	if lightmapJob == false then
		self:LogErr("Failed to generate lightmaps.")
		return false
	end]]
	self.m_updateMapLightmapData = {
		mapName = mapName,
		mapFilePath = absFilePath,
	}
	return true
end
function Component:OnBakingCompleted()
	if self.m_updateMapLightmapData == nil then
		return
	end
	local updateMapLightmapData = self.m_updateMapLightmapData
	self.m_updateMapLightmapData = nil
	local ent = ents.get_world()
	local lightmapDataCacheC = ent:GetComponent(ents.COMPONENT_LIGHT_MAP_DATA_CACHE)
	if lightmapDataCacheC == nil then
		self:LogErr("No lightmap data cache.")
		return false
	end

	local lightmapC = ent:GetComponent(ents.COMPONENT_LIGHT_MAP)
	if lightmapC == nil then
		self:LogErr("No lightmap component.")
		return false
	end
	local lightmapDataCache = lightmapDataCacheC:GetLightMapDataCacheFilePath()
	local lightmapMaterial = lightmapC:GetLightmapMaterialName()
	return self:WriteLightmapInformationToMap(
		updateMapLightmapData.mapFilePath,
		updateMapLightmapData.mapName,
		lightmapDataCache,
		lightmapMaterial
	)
end
