-- Define gravity, friction, initial speed, max speed, and acceleration increment
local gravity = -9.8
local friction = 0.9
local initial_speed = 4
local max_speed = 40
local speed_increment = 1 -- This will increase by 1 every second

-- Register the globalstep function
minetest.register_globalstep(function(dtime)
    for _, player in ipairs(minetest.get_connected_players()) do
        local attached = player:get_attach()
        if attached then
            local entity = attached:get_luaentity()
            if entity and entity.allow_control then
                local ctrl = player:get_player_control()
                local player_yaw = player:get_look_horizontal()
                local dir = minetest.yaw_to_dir(player_yaw)
                
                -- Get current velocity
                local vel = entity.object:get_velocity()
                
                -- If moving forward or backward, increase the speed increment
                if ctrl.up or ctrl.down then
                    -- Increase speed by 1 every second
                    speed_increment = speed_increment + 1 * dtime
                    -- Cap the speed increment at the max speed minus the initial speed
                    if speed_increment > max_speed - initial_speed then
                        speed_increment = max_speed - initial_speed
                    end
                else
                    -- Reset speed increment when not moving
                    speed_increment = 0
                end
                
                -- Calculate new speed based on the speed increment
                local new_speed = initial_speed + speed_increment
                
                -- Apply new speed in the direction the player is looking
                if ctrl.up then
                    vel.x = dir.x * new_speed
                    vel.z = dir.z * new_speed
                elseif ctrl.down then
                    vel.x = -dir.x * new_speed
                    vel.z = -dir.z * new_speed
                end
                
                -- Apply gravity and friction
                vel.y = (vel.y or 0) + gravity * dtime
                vel.x = vel.x * friction
                vel.z = vel.z * friction
                
                -- Set the new velocity
                entity.object:set_velocity(vel)
            end
        end
    end
end)

minetest.register_entity("car_mod:controllable_entity", {
    visual = "mesh",
    mesh = "carithink.obj",
    textures = {"car1.png"},
    stepheight = 1.5,
    physical = true,
    collisionbox = {-1.7, -0, -1.7, 2, 1.7, 1.7},

    on_activate = function(self, staticdata, dtime_s)
        self.object:set_properties({
            visual_size = {x=18, y=18},
        })
        self.object:set_acceleration({x=0, y=gravity, z=0})
        self.allow_control = true
    end,

    on_step = function(self, dtime)
        if self.driver then
            local ctrl = self.driver:get_player_control()
            if ctrl.up or ctrl.down or ctrl.left or ctrl.right then
                local player_yaw = self.driver:get_look_horizontal()
                self.object:set_yaw(player_yaw)
            end
            local v = self.object:get_velocity()
            if v.x ~= 0 or v.z ~= 0 then
                self.object:set_yaw(minetest.dir_to_yaw(v))
            end
        end
    end,

	on_rightclick = function(self, clicker)
		if self.driver and clicker == self.driver then
		vehicles.object_detach(self, clicker, {x=2, y=0, z=1})
		elseif not self.driver then
		vehicles.object_attach(self, clicker, {x=0, y=1, z=0}, false, {x=-6, y=5, z=3})
		minetest.sound_play("mech_start", 
		{to_player=self.driver:get_player_name(), gain = 4, max_hear_distance = 3, loop = false})
		self.sound_ready = false
		minetest.after(14, function()
		self.sound_ready = true
		end)
		end
	end,
})

-- Table to keep track of entities, their models, and timers
local entity_models = {
    ["car_mod:controllable_entity"] = {
        current_index = 1,
        models = {
            "roll1.obj", "roll2.obj", "roll3.obj", "roll4.obj", "roll5.obj", "roll6.obj", "roll7.obj", "roll8.obj", "roll9.obj", "roll10.obj", "roll11.obj", "roll12.obj"},

        last_position = {x=0, y=0, z=0},
        timer = 1, -- Add a timer for each entity

        interval = 0.01 -- Interval in seconds for model change
    }
}

-- Function to get the next model in the list
local function get_next_model(entity)
    entity.current_index = (entity.current_index % #entity.models) + 1
    return entity.models[entity.current_index]
end

-- Store the last position and change count of each entity
local entity_info = {}

minetest.register_globalstep(function(dtime)
    for _, obj in pairs(minetest.luaentities) do
        if obj and obj.name == "car_mod:controllable_entity" and obj.object and obj.object.get_pos then
            local entity_data = entity_models[obj.name]
            local pos = obj.object:get_pos()

            -- Check if pos is not nil before using it
            if pos then
                -- Initialize entity info if not present
                if not entity_info[obj] then
                    entity_info[obj] = {last_pos = nil, change_count = 0}
                end

                -- Check if the position has changed
                if not entity_info[obj].last_pos or pos.x ~= entity_info[obj].last_pos.x or pos.y ~= entity_info[obj].last_pos.y or pos.z ~= entity_info[obj].last_pos.z then
                    -- Increase the change count
                    entity_info[obj].change_count = entity_info[obj].change_count + 1

                    -- If the change count is 3, change the model and reset the count
                    if entity_info[obj].change_count >= 3 then
                        -- Get the next model
                        local next_model = get_next_model(entity_data)
                        -- Set the new model
                        obj.object:set_properties({mesh = next_model})
                        -- Reset the change count
                        entity_info[obj].change_count = 0

                        -- Calculate the speed of the entity
                        local speed = vector.length(obj.object:get_velocity())

                        -- Calculate the pitch based on the speed
                        local pitch = 1 + (speed / max_speed)

                        -- Play a sound with the calculated pitch
                        minetest.sound_play("car", {object = obj.object, gain = 1.0, max_hear_distance = 32, loop = false, pitch = pitch})
                    end
                end

                -- Store the current position for the next check
                entity_info[obj].last_pos = pos
            end
        end
    end
end)








-- Assuming 'self' is your car entity
local function update_model_and_speed_on_jump(self, player)
    -- Get the player's controls
    local controls = player:get_player_control()

    -- Check if the player is trying to jump
    if controls.jump then
        -- The player is trying to jump, so set the model to the 'jump' model
        self.object:set_properties({visual = "mesh", mesh = "up.obj"})

        -- Increase the speed of the entity
        local vel = self.object:get_velocity()
        self.object:set_velocity({x = vel.x * 1, y = vel.y, z = vel.z * 1})

        -- Play a sound
        minetest.sound_play("rev_car", {object = player, gain = 1.0, max_hear_distance = 5})
    else
        -- The player is not trying to jump, so set the model back to the normal model
        self.object:set_properties({visual = "mesh", mesh = "roll1.obj"})

        -- Reset the speed of the entity
        local vel = self.object:get_velocity()
        self.object:set_velocity({x = vel.x / 1.5, y = vel.y, z = vel.z / 1.5})
    end
end

-- Call this function in your step function
minetest.register_globalstep(function(dtime)
    for _,player in ipairs(minetest.get_connected_players()) do
        local attached_to = player:get_attach()
        if attached_to and attached_to:get_luaentity().name == "car_mod:controllable_entity" then
            update_model_and_speed_on_jump(attached_to:get_luaentity(), player)
        end
    end
end)


-- Table to store the previous speeds of the entities
local previous_speeds = {}

minetest.register_globalstep(function(dtime)
    -- Iterate over all objects in the world
    for _, obj in ipairs(minetest.get_objects_inside_radius({x=0, y=0, z=0}, 10000)) do
        -- Check if the object and its Lua entity are not nil
        if obj and obj:get_luaentity() then
            -- Check if the object is the specific entity you're interested in
            if obj:get_luaentity().name == "car_mod:controllable_entity" then
                local vel = obj:get_velocity() -- Get the object's velocity
                local speed = vector.length(vel) -- Calculate the speed

                -- Get the previous speed of the entity
                local previous_speed = previous_speeds[obj]

                -- If the previous speed was over 3 and the current speed is zero
                if previous_speed and previous_speed > 3 and speed == 0 then
                    -- Do something here
                    minetest.chat_send_all("The specific entity's speed went from over 3 to zero immediately!")
                end

                -- Store the current speed as the previous speed for the next step
                previous_speeds[obj] = speed
            end
        end
    end
end)

minetest.register_globalstep(function(dtime)
    for _, entity in pairs(minetest.luaentities) do
        if entity.name == "car_mod:controllable_entity" then -- Replace with your entity's name
            if entity.object:get_velocity().y == 0 then -- The entity is not in the air
                local pos = entity.object:get_pos()
                local node = minetest.get_node(pos)

                if node.name ~= "air" then -- The entity has hit a node
                    local velocity = entity.object:get_velocity()
                    local speed = vector.length(velocity)

                    if speed > 10 then -- The entity hit the node hard (change the value as needed)
                        minetest.chat_send_all("The specific entity hit a node hard!")
                        -- Add your code here to handle the collision
                    end
                end
            end
        end
    end
end)















minetest.register_on_chat_message(function(name, message)
    local player = minetest.get_player_by_name(name)
    if not player then
        return
    end

    -- Split the message into individual characters
    local chars = message:gmatch(".")

    -- Initialize a delay
    local delay = 0

    -- For each character in the message
    for char in chars do
        -- If the character is a letter
        if char:match("%a") then
            -- Schedule the sound to play after the current delay
            minetest.after(delay, function()
                minetest.sound_play(char:lower(), {object=player})
            end)

            -- Increase the delay for the next sound
            delay = delay + 0.5
        end
    end
end)