#include "../../script/helpers/string.lua"
#include "../../script/helpers/entity.lua"
#include "../../config/events.lua"

function init()
    script = GetScriptId()
    lightswitcher = FindShape("lightswitcher", true)
    lightswitchergas = FindShape("lightswitchergas", true)
    if not IsHandleValid(lightswitcher) or not IsHandleValid(lightswitchergas) then
        DISABLED = cEntity:EnqueueDeletion()
        return
    end
    powerOn = LoadSound("MOD/snd/poweron.ogg")
    clickUp = LoadSound("clickup.ogg")
	clickDown = LoadSound("clickdown.ogg")
    RegisterListenerTo(EVENTS.MAIN_FIRST_TICK, "FirstTick")
end

function FirstTick()
    UnregisterListener(EVENTS.MAIN_FIRST_TICK, "FirstTick")

    if HasTag(lightswitcher, "ok") and not HasTag(lightswitcher, "interact") then
        SetTag(lightswitcher, "interact", "loc@FLIP_SWITCH")
    end
    if HasTag(lightswitchergas, "ok") and not HasTag(lightswitchergas, "interact") then
        SetTag(lightswitchergas, "interact", "loc@FLIP_SWITCH")
    end
end

function tick(dt)
    if DISABLED then return end

    local broken
    if IsHandleValid(lightswitcher) and IsShapeBroken(lightswitcher) then
        SetLightShapesToggleEmissive("lightswitcher", false)
        SetShapesToggleEmissive("lightswitcher", false)
        broken = true
        PlaySound(clickDown)
        lightswitcher = 0
    end
    if IsHandleValid(lightswitchergas) and IsShapeBroken(lightswitchergas) then
        SetLightShapesToggleEmissive("lightswitchergas", false)
        SetShapesToggleEmissive("lightswitchergas", false)
        PlaySound(powerOn)
        lightswitchergas = 0
        if broken then
            -- Both shapes broken, exiting
            DISABLED = cEntity:EnqueueDeletion()
            return
        end
    end

    local interact = GetPlayerInteractShape()
    if interact == 0 then return end

    if InputPressed("interact")
    and (interact == lightswitcher or interact == lightswitchergas) then
        local ret = ExecOnInteract(interact)
        if ret == nil then return end

        if interact == lightswitchergas then
            PlaySound(powerOn)
        else
            if ret then
                PlaySound(clickUp)
            else
                PlaySound(clickDown)
            end
        end
    end
end


function SetLightShapesToggleEmissive(tag, state)
    local lights = FindLights(tag, true)
    local newstate
    for i = 1, #lights do
        local light = lights[i]
        newstate = (state and 1 or state == false and 0) or IsLightActive(light) and 0 or 1
        SetShapeEmissiveScale(GetLightShape(light), newstate)
    end
    return newstate
end

function SetShapesToggleEmissive(tag, state)
    local shapes = FindShapes(tag, true)
    local newstate
    for i = 1, #shapes do
        local shape = shapes[i]
        newstate = (state and 1 or state == false and 0) or GetProperty(shape, "emissiveScale") == 1 and 0 or 1
        SetShapeEmissiveScale(shape, newstate)
    end
    return newstate
end

function ToggleEmissive(tag)
    local ret = SetLightShapesToggleEmissive(tag)
    ret = SetShapesToggleEmissive(tag) or ret
    return ret
end

function ExecOnInteract(target)
    if not HasTag(target, "oninteract") then return end

    local f, args = GetTagValue(target, "oninteract"):match"[@]?(.-)[(](.*)[)]"

    local args_t = {}
    for n in args:gmatch"[^,]+" do
        local not_, f, args = n:match"(.-)%s?([%w]+)[(](.*)[)]"
        n = n:gsub("child", target+n:count("child"), 1):gsub("child", "")
        n = n:gsub("this", tonumber(target))
        n = n:gsub("script", tonumber(script))
        if f then
            local _args_t = {}
            for _n in args:gmatch"[^,]+" do
                _args_t[#_args_t+1] = tonumber(_n) or _n:as_bool() or _n
            end
            local result = _G[f](unpack(_args_t))
            n = not_ == "not_" and not result or result
        end
        args_t[#args_t+1] = type(n)=="string" and (tonumber(n) or n:as_bool() or (n:gsub("|"," "))) or n
    end
    return _G[f](unpack(args_t))
end
