---
--- Date         : 2020-07-30 15:21:07
--- Author       : LICHAO7
--- LastEditors  : LICHAO7
--- LastEditTime : 2020-08-14 16:13:13
--- Description  : Draw others item or test code item menu components.
--- 需要添加测试项的，添加一个Debug_前缀的function，然后注册到tbMenuItem中即可，等到不用时，尽量删掉
---

-- *一些特殊菜单需要保存的打开关闭状态
local tbMenuState = {

};

---
--- OnClick Handler
---

function Debug_ImGuiDemoUI(self)
    self.m_bShowDemo = not self.m_bShowDemo;
end

function Debug_ActorAttributesDemoUI(self)
    local bOpen = g_uiManager:GetOpenClose(_G.UI_ACTOR_ATTRIBUTES_DEMO);
    g_uiManager:SetOpenClose(_G.UI_ACTOR_ATTRIBUTES_DEMO, not bOpen);
end

function Debug_LuteSimulatorUI(self)
    local bOpen = _G.g_uiManager:GetOpenClose(_G.UI_LUTE_SIMULATOR);
    _G.g_uiManager:SetOpenClose(_G.UI_LUTE_SIMULATOR, not bOpen);
end

function Debug_Test(self)
    local szMesh     = "\\data\\source\\maps_source\\temp\\家园系统\\测试mesh\\JY_单人椅子001_HD.Mesh";
    local lMeshActor = g_ActorManager:CreateSkeletalMeshActor(szMesh);
    local lPlayer    = g_ActorManager:GetLocalPlayer();
    local bRetCode   = lMeshActor:AttachToParent(lPlayer, Core.eAR_KeepRelative);
    LOG_I("[TTTEEESSSTTT] ", lMeshActor:GetId(), bRetCode);
end

function Debug_Test2(self)
    local szMesh     = "data\\material\\Model\\MaterialModel_Box.Mesh";
    local lMeshActor = g_ActorManager:CreateStaticMeshActor(szMesh);
    local lPlayer    = g_ActorManager:GetLocalPlayer();
    local _, x, y, z = lPlayer:GetWorldPosition();
    x = x + 100;
    z = z + 100;
    y = 200;
    lMeshActor:SetWorldPosition(x, y, z);
    lMeshActor:SetWorldScale(0.1, 0.1, 0.1);
    lMeshActor:SetCollisionType(Core.QueryAndPhysics);
    lMeshActor:SetSimulatePhysics(true);
end

function Debug_SpawnBall(self)
    local szMesh     = "data\\material\\Model\\MaterialModel_Sphere.Mesh";
    local lMeshActor = g_ActorManager:CreateStaticMeshActor(szMesh);
    local lPlayer    = g_ActorManager:GetLocalPlayer();
    local _, x, y, z = lPlayer:GetWorldPosition();
    x = x + 10 ;
    z = z + 10;
    y = 200;

    local _, t = lPlayer:GetWorldTransform();
    local dirX, dirY, dirZ = t:Rotate(0, 0, 1, 0, 0, 0);

    local _, fLookAtX, fLookAtY, fLookAtZ = g_CameraController:GetLookDir();

    lMeshActor:SetWorldPosition(x, y, z);
    lMeshActor:SetWorldScale(0.1, 0.1, 0.1);
    lMeshActor:SetCollisionType(Core.QueryAndPhysics);
    lMeshActor:SetSimulatePhysics(true);
    local fVelocityScale = 3.0;
    lMeshActor:SetLinearVelocity(fVelocityScale * fLookAtX, fVelocityScale * fLookAtY, fVelocityScale * fLookAtZ, false);

    LOG_I("[TTTEEESSSTTT] ", lMeshActor:GetId(), lMeshActor:IsSimulatePhysics());
end

function Debug_CreateConstraint(self)
    local szMesh  = "data\\material\\Model\\MaterialModel_Box.Mesh";
    local actor1  = g_ActorManager:CreateStaticMeshActor(szMesh);
    local lPlayer = g_ActorManager:GetLocalPlayer();
    local _, x, y, z = lPlayer:GetWorldPosition();
    x = x + 100;
    z = z + 100;
    y = 150;
    actor1:SetWorldPosition(x, y, z);
    actor1:SetWorldScale(0.1, 0.1, 0.1);
    actor1:SetCollisionType(Core.QueryAndPhysics);
    actor1:SetPhysicsStatic(true);

    local actor2 = g_ActorManager:CreateStaticMeshActor(szMesh);
    x = x + 200;
    z = z + 200;
    y = 10;
    actor2:SetWorldPosition(x, y, z);
    actor2:SetWorldScale(0.1, 0.1, 0.1);
    actor2:SetCollisionType(Core.QueryAndPhysics);
    actor2:SetSimulatePhysics(true);

    local t1 = KTransform();
    local t2 = KTransform();
    t2:SetPosition(0, -100, 0);
    local joint = g_ActorManager:CreateConstraintActor(actor1, t1, actor2, t2);
    joint:SetLinearXMotion(ELCM_LIMITED);
    joint:SetLinearYMotion(ELCM_LIMITED);
    joint:SetLinearZMotion(ELCM_LIMITED);
    joint:SetLinearLimit(1.0, -1, 0.0);
    joint:SetAngularTwistMotion(ELCM_LIMITED);

    LOG_I("[Test Constraint] ", actor1:GetId(), bRetCode);
end

function Debug_CreateDoor(self)
    local actor1     = g_ActorManager:CreateActor();
    local lPlayer    = g_ActorManager:GetLocalPlayer();
    local _, x, y, z = lPlayer:GetWorldPosition();
    local x1 = x + 100;
    local z1 = z + 100;
    local y1 = 100;
    actor1:SetTranslation(x, y, z);
    -- actor1:SetWorldScale(0.1, 0.1, 0.1);
    -- actor1:SetCollisionType(Core.QueryAndPhysics);
    -- actor1:SetPhysicsStatic(true);

    local szMesh = "data\\source\\NPC_source\\PJ_lqf围墙大门002\\模型\\PJ_lqf围墙大门002_body_HD.mesh"
    local actor2 = g_ActorManager:CreateStaticMeshActor(szMesh);
    x = x + 300;
    z = z + 300;
    y = 10;
    actor2:SetTranslation(x, y, z);
    actor2:SetWorldScale(0.3, 0.3, 0.3);
    actor2:SetCollisionType(Core.QueryAndPhysics);
    actor2:SetSimulatePhysics(true);

    local joint = g_ActorManager:CreateConstraintActor(actor1, x1, y1, z1, actor2, 0, 50, 0);
    joint:SetLinearXMotion(ELCM_LOCKED);
    joint:SetLinearYMotion(ELCM_LOCKED);
    joint:SetLinearZMotion(ELCM_LOCKED);
    joint:SetLinearLimit(1.0, -1, 0.0);
    joint:SetAngularTwistMotion(ELCM_LOCKED);
    joint:SetAngularSwing1Motion(ELCM_LIMITED);
    joint:SetAngularSwing2Motion(ELCM_LOCKED);
    joint:SetAngularSwing2Limit(30.0);

    LOG_I("[Test Constraint] ", actor1:GetId(), bRetCode);
end

function Debug_CreateBuilding(self)
    local Config = ReLoadScript("ugc_common/script/cases/destruction/config.lua");
    Config.Cfg:createDestructibleObject("data/source/Home/building/AREA/JN/JN_house_M_house01_L_01_16_20_02_HD.Group");
end

function Debug_CreateRoleM2(self)
    local szMesh   = "data/source/player/actor/M2_Model.actor";
    local lM2Actor = g_ActorManager:CreateSkeletalMeshActor(szMesh);

    lM2Actor:AddModelToScene();
    lM2Actor:SetWorldPosition(100, 0, 50);
    lM2Actor:SetWorldRotation(0, 90, 0);
    lM2Actor:LoadDefaultAnimation();
end

function Debug_TestKLString(self)
    local klstr1 = KLString:new_local();                            --default constructor
    local klstr2 = KLString:new_local("MiniClient is number one!"); --assignment constructor
    local klstr3 = KLString:new_local(klstr2);                      --copy constructor

    LOG_I(string.format("klstr1 = %s", klstr1:ToString()));
    LOG_I(string.format("klstr2 = %s", klstr2:ToString()));
    LOG_I(string.format("klstr3 = %s", klstr3:ToString()));

    klstr1:Assign("Our slogan is: ");
    klstr1:AppendS(klstr2);
    LOG_I(string.format("klstr1 = %s", klstr1:ToString()));
    LOG_I(string.format("klstr1 compare klstr2 = %d", klstr1:CompareS(klstr2)));
    LOG_I(string.format("klstr2 compare klstr1 = %d", klstr2:CompareS(klstr1)));

    local nFoundPos = klstr1:FindS(klstr2);
    if -1 ~= nFoundPos then
        klstr1:Erase(0, nFoundPos);
        LOG_I(string.format("klstr1 = %s", klstr1:ToString()));
        LOG_I(string.format("klstr1 compare klstr2 = %d", klstr1:CompareS(klstr2)));
    end

    local str2Find = "number one";
    local str2Insert = "the best";
    nFoundPos = klstr1:RFind(str2Find);
    if -1 ~= nFoundPos then
        klstr1:Insert(nFoundPos, #str2Find, str2Insert);
        LOG_I(string.format("klstr1 = %s", klstr1:ToString()));

        local klstr4 = klstr1:SubString(nFoundPos, #str2Insert);
        local klstr5 = klstr1:SubString(0, 10);
        LOG_I(string.format("The first character in klstr4 is: %s", string.char(klstr4:GetAt(0))));
        klstr4:Append(" is "):AppendS(klstr5):Append("!"):SetAt(0, string.byte("T"));
        LOG_I(string.format("klstr4 = %s", klstr4:ToString()));
    end

    LOG_I(string.format("klstr1 len = %d, capacity = %d", klstr1:Size(), klstr1:Capacity()));
    klstr1:AppendS(klstr2);
    LOG_I(string.format("klstr1:AppendS(klstr2); klstr1 len = %d, capacity = %d", klstr1:Size(), klstr1:Capacity()));
    klstr1:Reserve(klstr1:Size() * 2);
    LOG_I(string.format("klstr1:Reserve(klstr1:Size() * 2); klstr1 len = %d, capacity = %d", klstr1:Size(), klstr1:Capacity()));
    klstr1:Clear();
    LOG_I(string.format("klstr1:Clear(); Is klstr1 empty? %s", tostring(klstr1:IsEmpty())));
    LOG_I(string.format("klstr1 len = %d, capacity = %d", klstr1:Size(), klstr1:Capacity()));
    klstr1:AssignS(klstr2);
    klstr1:ShrinkToFit();
    LOG_I(string.format("klstr1 len = %d, capacity = %d", klstr1:Size(), klstr1:Capacity()));

    -- --KLImGui example
    -- KLImGui.InputText("test", klstr1, klstr1:Capacity());
end

function Debug_SimpleFlight()
    local bOpen = _G.g_uiManager:GetOpenClose(_G.UI_FLIGHT_LIST);
    _G.g_uiManager:SetOpenClose(_G.UI_FLIGHT_LIST, not bOpen);
end

-- * Menubar name/handler.
local tbMenuItem = {
    {"ImGuiDemo",            Debug_ImGuiDemoUI,        nil},
    {"Test",                 Debug_Test,               nil},
    {"Test2",                Debug_Test2,              nil},
    {"Spawn ball",           Debug_SpawnBall,          nil},
    {"Create Constraint",    Debug_CreateConstraint,   nil},
    {"Create Door",          Debug_CreateDoor,         nil},
    {"Create Building",      Debug_CreateBuilding,     nil},
    {"Create Role M2",       Debug_CreateRoleM2,       nil},
    {"Test KLString",        Debug_TestKLString,       nil},
    {"Simple flight",        Debug_SimpleFlight,       nil},
};

-- *要用util.a2u8转的的，在这里insert进去，看起来整齐一些
table.insert(tbMenuItem, {util.a2u8("属性面板"), Debug_ActorAttributesDemoUI, nil});
table.insert(tbMenuItem, {util.a2u8("琵琶模拟"), Debug_LuteSimulatorUI,       nil});

---
--- Batch draw menu item.
---
--- @return boolean
---
DrawOthersCom = function(self)
    for _, item in ipairs(tbMenuItem) do
        local menuName, fnOnClick, fnCheck = unpack(item);
        local bCheck = (fnCheck and {fnCheck()} or {true})[1];
        if bCheck and ImGui.MenuItem(menuName) then
            fnOnClick(self);
        end
    end
end
