local EffectObject = require "app/bf/unity/effect_object"

local EffectManager = {
	battleCacheList = {},
	battleCacheMap = {}
}

local TypeOfGameObject = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT
local BATTLE_CACHE_SIZE = 60  -- 战斗特效缓存容量s
local HERO_SHOW_FX_PATH = "assets/prefabs/effects/show/%s.prefab"

function EffectManager:loadUIEffectAsync(path, ui, parent, order, callback)
	ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
		if ui:isClosed() then
			ResourceManager:destroyPrefab(prefab)
			ResourceManager:unload(assetPath)
			return
		end
		if parent == nil or parent:isDestroyed() then
			ResourceManager:destroyPrefab(prefab)
			ResourceManager:unload(assetPath)
			return
		end
		local effectObject = EffectObject:create()
		effectObject:initWithPrefab(assetPath, prefab)
		effectObject:addUnloadCallback(function(obj)
			ResourceManager:unload(obj:getAssetPath())
		end)
		ui:addEffect(effectObject, parent, order)
		if callback then
			callback(effectObject)
		end
	end)
end

function EffectManager:loadEffectAsync(path, parent, callback)
	ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
		if parent and parent:isDestroyed() then
			ResourceManager:destroyPrefab(prefab)
			ResourceManager:unload(assetPath)
			return
		end
		local effectObject = EffectObject:create()
		effectObject:initWithPrefab(assetPath, prefab)
		effectObject:addUnloadCallback(function(obj)
			ResourceManager:unload(obj:getAssetPath())
		end)
		if parent then
			effectObject:setParent(parent, false)
		end
		if callback then
			callback(effectObject)
		end
	end)
end

function EffectManager:loadHeroShowEffectAsync(name, parent, callback)
	local path = string.format(HERO_SHOW_FX_PATH, name)
	ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
		if parent and parent:isDestroyed() then
			ResourceManager:destroyPrefab(prefab)
			ResourceManager:unload(assetPath)
			return
		end
		local effectObject = EffectObject:create()
		effectObject:initWithPrefab(assetPath, prefab)
		effectObject:addUnloadCallback(function(obj)
			ResourceManager:unload(obj:getAssetPath())
		end)
		if parent then
			effectObject:setParent(parent, false)
		end
		if callback then
			callback(effectObject)
		end
	end)
end

function EffectManager:loadBattleEffectAsync(path, parent, callback)
	ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
		if parent and parent:isDestroyed() then
			ResourceManager:destroyPrefab(prefab)
			ResourceManager:unload(assetPath)
			return
		end
		local effectObject = EffectObject:create()
		effectObject:initWithPrefab(assetPath, prefab)
		effectObject:addUnloadCallback(function(obj)
			local effectPath = obj:getAssetPath()
			if self.battleCacheMap[effectPath] then
				ResourceManager:unload(effectPath)
			else
				if #self.battleCacheList == BATTLE_CACHE_SIZE then
					local headPath = table.remove(self.battleCacheList, 1)
					ResourceManager:unload(headPath)
					self.battleCacheMap[headPath] = nil
				end
				self.battleCacheMap[effectPath] = true
				table.insert(self.battleCacheList, effectPath)
			end
		end)
		if parent then
			effectObject:setParent(parent, false)
		end
		if callback then
			callback(effectObject)
		end
	end)
end

function EffectManager:markCache(path)
	if #self.battleCacheList >= BATTLE_CACHE_SIZE then
		return false
	end
	if self.battleCacheMap[path] == nil then
		self.battleCacheMap[path] = true
		table.insert(self.battleCacheList, path)
		return true
	end
	return false
end

function EffectManager:isCacheFull()
	return #self.battleCacheList == BATTLE_CACHE_SIZE
end

function EffectManager:getCacheMaxSize()
	return BATTLE_CACHE_SIZE
end

function EffectManager:clearCache()
	for _, path in ipairs(self.battleCacheList) do
		ResourceManager:unload(path)
	end
	self.battleCacheList = {}
	self.battleCacheMap = {}
end

return EffectManager