---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by HUAFEI2.
--- DateTime: 2020/6/11 14:43
---

local LBaseActorManager = ImportScript("ugc_common/script/core/actor/actor_manager.lua").LBaseActorManager;
local LActor = ImportScript("ugc_common/script/pc/actor/actor_impl.lua").LActor;
local LSkeletalMeshActor = ImportScript("ugc_common/script/pc/actor/skeletal_mesh_actor_impl.lua").LSkeletalMeshActor;
local LLocalPlayer = ImportScript("ugc_common/script/pc/actor/local_player_impl.lua").LLocalPlayer;
local LStaticMeshActor = ImportScript("ugc_common/script/pc/actor/static_mesh_actor_impl.lua").LStaticMeshActor;
local LEmitter = ImportScript("ugc_common/script/pc/actor/emitter_impl.lua").LEmitter;
local LWheeledVehicleActor = ImportScript("ugc_common/script/pc/actor/wheeled_vehicle_actor_impl.lua").LWheeledVehicleActor;
local LPhysicsConstraintActor = ImportScript("ugc_common/script/pc/actor/physics_constraint_actor_impl.lua").LPhysicsConstraintActor;
local LSimpleFightActor = ImportScript("ugc_common/script/pc/actor/simple_flight_actor_impl.lua").LSimpleFightActor;

---@class LActorManager
LActorManager = LActorManager or class("LActorManager", LBaseActorManager);

function LActorManager:ctor()
    self.m_actors = g_dataTable:GetTable("LActorManager");
end

function LActorManager:dtor()
    self.m_actors = nil;
end

---@return LActor
function LActorManager:CreateActor()
    local kActor = KLActorManager.CreateActor();
    if not kActor then
        return nil;
    end

    LOG_I("LActorManager:CreateActor", kActor, LActor, LActor.GetId, LActor.__cname);
    local lActor = LActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateActor", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@return LLocalPlayer
function LActorManager:CreateLocalPlayer()
    local kActor = KLActorManager.CreateLocalPlayer();
    if not kActor then
        return nil;
    end

    LOG_I("LActorManager:CreateLocalPlayer", kActor, LSkeletalMeshActor, LSkeletalMeshActor.GetId, LSkeletalMeshActor.__cname);
    local lActor = LLocalPlayer:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateLocalPlayer", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@param szMeshPath string
---@return LSkeletalMeshActor
function LActorManager:CreateSkeletalMeshActor(szMeshPath)
    if not szMeshPath then
        return;
    end

    local kActor = KLActorManager.CreateSkeletalMeshActor(szMeshPath);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateSkeletalMeshActor begin", kActor, szMeshPath);

    local lActor = LSkeletalMeshActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateSkeletalMeshActor mid", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@param szMeshPath string
---@return LStaticMeshActor
function LActorManager:CreateStaticMeshActor(szMeshPath)
    if not szMeshPath then
        return;
    end

    local kActor = KLActorManager.CreateStaticMeshActor(szMeshPath);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateStaticMeshActor begin", kActor, szMeshPath);

    local lActor = LStaticMeshActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateStaticMeshActor mid", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@param szParticleSystemPath string
---@return LEmitter
function LActorManager:CreateEmitter(szParticleSystemPath)
    if not szParticleSystemPath then
        return;
    end

    local kActor = KLActorManager.CreateEmitter(szParticleSystemPath);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateEmitter begin", kActor, szParticleSystemPath);

    local lActor = LEmitter:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateEmitter mid", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@param lActor LBaseActor
---@return boolean
function LActorManager:DestroyActor(lActor)
    LOG_I("LActorManager:DestroyActor: ", lActor);
    if not lActor then
        return;
    end
    local actorId = lActor:GetId();
    LOG_I("LActorManager:DestroyActor: ", actorId);
    KLActorManager.DestroyActor(actorId);
    self.m_actors[actorId] = nil;
end

---@param szResPath string
---@return LWheeledVehicleActor
function LActorManager:CreateWheeledVehicleActor(szResPath)
    if not szResPath then
        return;
    end

    local kActor = KLActorManager.CreateWheeledVehicleActor(szResPath);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateWheeledVehicleActor begin", kActor, szResPath);

    local lActor = LWheeledVehicleActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateWheeledVehicleActor mid", actorId, lActor);
    self.m_actors[actorId] = lActor;

    return lActor;
end

function LActorManager:CreateSimpleFlightActor(szResPath)
    if not szResPath then
        return;
    end

    local kActor = KLActorManager.CreateSimpleFlightActor(szResPath);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateSimpleFlightActor begin", kActor, szResPath);

    local lActor = LSimpleFightActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateSimpleFlightActor mid", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

---@return LBaseActor
function LActorManager:GetActorById(actorId)
    return self.m_actors[actorId]
end

---@return LBaseLocalPlayer
function LActorManager:GetLocalPlayer()
    return self.m_actors[1];
end

---@param actor1 
---@param actor2 
---@return LStaticMeshActor
function LActorManager:CreateConstraintActor(actor1, t1, actor2, t2)
    t1 = t1 or Core.FTransform();
    t2 = t2 or Core.FTransform();
    if not actor1 or not actor2 then
        return;
    end

    local kActor = KLActorManager.CreateConstraintActor(actor1 and actor1:GetKActor(), t1, actor2 and actor2:GetKActor(), t2);
    if not kActor then
        return nil;
    end
    LOG_I("LActorManager:CreateConstraintActor begin", actor1, actor2);

    local lActor = LPhysicsConstraintActor:new(kActor);
    local actorId = lActor:GetId();
    LOG_I("LActorManager:CreateStaticMeshActor mid", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

function LActorManager:SaveActorToJson(actor)
    if not actor then
        return;
    end
    local kActor = actor:GetKActor();
    if not kActor then
        return;
    end
    local strJson = KLSerialization.SaveActorToJsonString(kActor);
    return strJson;
end

function LActorManager:AddLoadedActor(kActor)
    if not kActor then
        return;
    end

    local lActor;
    local szClassName = kActor:GetClassName();
    if szClassName == "ALocalPlayer" then
        lActor = LLocalPlayer:new(kActor);
    elseif szClassName == "ASkeletalMeshActor" then
        lActor = LSkeletalMeshActor:new(kActor);
    elseif szClassName == "AStaticMeshActor" then
        lActor = LStaticMeshActor:new(kActor);
    elseif szClassName == "AWheeledVehicleActor" then
        lActor = LWheeledVehicleActor:new(kActor);
    elseif szClassName == "ASimpleFlightActor" then
        lActor = LSimpleFightActor:new(kActor);
    else
        lActor = LActor:new(kActor);
    end

    local actorId = lActor:GetId();
    LOG_I("LActorManager:AddLoadedActor", actorId, lActor);
    self.m_actors[actorId] = lActor;
    return lActor;
end

function LActorManager:LoadActorFromJson(strJson)
    if type(strJson) ~= "string" then
        return;
    end

    local varArray = Core.FVariantArray:new_local();
    if not varArray then
        return;
    end

    local bRetCode = KLSerialization.LoadActorFromJsonString(strJson, varArray);
    if not bRetCode then
        return
    end

    local tbLoadedKActors = {}
    local nActorVarLen = varArray:Length();
    for i = 1, nActorVarLen do
        local pActor = varArray:GetPointerByIdx(i - 1);
        if not pActor then
            return;
        end
        local kActor = tolua.cast(pActor, "Core::AActor");
        if not kActor then
            return;
        end
        table.insert(tbLoadedKActors, kActor);
    end

    local tbLoadedActors = {}
    for _, kActor in ipairs(tbLoadedKActors) do
        local lActor = self:AddLoadedActor(kActor);
        table.insert(tbLoadedActors, lActor);
    end
    return tbLoadedActors;
end

_G.g_ActorManager = LActorManager:new();
