---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by luojunxin.
--- DateTime: 2020/7/10 11:59
---


UI_ENTITY_PROPERTY_VIEW = "EntityPropertyView";
local Ui = Ui or class(UI_ENTITY_PROPERTY_VIEW, LUiBase);
_G.UI_ENTITY_PROPERTY_VIEW = UI_ENTITY_PROPERTY_VIEW;

function Ui:ctor()
    self.m_bOpen = false;
    self.m_szName = UI_ENTITY_PROPERTY_VIEW;
    self.m_lstHeights = {};
end

function Ui:dtor()
    --
end

function Ui:GameTick()
    --
end

function Ui:GameDraw()
    ImGui.SetNextWindowSize(ImVec2(250, 500), ImGuiCond_.ImGuiCond_FirstUseEver);
    _, self.m_bOpen = ImGui.Begin(self.m_szName, self.m_bOpen);
    self:draw();
    ImGui.End();
end

function Ui:draw()
    local curr = g_DataStorage:GetCurrentEntity();
    if curr ~= nil then
        if g_App:IsDebug() then
            local tabAttr = curr:GetAttributeSet();
            if tabAttr ~= nil then
                local nCount = tabAttr:GetChildAttrNum() - 1;
                for nIndex = 0, nCount do
                    local item = tabAttr:GetChildAttrByIdx(nIndex);
                    local type = item:GetType();
                    local func = self.switch_case_type[type + 1];
                    if func ~= nil then
                        func(item, "_" .. tostring(nIndex) .. "_");
                    end
                end
            end
            ImGui.Separator();
        end

        local bResult;
        local nOld, nNew;

        nOld = curr:GetCollisionType();
        ImGui.Text("Collision Type");
        ImGui.SameLine(0, -1);
        bResult, nNew = ImGui.Combo("##CollisionType", nOld, "No Collision\0Query Only\0Physics Only\0Query And Physics\0", -1);
        if nOld ~= nNew then
            curr:SetCollisionType(nNew);
        end

        local bSimulatePhysics = curr:IsSimulatePhysics()
        local _, bNewSimulatePhysics = ImGui.Checkbox("Simulate Physics", bSimulatePhysics);
        if bNewSimulatePhysics ~= bSimulatePhysics then
            curr:SetSimulatePhysics(bNewSimulatePhysics);
        end
    end
end

function Ui:drawAttributeSet(attr, szParentID, tabAttr)
    local nUIHeight = 0;
    local szName = attr:GetDisplayName();
    local szID = szParentID .. "_" .. szName;
    local func = self.switch_case_object_name[szName];
    if func ~= nil then
        nUIHeight = nUIHeight + func(attr, szID);
    else
        if ImGui.CollapsingHeader(szName, 0) and tabAttr ~= nil then
            local nChildHeight = self.m_lstHeights[szID];
            if nChildHeight == nil then nChildHeight = 0 end;
            if ImGui.BeginChild(szID, ImVec2(0, nChildHeight), true) then
                local nCount = tabAttr:GetChildAttrNum() - 1;
                for nIndex = 0, nCount do
                    local item = tabAttr:GetChildAttrByIdx(nIndex);
                    local type = item:GetType();
                    func = self.switch_case_type[type + 1];
                    if func ~= nil then
                        nUIHeight = nUIHeight + func(item, szID .. "_" .. tostring(nIndex));
                    end
                end
                self.m_lstHeights[szID] = nUIHeight;
                ImGui.EndChild();
            end
            nUIHeight = nUIHeight + 4;
        end
        nUIHeight = nUIHeight + 36;
    end
    return nUIHeight;
end

UiInst = Ui:new();

UiInst.switch_case_type = {
    function(attr, szParentID)
        -- integer
        if attr:IsEditorVisible() == false then return 0 end;
        local szName = attr:GetDisplayName();
        local szID = szParentID .. "_" .. szName;
        local nValue = attr:GetInt();
        local fRange = attr:GetRange();
        local fRangeMax = 0
        local fRangeMin = 0;
        if attr:IsInRange() then
            fRangeMin = fRange:GetMin();
            fRangeMax = fRange:GetMax();
        end
        ImGui.SetNextItemWidth(120);
        ImGui.Text(szName);
        ImGui.SameLine(0, -1);
        local bResult, nNewValue = ImGui.DragInt("##" .. szID, nValue, 1, fRangeMin, fRangeMax, "%d");
        if nNewValue ~= nValue then
            attr:SetInt(nNewValue, false);
            local action = LActionAttrIntegerModify:new();
            action:Init(attr, nValue, nNewValue);
            g_UndoRedoManager:AddAction(action);
        end
        return 25;
    end,
    function(attr, szParentID)
        -- bool
        if attr:IsEditorVisible() == false then return 0 end;
        local szName = attr:GetDisplayName();
        local szID = szParentID .. "_" .. szName;
        local bValue = attr:GetBool();
        ImGui.SetNextItemWidth(120);
        ImGui.Text(szName);
        ImGui.SameLine(0, -1);
        local bResult, bNewValue = ImGui.Checkbox("##" .. szID, bValue);
        if bNewValue ~= bValue then
            attr:SetBool(bNewValue, false);
            local action = LActionAttrBoolModify:new();
            action:Init(attr, bNewValue);
            g_UndoRedoManager:AddAction(action);
        end
        return 25;
    end,
    function(attr, szParentID)
        -- float
        if attr:IsEditorVisible() == false then return 0 end;
        local szName = attr:GetDisplayName();
        local szID = szParentID .. "_" .. szName;
        local fValue = attr:GetFloat();
        local szDesc = attr:GetDesc();
        local fRange = attr:GetRange();
        local fRangeMax = 0
        local fRangeMin = 0;
        if attr:IsInRange() then
            fRangeMin = fRange:GetMin();
            fRangeMax = fRange:GetMax();
        end
        ImGui.SetNextItemWidth(120);
        ImGui.Text(szName);
        ImGui.SameLine(0, -1);
        local bResult, fNewValue = ImGui.DragFloat("##" .. szID, fValue, 1, fRangeMin, fRangeMax, "%.6f", 1);
        if fNewValue ~= fValue then
            attr:SetFloat(fNewValue, false);
            local action = LActionAttrFloatModify:new();
            action:Init(attr, fValue, fNewValue);
            g_UndoRedoManager:AddAction(action);
        end
        return 25;
    end,
    function(attr, szParentID)
        -- string
        if attr:IsEditorVisible() == false then return 0 end;
        local szName = attr:GetDisplayName();
        local szID = szParentID .. "_" .. szName;
        local szValue = util.a2u8(attr:GetString());
        szValue = string.split(szValue, "%z")[1];   -- 清理掉字符串末尾多余的0字符
        local cszValue = KLString:new_local(szValue);
        ImGui.SetNextItemWidth(120);
        ImGui.Text(szName);
        ImGui.SameLine(0, -1);
        KLImGui.InputText("##" .. szID, cszValue, cszValue:Capacity());
        local szNewValue = cszValue:ToString()
        if szNewValue ~= szValue then
            attr:SetString(util.u82a(szNewValue), false);
            local action = LActionAttrStringModify:new();
            action:Init(attr, szValue, szNewValue);
            g_UndoRedoManager:AddAction(action);
        end
        return 25;
    end,
    function(attr, szParentID)
        -- array
        if attr:IsEditorVisible() == false then return 0 end;
        return UiInst:drawAttributeSet(attr, szParentID, attr:GetArray());
    end,
    function(attr, szParentID)
        -- struct
        if attr:IsEditorVisible() == false then return 0 end;
        return UiInst:drawAttributeSet(attr, szParentID, attr:GetStruct());
    end,
    function(attr, szParentID)
        -- object
        if attr:IsEditorVisible() == false then return 0 end;
        return UiInst:drawAttributeSet(attr, szParentID, attr:GetObject());
    end
}

UiInst.switch_case_object_name = {
    ["Transform"] = function(attr, szParentID)
        local szName = attr:GetDisplayName();
        local szID = szParentID .. "_" .. szName;
        local tabAttr = attr:GetStruct();
        if tabAttr ~= nil then
            ImGui.BeginChild(szName .. "##" .. szID, ImVec2(0, 86));
            ImGui.Text("Transform");
            local nWidth = ImGui.GetWindowContentRegionWidth() / 3 - 27;
            local tabTempName = {"Position", "Rotation", "Scaling "};
            local tabSensitivity = {1, 1, 0.1};
            local tabAccuracy = {"%.1f", "%.1f", "%.2f"};
            for nIndexY = 1, 3 do
                ImGui.Text(tabTempName[nIndexY]);
                for nIndexX = 1, 3 do
                    local i = nIndexY * 3 + nIndexX - 4;
                    ImGui.SameLine(0, -1);
                    ImGui.SetNextItemWidth(nWidth);
                    local item = tabAttr:GetChildAttrByIdx(i);
                    local oldValue = item:GetFloat();
                    local bResult, newValue = ImGui.DragFloat("##" .. szID .. "_" .. tostring(i), oldValue, tabSensitivity[nIndexY], 0, 0, tabAccuracy[nIndexY], 1);
                    if newValue ~= oldValue then
                        item:SetFloat(newValue, false);
                        local action = LActionAttrFloatModify:new();
                        action:Init(item, oldValue, newValue);
                        g_UndoRedoManager:AddAction(action);
                    end
                    ImGui.NextColumn();
                end
            end
            ImGui.EndChild();
        end
        return 100;
    end
}