local wait = require("src/wait")

actionHandler = {
    action = {},
    actions = {},
}

actionHandler.currentAnimations = {}

-- Initialize the actions pages.
function actionHandler.create_page(main_page)
    local action_page = action_wheel:newPage()
    -- Add the ability to go back.
    action_page:newAction()
        :title("Main Menu")
        :item("arrow")
        :onLeftClick(function()
            action_wheel:setPage(main_page)
        end)
    -- Return the page.
    return action_page
end

-- Adds a list of actions to the defined config page.
function actionHandler.action.add(page, object)
    -- Loop through the actions.
    for actionName, actionDetails in pairs(object) do
        -- Add the animation based on type.
        actionHandler.action[actionDetails.type](page, actionName, actionDetails)
    end
end

-- Adds a toggleable animation/ping to the defined config page.
function actionHandler.action.toggle(page, action_name, actionDetails)
    -- Create the ping for the animation.
    pings[action_name] = function(value)
        if value == true then
            actionHandler.currentAnimations[action_name] = true
            animations.model[action_name]:play()
        else
            actionHandler.currentAnimations[action_name] = nil
            animations.model[action_name]:stop()
        end
        -- Save the skin that's being applied for later.
        config:save("active_actions", actionHandler.currentAnimations)
    end
    -- Add the action to the action_wheel.
    actionHandler.actions[action_name] = page:newAction()
        :title(action_name:gsub("_", " "):gsub("(%a)(%w*)",
            function(first, rest) return first:upper() .. rest:lower() end))
        :toggleTitle(action_name:gsub("_", " "):gsub("(%a)(%w*)",
            function(first, rest) return first:upper() .. rest:lower() end))
        :item(actionDetails.icon)
        :toggleItem(actionDetails.icon)
        :onToggle(function(state) pings[action_name](state) end)
end

-- Adds a animation/ping to the defined config page.
function actionHandler.action.single(page, action_name, actionDetails)
    -- Create the ping for the animation.
    pings[action_name] = function()
        animations.model[action_name]:play()
    end
    -- Add the action to the action_wheel.
    actionHandler.actions[action_name] = page:newAction()
        :title(action_name:gsub("_", " "):gsub("(%a)(%w*)",
            function(first, rest) return first:upper() .. rest:lower() end))
        :toggleTitle(action_name:gsub("_", " "):gsub("(%a)(%w*)",
            function(first, rest) return first:upper() .. rest:lower() end))
        :item(actionDetails.icon)
        :toggleItem(actionDetails.icon)
        :onLeftClick(pings[action_name])
end

-- Adds a sound ping.
function actionHandler.action.sound(page, action_name, actionDetails)
    -- Create the ping for the animation.
    pings[action_name] = function()
        sounds:playSound(action_name:gsub("_", "."), player:getPos(), 1, 1)
    end
    -- Add the action to the action_wheel.
    actionHandler.actions[action_name] = page:newAction()
        :title(actionDetails.display_name)
        :item(actionDetails.icon)
        :toggleItem(actionDetails.icon)
        :onLeftClick(pings[action_name])
end

-- Define the function that will be used to load the skin indefinitely.
function actionHandler.load()
    -- Save the skin for the next time it loads.
    if host:isHost() then
        -- Load the existing config.
        local data = config:load("active_actions")
        -- If the config is blank then set it to default otherwise load the saved skin.
        if data == nil then
            config:save("active_actions", {})
        else
            -- Loop through the actions.
            for actionName, actionDetails in pairs(data) do
                pings[actionName](true)
                actionHandler.actions[actionName]:setToggled(true)
            end
        end
    end
end

-- Run every 20 ticks.
function actionHandler.oneSecondTick()
    -- Apply the saved skin.
    actionHandler.load()
    -- Repeat the function.
    wait.schedule(20, actionHandler.oneSecondTick)
end

wait.schedule(20, actionHandler.oneSecondTick)

return actionHandler
