--//*********THE CREATOR********//--
--//*Made by FlashGun for BriaN*//--

--[[
All important values can be changed directly inside the objects table. In case you want to modify the order of the objects you will have to take care of something inside 
the createPreviewObject and updatePreviewObject:

1. Objects like 8558 and 1894 need their z rotation to be changed in order to be displayed correctly in front of the car and maintain the symmetry.
   1.1. Objects like 8558 and 1894 therefore will need to use these offset values for x and y inside createPreviewObject and updatePreviewObject:
        xOffset = x + distance * math.cos(angle)
        yOffset = y + distance * math.sin(angle)
        1.2. Make sure to use the right indexes, like for example selectedObject == 1 or selectedObject == 2 would be correct in case two objects like this would
             have the first and second position in the objects table, in case you move them to the 3rd and 4th position you will need to modify selectedObject to
             equal 3 and 4 in the above-mentioned functions and make sure it uses the correct x and y offset values.
2. Objects like 1655 and 6959 have their z rotation direction the same as the vehicle, meaning that when the vehicle is facing forwards the object is also facing
   forwards in the same direction as the vehicle does.
   2.1. Objects like 1655 and 6959 therefore will need to use these offset values for x and y inside createPreviewObject and updatePreviewObject:
        xOffset = x + distance * math.cos(angle + math.pi/2)
        yOffset = y + distance * math.sin(angle + math.pi/2)
        2.2. As in the previous last step make sure to adjust the indexes for selectedObject accordingly, using the same logic as described above.       
]]

local objects = {
	{model = 6959, name = "vegas⠀⬇", distance = 35, offset = 0, height = -0.69, ry = 0,  rz = 0},
    {model = 1655, name = "waterjump⠀⬆", distance = 50, offset = 0, height = 0.35, ry = 0, rz = 0},
    {model = 3437, name = "bally⠀⮕", distance = 50, offset = 0, height = -1.5, ry = 85, rz = 90} -- ry is bally's inclination
}

local selectedObject = 1
local previewObject = nil
local selectedObjectName = ""
local initialVehicleRotation = 0

function createPreviewObject()
    if isElement(previewObject) then
        destroyElement(previewObject)
    end

    local player = getLocalPlayer()
    local vehicle = getPedOccupiedVehicle(player)

    if vehicle and selectedObject then
        local x, y, z = getElementPosition(vehicle)
        local rx, ry, rz = getElementRotation(vehicle)
        
        local objectData = objects[selectedObject]
        local distance = objectData.distance
        local height = objectData.height
        selectedObjectName = objectData.name
        ry = objectData.ry
        rz = rz + objectData.rz
        initialVehicleRotation = rz

        local angle = math.rad(rz)  
        local xOffset, yOffset

        if selectedObject == 3 then
            xOffset = x + distance * math.cos(angle)
            yOffset = y + distance * math.sin(angle)
        elseif selectedObject == 1 or selectedObject == 2 then
            xOffset = x + distance * math.cos(angle + math.pi/2)
            yOffset = y + distance * math.sin(angle + math.pi/2)
        end

        previewObject = createObject(objectData.model, xOffset, yOffset, z + height, 0, ry, rz, true)
        setElementAlpha(previewObject, 150)
    end
end

function updatePreviewObject()
    if isElement(previewObject) then
        local player = getLocalPlayer()
        local vehicle = getPedOccupiedVehicle(player)

        if vehicle then
            local x, y, z = getElementPosition(vehicle)
            local rx, ry, rz = getElementRotation(vehicle)
            
            local objectData = objects[selectedObject]
            local distance = objectData.distance
            local offset = objectData.offset
            local height = objectData.height
            ry = objectData.ry
            rz = rz + objectData.rz

            local offsetAngle = math.rad(initialVehicleRotation - rz)
            local offset = objectData.offset * math.cos(offsetAngle)

            local angle = math.rad(rz)  
            local xOffset, yOffset

            if selectedObject == 3 then
                xOffset = x + distance * math.cos(angle)
                yOffset = y + distance * math.sin(angle)
            elseif selectedObject == 1 or selectedObject == 2 then
                xOffset = x + distance * math.cos(angle + math.pi/2)
                yOffset = y + distance * math.sin(angle + math.pi/2)
            end

            setElementPosition(previewObject, xOffset, yOffset + offset, z + height)
            setElementRotation(previewObject, 0, ry, rz)
            setElementAlpha(previewObject, 150)
        end
    end
end

function cycleSelectedObject()
    selectedObject = selectedObject % #objects + 1
    createPreviewObject()
end

function unloadPreviewObject()
    if isElement(previewObject) then
        destroyElement(previewObject)
        previewObject = nil
    end
end

local resourceRoot = getRootElement()

addEventHandler("onClientResourceStart", resourceRoot, function()
    selectedObject = 1
    setTimer(createPreviewObject, 2000, 1) -- timer so it has enough time to create the preview
end)

addEventHandler("onClientResourceStop", resourceRoot, function()
    selectedObject = 1
    unloadPreviewObject()
end)
addEventHandler("onClientRender", root, updatePreviewObject)

function drawSelectedObjectName()
    local player = getLocalPlayer()
    local vehicle = getPedOccupiedVehicle(player)

    if vehicle and selectedObjectName and selectedObjectName ~= "" then
        local screenWidth, screenHeight = guiGetScreenSize()
        local textX = screenWidth / 2
        local textY = screenHeight - 150 -- adjust the Y position as needed
        local textZ = screenHeight - 135

        dxDrawText(selectedObjectName, textX, textY, textX, textY, tocolor(255, 255, 255), 3, "default-bold", "center", "bottom", false, false, false, true)
        dxDrawText("press 'LShift' to change, 'F' to place", textX, textZ, textX, textZ, tocolor(255, 255, 255), 1, "default-italic", "center", "bottom", false, false, false, true)
    end
end
addEventHandler("onClientRender", root, drawSelectedObjectName)

bindKey("lshift", "down", function()
    cycleSelectedObject()
end)

bindKey("f", "down", function()
    if isElement(previewObject) then
        local x, y, z = getElementPosition(previewObject)
        local rx, ry, rz = getElementRotation(previewObject)
        local createdObject = createObject(objects[selectedObject].model, x, y, z, rx, ry, rz)

        setElementAlpha(previewObject, 255)

        -- timer to delete the created object, 5000 = 5 sec
        setTimer(function()
            if isElement(createdObject) then
                destroyElement(createdObject)
            end
        end, 5000, 1)
    end
end)

