require("Script.src.Core.GameWorld");

---@class Editing
Editing = Editing or class("Editing");

ResArr = {
    Default = "\\UGCSource\\player\\DefaultModel.actor",
    F1      = "\\UGCSource\\player\\F1_Model.actor",
    F2      = "\\UGCSource\\player\\F2_Model.actor",
    M1      = "\\UGCSource\\player\\M1_Model.actor",
    M2      = "\\UGCSource\\player\\M2_Model.actor"
};



function Editing:ctor()
    ---@type Actor
    self.m_actor = nil;
    self.m_selectedRes = nil;
    self.m_bWantPlace = false;

    ---@type Actor
    self.m_actorSelected = nil;
end

function Editing:dtor()

end

function Editing:GameLoop()
    if self.m_bWantPlace == true and self.m_actor then
        self:ProcessPlaceActor();
    else
        self:ProcessSelectActor();
    end
end

function Editing:RenderUI()
    ImGui.Begin("Resources");
    for k,v in pairs(ResArr) do
        ImGui.SameLine(0.0, 5.0);
        if true == ImGui.Button(k, ImVec2(64,64)) then
            print(string.format("%s -> %s", k, v));
            self:BeginPlace(v);
        end
    end
    ImGui.End();

    if nil ~= self.m_actorSelected then
        local actor = self.m_actorSelected;
        ImGui.Begin("Inspector");
        local actorName = actor:GetName();
        ImGui.InputText("name", actorName, #actorName);
        local _,x,y,z = actor:GetWorldPosition(0,0,0);
        local _,yaw,pitch,roll = actor:GetWorldRotation(0,0,0);
        local _,sx,sy,sz = actor:GetWorldScale(0,0,0);
        local position = {x,y,z};
        local rotation = {yaw,pitch,roll};
        local scale = {sx,sy,sz};
        if true == ImGui.DragFloat3("position", position, 1, 0, 0, "%.3f", 1) then
            actor:SetWorldPosition(position[1], position[2], position[3]);
        end
        if true == ImGui.DragFloat3("rotation", rotation, 0.01, -2*math.pi, 2*math.pi, "%.3f", 1) then
            actor:SetWorldRotation(rotation[1], rotation[2], rotation[3]);
        end
        if true == ImGui.DragFloat3("scale", scale, 1, 0, 0, "%.3f", 1) then
            actor:SetWorldScale(scale[1], scale[2], scale[3]);
        end
        
        ImGui.End();
    end
end

function Editing:ProcessPlaceActor()
    ---@type ImVec2
    local mousePos = ImGui.GetMousePos();
    local bOK,wx,wy,wz = GameWorld.Instance:GetRayHitPointFromScreen(mousePos.x, mousePos.y, 0, 0, 0);
    if true == bOK then
        self.m_actor:SetWorldPosition(wx, wy, wz);
    end

    if true == ImGui.IsMouseClicked(ImGuiMouseButton_.ImGuiMouseButton_Left) then
        self:EndPlace();
    elseif true == ImGui.IsMouseClicked(ImGuiMouseButton_.ImGuiMouseButton_Right) then
        self:DiscardPlace();
    end
end

---@param resPath string
function Editing:BeginPlace(resPath)
    if self.m_selectedRes ~= resPath then
        self.m_actor = GameWorld.Instance:CreateActor();
        self.m_actor:SetModelRes(resPath);
        self.m_actor:SetVisible(true);
        self.m_selectedRes = resPath;
    end
    self.m_bWantPlace = true;
end

function Editing:EndPlace()
    self.m_actor = nil;
    self.m_selectedRes = nil;
    self.m_bWantPlace = false;
end

function Editing:DiscardPlace()
    if nil ~= self.m_actor then
        GameWorld.Instance:DestoryActor(self.m_actor:GetId());
    end
    self:EndPlace();
end

function Editing:ProcessSelectActor()
    if true == ImGui.IsMouseClicked(ImGuiMouseButton_.ImGuiMouseButton_Left) then
        ---@type ImVec2
        local mousePos = ImGui.GetMousePos();
        local tbActorId = GameWorld.Instance:GetAllActorID();
        local selectedActor = nil;
        for index, value in ipairs(tbActorId) do
            local actor = GameWorld.Instance:GetActorById(value);
            if nil ~= actor then
                local _,wx,wy,wz = actor:GetWorldPosition(0,0,0);
                local _,sx,sy = GameWorld.Instance:WorldPosToScreenPos(wx,wy,wz,0,0);
                local deltaX = math.abs(mousePos.x - sx);
                local deltaY = sy - mousePos.y;
                if deltaX <= 32 and deltaY >= 0 and deltaY <= 128 then
                    selectedActor = actor;
                end
            end
        end
        if nil ~= selectedActor then
            self.m_actorSelected = selectedActor;
            print("select :", self.m_actorSelected:GetName(), self.m_actorSelected:GetId());
        end
    elseif true == ImGui.IsMouseClicked(ImGuiMouseButton_.ImGuiMouseButton_Right) then
        self.m_actorSelected = nil;
    end
end

Editing.Instance = Editing:new();

