--------------------------------------------------------------------------
--[[ AmbientLighting ]]
--------------------------------------------------------------------------

return Class(function(self, inst)

--------------------------------------------------------------------------
--[[ Constants ]]
--------------------------------------------------------------------------

local PHASE_COLOURS =
{
    day = { colour = Point(255 / 255, 230 / 255, 158 / 255), time = 4 },
    dusk = { colour = Point(100 / 255, 100 / 255, 100 / 255), time = 6 },
    night = { colour = Point(0 / 255, 0 / 255, 0 / 255), time = 8 },
}

local CAVE_COLOUR = { colour = Point(0 / 255, 0 / 255, 0 / 255), time = 2 }

--------------------------------------------------------------------------
--[[ Member variables ]]
--------------------------------------------------------------------------

--Public
self.inst = inst

--Private
local _world = TheWorld
local _iscave = _world:HasTag("cave")
local _updating = false
local _remainingtimeinlerp = 0
local _totaltimeinlerp = 0
local _lerpfromcolour = Point()
local _lerptocolour = Point()
local _currentcolour = _iscave and Point(CAVE_COLOUR.colour:Get()) or Point(PHASE_COLOURS.day.colour:Get())
local _lightpercent = 1
local _flash = false
local _flashtime = 0
local _flashintensity = 1

local _caveTiles = {
    [GROUND.CAVE] = true,
    [GROUND.FUNGUS] = true,
    [GROUND.FUNGUSRED] = true,
    [GROUND.FUNGUSGREEN] = true,
    [GROUND.SINKHOLE] = true,
    [GROUND.UNDERROCK] = true,
    [GROUND.MUD] = true,
    [GROUND.UNDERGROUND] = true,
    [GROUND.BRICK] = true,
    [GROUND.BRICK_GLOW] = true,
    [GROUND.TILES] = true,
    [GROUND.TILES_GLOW] = true,
    [GROUND.TRIM] = true,
    [GROUND.TRIM_GLOW] = true,
}

--------------------------------------------------------------------------
--[[ Private member functions ]]
--------------------------------------------------------------------------

local function SetColour(dest, src)
    dest.x, dest.y, dest.z = src:Get()
end

local function Start()
    if not _updating then
        inst:StartUpdatingComponent(self)
        _updating = true
    end
end

local function Stop()
    if _updating then
        inst:StopUpdatingComponent(self)
        _updating = false
    end
end

local function PushCurrentColour()
    TheSim:SetAmbientColour(_currentcolour.x * _lightpercent, _currentcolour.y * _lightpercent, _currentcolour.z * _lightpercent)
end

--------------------------------------------------------------------------
--[[ Private event handlers ]]
--------------------------------------------------------------------------

local function OnPhaseChanged(src, phase)
	local playerpos = player ~= nil and Vector3(player.Transform:GetWorldPosition()) or Vector3(0, 0, 0)
	local x, y = _map:GetTileCoordsAtPoint(playerpos:Get())
	local tile = _map:GetTile(x, y)
    local col = _caveTiles[tile] and CAVE_COLOUR or PHASE_COLOURS[phase]
    if col == nil then
        return
    end

    if _flash then
        SetColour(_lerptocolour, col.colour)
    else
        _remainingtimeinlerp = col.colour ~= _currentcolour and col.time or 0
        if _remainingtimeinlerp > 0 then
            _totaltimeinlerp = _remainingtimeinlerp
            SetColour(_lerpfromcolour, _currentcolour)
            SetColour(_lerptocolour, col.colour)
            Start()
        else
            SetColour(_currentcolour, col.colour)
            Stop()
        end
        PushCurrentColour()
    end
end

local function OnWeatherTick(src, data)
    _lightpercent = data.light
    if not _flash then
        PushCurrentColour()
    end
end

local function OnScreenFlash(src, intensity)
    if _remainingtimeinlerp > 0 then
        _remainingtimeinlerp = 0
    elseif not _flash then
        SetColour(_lerptocolour, _currentcolour)
    end
    _flash = true
    _flashtime = 0
    _flashintensity = intensity
    Start()
end

--------------------------------------------------------------------------
--[[ Initialization ]]
--------------------------------------------------------------------------

PushCurrentColour()

--Register events
inst:ListenForEvent("phasechanged", OnPhaseChanged, _world)
inst:ListenForEvent("weathertick", OnWeatherTick, _world)
inst:ListenForEvent("screenflash", OnScreenFlash, _world)

--------------------------------------------------------------------------
--[[ Update ]]
--------------------------------------------------------------------------

function self:OnUpdate(dt)
	print("custom ambientlightning")
    if _flash then
        _flashtime = _flashtime + dt
        if _flashtime < 3 / 60 then
            TheSim:SetAmbientColour(0, 0, 0)
        elseif _flashtime < 7 / 60 then
            TheSim:SetAmbientColour(_flashintensity, _flashintensity, _flashintensity)
        elseif _flashtime < 9 / 60 then
            TheSim:SetAmbientColour(0, 0, 0)
        elseif _flashtime < 17 / 60 then
            TheSim:SetAmbientColour(_flashintensity, _flashintensity, _flashintensity)
        else
            _flash = false
            _currentcolour.x = _lerptocolour.x * .5
            _currentcolour.y = _lerptocolour.y * .5
            _currentcolour.z = _lerptocolour.z * .5
            if _currentcolour ~= _lerptocolour then
                SetColour(_lerpfromcolour, _currentcolour)
                _totaltimeinlerp = 1.5
                _remainingtimeinlerp = _totaltimeinlerp
            else
                Stop()
            end
            PushCurrentColour()
        end
    elseif _remainingtimeinlerp > 0 then
        _remainingtimeinlerp = _remainingtimeinlerp - dt
        if _remainingtimeinlerp > 0 then
            local frompercent = _remainingtimeinlerp / _totaltimeinlerp
            local topercent = 1 - frompercent
            _currentcolour.x = _lerpfromcolour.x * frompercent + _lerptocolour.x * topercent
            _currentcolour.y = _lerpfromcolour.y * frompercent + _lerptocolour.y * topercent
            _currentcolour.z = _lerpfromcolour.z * frompercent + _lerptocolour.z * topercent
        else
            SetColour(_currentcolour, _lerptocolour)
            Stop()
        end
        PushCurrentColour()
    end
end

function self:LongUpdate(dt)
    if _updating then
        SetColour(_currentcolour, _lerptocolour)
        _flash = false
        _remainingtimeinlerp = 0
        PushCurrentColour()
        Stop()
    end
end

--------------------------------------------------------------------------
--[[ End ]]
--------------------------------------------------------------------------

end)