---
--- Date         : 2020-08-10 15:36:36
--- Author       : LICHAO7
--- LastEditors  : LICHAO7
--- LastEditTime : 2020-08-20 10:40:19
--- Description  : Wheeled vehicle assemble
---

local LBaseAssemble = ImportScript("ugc_common/script/core/assemble/base_assemble.lua").LBaseAssemble;
---
--- @class LWheeledVehicleAssemble
---
LWheeledVehicleAssemble = LWheeledVehicleAssemble or class("LWheeledVehicleAssemble", LBaseAssemble);

function LWheeledVehicleAssemble:ctor()
    self.m_tbSocketName = {
        S_Bone_Wheel_LF = util.a2u8("左前轮"),
        S_Bone_Wheel_RF = util.a2u8("右前轮"),
        S_Bone_Wheel_LR = util.a2u8("左后轮"),
        S_Bone_Wheel_RR = util.a2u8("右后轮"),
        Root            = util.a2u8("车身"),
    };
    self.m_tbProperty = {
        S_Bone_Wheel_LF = {
            Label = util.a2u8("左前轮位置"),
            Value = {0, 0, 0},
        },
        S_Bone_Wheel_RF = {
            Label = util.a2u8("右前轮位置"),
            Value = {0, 0, 0},
        },
        S_Bone_Wheel_LR = {
            Label = util.a2u8("左后轮位置"),
            Value = {0, 0, 0},
        },
        S_Bone_Wheel_RR = {
            Label = util.a2u8("右后轮位置"),
            Value = {0, 0, 0},
        },
        PlayerOffset = {
            Label = util.a2u8("驾驶者位置"),
            Value = {0, 0, 0}
        },
        PlayerOrientation = {
            Label = util.a2u8("驾驶者朝向"),
            Value = {0, 0, 0}
        },
    };
    self.m_strControlTip = util.a2u8([[
        操作提示
W(向前加速) | S(向后加速)
A(向左转向) | D(向右转向)
    ]]);
end

function LWheeledVehicleAssemble:dtor()
end

---
--- Construct edit property
---
function LWheeledVehicleAssemble:ConstructPropertyFromLogicSockets()
    self.m_tbProperty.PlayerOffset.Value      = self.m_tbLogicSockets.Root.PlayerOffset or {0, 0, 0};
    self.m_tbProperty.PlayerOrientation.Value = self.m_tbLogicSockets.Root.PlayerOrientation or {0, 0, 0};
    for name, socket in pairs(self.m_tbLogicSockets) do
        if self.m_tbProperty[name] then
            self.m_tbProperty[name].Value = {
                socket.Matrix[13],
                socket.Matrix[14],
                socket.Matrix[15],
            };
        end
    end
end

---
--- Dump edit property to logic socket
---
function LWheeledVehicleAssemble:DumpPropertyToLogicSockets()
    -- self.m_tbLogicSockets.Root.PlayerOffset      = self.m_tbProperty.PlayerOffset.Value;
    -- self.m_tbLogicSockets.Root.PlayerOrientation = self.m_tbProperty.PlayerOrientation.Value;
    for name, socket in pairs(self.m_tbProperty) do
        if self.m_tbLogicSockets[name] then
            self.m_tbLogicSockets[name].Matrix = {
                1.0, 0.0, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 1.0, 0.0,
                socket.Value[0], socket.Value[1], socket.Value[2], 1.0
            };
        end
    end
end

function LWheeledVehicleAssemble:DrawPropertyWidget(strSocketName)
    -- if false then -- 屏蔽
        -- if strSocketName ~= "Root" and self.m_tbProperty[strSocketName] then
        --     ImGui.Text(self.m_tbProperty[strSocketName].Label);
        --     _, self.m_tbProperty[strSocketName].Value[1] = ImGui.DragFloat("##X", self.m_tbProperty[strSocketName].Value[1], 0.5, -360, 360, "X: %.3f");
        --     _, self.m_tbProperty[strSocketName].Value[2] = ImGui.DragFloat("##Y", self.m_tbProperty[strSocketName].Value[2], 0.5, -360, 360, "Y: %.3f");
        --     _, self.m_tbProperty[strSocketName].Value[3] = ImGui.DragFloat("##Z", self.m_tbProperty[strSocketName].Value[3], 0.5, -360, 360, "Z: %.3f");
        -- end

        if strSocketName == "Root" then
            ImGui.Text(self.m_tbProperty.PlayerOrientation.Label);
            _, self.m_tbProperty.PlayerOrientation.Value[1] = ImGui.DragFloat("##Player X", self.m_tbProperty.PlayerOrientation.Value[1], 0.5, 0, 360, "X: %.3f");
            _, self.m_tbProperty.PlayerOrientation.Value[2] = ImGui.DragFloat("##Player Y", self.m_tbProperty.PlayerOrientation.Value[2], 0.5, 0, 360, "Y: %.3f");
            _, self.m_tbProperty.PlayerOrientation.Value[3] = ImGui.DragFloat("##Player Z", self.m_tbProperty.PlayerOrientation.Value[3], 0.5, 0, 360, "Z: %.3f");

            ImGui.Text(self.m_tbProperty.PlayerOffset.Label);
            _, self.m_tbProperty.PlayerOffset.Value[1] = ImGui.DragFloat("##Part X", self.m_tbProperty.PlayerOffset.Value[1], 0.5, 0, 360, "X: %.3f");
            _, self.m_tbProperty.PlayerOffset.Value[2] = ImGui.DragFloat("##Part Y", self.m_tbProperty.PlayerOffset.Value[2], 0.5, 0, 360, "Y: %.3f");
            _, self.m_tbProperty.PlayerOffset.Value[3] = ImGui.DragFloat("##Part Z", self.m_tbProperty.PlayerOffset.Value[3], 0.5, 0, 360, "Z: %.3f");
        end
        self:UpdateProperty(strSocketName);
    -- end
end

function LWheeledVehicleAssemble:DrawControlTipWidget()
    ImGui.TextWrapped(self.m_strControlTip);
end

---
--- Create MeshActor.
---
--- @return boolean
---
function LWheeledVehicleAssemble:CreateActor()
    self.m_actor = g_ActorManager:CreateWheeledVehicleActor(self.m_strPath);
    self.m_player = g_ActorManager:GetLocalPlayer();
    local _, x, y, z  = self.m_player:GetWorldPosition();
    x = x + 300;
    z = z + 300;

    self.m_actor:SetWorldPosition(x, y, z);
    self.m_actor:SetCollisionType(Core.QueryAndPhysics);
    self.m_actor:BeginControl();
    self.m_player:AttachToParent(self.m_actor, Core.eAR_SnapToTarget);
    self.m_player:SetLocalRotation(
        self.m_tbProperty.PlayerOrientation.Value[1],
        self.m_tbProperty.PlayerOrientation.Value[2],
        self.m_tbProperty.PlayerOrientation.Value[3]
    );
    self.m_player:SetLocalPosition(
        self.m_tbProperty.PlayerOffset.Value[1],
        self.m_tbProperty.PlayerOffset.Value[2],
        self.m_tbProperty.PlayerOffset.Value[3]
    );
    g_NetWorking:EntityCreated(g_NetWorking.ENTITY_TYPE_VEHICLE, self.m_actor:GetId(), self.m_strPath);
    return true;
end

---
--- Destroy MeshActor.
---
--- @return boolean
---
function LWheeledVehicleAssemble:DestroyActor()
    if self.m_actor then
        self.m_actor:EndControl();
        self.m_player:DetachFromParent();
        self.m_player:SetLocalRotation(0, 0, 0);
        g_NetWorking:EntityDeleted(self.m_actor:GetId());
        g_ActorManager:DestroyActor(self.m_actor);
        self.m_actor = nil;
    end
    self.m_player = nil;
    return true;
end

function LWheeledVehicleAssemble:UpdateProperty(strSocketName)
    -- if self.m_tbProperty[strSocketName] then
    --     local transVector = KVec3:new_local(
    --         self.m_tbProperty[strSocketName].Value[1],
    --         self.m_tbProperty[strSocketName].Value[2],
    --         self.m_tbProperty[strSocketName].Value[3]
    --     );
    --     local identityMatrix = KMatrix:new_local(true);
    --     local translationMatrix = identityMatrix:Translation(transVector);
    --     self.m_actor:SetLogicSocketMatrix(strSocketName, translationMatrix);
    -- end

    self.m_player:SetLocalPosition(
        self.m_tbProperty.PlayerOffset.Value[1],
        self.m_tbProperty.PlayerOffset.Value[2],
        self.m_tbProperty.PlayerOffset.Value[3]
    );
    self.m_player:SetLocalRotation(
        self.m_tbProperty.PlayerOrientation.Value[1],
        self.m_tbProperty.PlayerOrientation.Value[2],
        self.m_tbProperty.PlayerOrientation.Value[3]
    );
end

