local LTouchEventHandle = LTouchEventHandle or class("LTouchEventHandle")
local Lib = ImportScript("ugc_common/script/base/lib.lua")

E_TOUCH_STATE = Lib.CreateEnumTable(
{
	"Possible",
    "Began",
    "Changed",
    "Ended",
    "Cancelled",
    "Failed",
})

function LTouchEventHandle:ctor()
    self.m_fLastPinch = 0;
    self.m_nLastPanX = 0;
    self.m_nLastPanY = 0;
    self.m_fLastScenePosX = 0.0;
    self.m_fLastScenePosY = 0.0;
    self.m_fLastScenePosZ = 0.0;
    self.m_tPlayers = {fRotation = 90, fScale = 1};

    self.m_fLastMouseDeltaX = 0.0
    self.m_fLastMouseDeltaY = 0.0
end

function LTouchEventHandle:dtor()
    --
end

function LTouchEventHandle:OnTapEvent(touchState, nPosX, nPosY)
    local lPlayer = nil
    local nModelId = g_SceneManager:GetModelFromScenePos(nPosX, nPosY)
    if nModelId > 0 then
        lPlayer = g_ActorManager:GetActorById(nModelId)
    end

    if KLPlatformNative:IsARMode() then
        if not lPlayer then
            KLPlatformNative:StartTracker()
        else
            local lastPlayer = g_ActorManager:GetLocalPlayer();
            if lastPlayer ~= lPlayer then
                lastPlayer:SetAdditionnalObjectVisibal("选择特效a003.sfx", false);
            end
            g_ActorManager:SetLocalPlayer(lPlayer);
            lPlayer:ConverseAdditionnalObjectVisibal("选择特效a003.sfx");
        end
    end
end

function LTouchEventHandle:OnPanEvent(touchState, nPosX, nPosY, nDeltaX, nDeltaY)
    local nModelId,lPlayer
    local fPosX, fPosY, fPosZ
    local fX,fY,fZ = g_SceneManager:GetScenePosFromPlanePos()

    if KLPlatformNative:IsARMode() then
        nModelId = g_SceneManager:GetModelFromScenePos(nPosX, nPosY)
        if E_TOUCH_STATE["Changed"] == touchState then
            lPlayer = g_ActorManager:GetActorById(nModelId)
            local bCheck = g_SceneManager:CheckIsInModelShadowFromScenePos(lPlayer, nPosX, nPosY); -- 是否点中模型脚部位置
            if lPlayer and bCheck then
                _, fPosX, fPosY, fPosZ = lPlayer:GetWorldPosition()
                fPosX = fPosX + fX - self.m_fLastScenePosX
                fPosY = fPosY + fY - self.m_fLastScenePosY
                fPosZ = fPosZ + fZ - self.m_fLastScenePosZ
                lPlayer:SetWorldPosition(fPosX,fPosY,fPosZ)
            else
                lPlayer = g_ActorManager:GetLocalPlayer()
                local subRot = (self.m_nLastPanX - nPosX) * 0.2
                self.m_tPlayers.fRotation = self.m_tPlayers.fRotation + subRot

                if self.m_tPlayers.fRotation > 180 then
                    self.m_tPlayers.fRotation = self.m_tPlayers.fRotation - 360
                elseif self.m_tPlayers.fRotation < -180 then
                    self.m_tPlayers.fRotation = self.m_tPlayers.fRotation + 360
                end

                lPlayer:SetWorldRotation(0, self.m_tPlayers.fRotation, 0)
            end
        end
    else
        lPlayer = g_ActorManager:GetLocalPlayer()
        if E_TOUCH_STATE["Changed"] == touchState then
            if lPlayer then
                if math.abs(nPosX - self.m_nLastPanX) < 5 and math.abs(nPosY  - self.m_nLastPanY) > 10 then
                    _, fPosX, fPosY, fPosZ = lPlayer:GetWorldPosition();
                    fPosY = fPosY + (self.m_nLastPanY - nPosY) * 0.1
                    lPlayer:SetWorldPosition(fPosX, fPosY, fPosZ);
                else
                    local subRot = (self.m_nLastPanX - nPosX) * 0.2
                    self.m_tPlayers.fRotation = self.m_tPlayers.fRotation + subRot

                    if self.m_tPlayers.fRotation > 180 then
                        self.m_tPlayers.fRotation = self.m_tPlayers.fRotation - 360
                    elseif self.m_tPlayers.fRotation < -180 then
                        self.m_tPlayers.fRotation = self.m_tPlayers.fRotation + 360
                    end

                    lPlayer:SetWorldRotation(0, self.m_tPlayers.fRotation, 0)
                end
            end
        end
    end

    self.m_nLastPanX = nPosX
    self.m_nLastPanY = nPosY
    self.m_fLastScenePosX = fX
    self.m_fLastScenePosY = fY
    self.m_fLastScenePosZ = fZ
end

function LTouchEventHandle:OnPinchEvent(touchState, fScale)
    local tPlayer = g_ActorManager:GetLocalPlayer()

    if E_TOUCH_STATE["Changed"] == touchState then
        if tPlayer then
            local subScale = (fScale - self.m_fLastPinch) * 0.5
            self.m_tPlayers.fScale = self.m_tPlayers.fScale * (1 + subScale)
            self.m_tPlayers.fScale = math.min(self.m_tPlayers.fScale, 25)
            self.m_tPlayers.fScale = math.max(self.m_tPlayers.fScale, 0.15)

            tPlayer:SetWorldScale(self.m_tPlayers.fScale, self.m_tPlayers.fScale, self.m_tPlayers.fScale)
        end
    end

    self.m_fLastPinch = fScale
end

function LTouchEventHandle:OnMultiTouchPanEvent(touchState, nPosX, nPosY, nDeltaX, nDeltaY)
end

function LTouchEventHandle:OnSwipeEvent(touchState, nPosX, nPosY)
end

---@deprecated
---Make the View draggable like a browser
---function must use between Begin***()/End***()
function LTouchEventHandle:ScrollWhenDraggingOnVoid()
    local io = ImGui.GetIO();
    local mouse_delta = io.MouseDelta
    MouseDelta = ImVec2(0.0, mouse_delta.y)
    local g = ImGui.GetCurrentContext();
    local window = g.HoveredWindow;

    if ImGui.IsWindowFocused(ImGuiFocusedFlags_.ImGuiFocusedFlags_ChildWindows) then
        if window ~= nil then
            if math.abs(mouse_delta.x - self.m_fLastMouseDeltaX) > 5 then
                self.m_fLastMouseDeltaX = mouse_delta.x
                self.m_fLastMouseDeltaY = mouse_delta.y
                return
            end
            local posScroll = window.Scroll
            ImGui.SetScrollY(window, posScroll.y - mouse_delta.y);
            self.m_fLastMouseDeltaX = mouse_delta.x
            self.m_fLastMouseDeltaY = mouse_delta.y
        end
    end
end


_G.g_TouchEventHandle = LTouchEventHandle:new();
