-- Third light appears at 30
-- Combining starts at 1:15
-- Scene changes at 2:00

_G.clearColor = { red = 0, green = 0, blue = 0.1 }

_G.time = 0
local model = {
	layer = "3d",
	uniforms = {
		directionalLight = { 1, 1, 0 },
		intensity = 0.7,
		ambientLight = 0.5,
		color = { 0, 0, 1, 1 },
	}
}

local getPosition = function(channel, offset)
	--print(offset)
	local time = _G.time * 10 + offset
	local area = 700
	local t = time - math.floor(time)
	local pixel0 = _G.resources.getColorFromTexture("perlin_noise", math.abs(time) % (512 * 512), channel) / 255 * area - area/2
	local pixel1 = _G.resources.getColorFromTexture("perlin_noise", math.abs(time + 1) % (512 * 512), channel) / 255 * area - area/2
	return _G.lerp(pixel0, pixel1, t)
end

_G.renderTextureTargets = {
	effect1 = { width = _G.config.width, height = _G.config.height },
	effect2 = { width = _G.config.width, height = _G.config.height },
	effect3 = { width = _G.config.width, height = _G.config.height },
	effect4 = { width = _G.config.width, height = _G.config.height },
	birds = { width = _G.config.width, height = _G.config.height },
}
_G.graphics.createRenderTargets()

local light = {
	texture = "light",
	layer = "rays1",
	perlinStrength = 0.6,
	x = function(self) return getPosition(0, self.offset) * _G.get(self.perlinStrength) end,
	y = function(self) return getPosition(1, self.offset) * _G.get(self.perlinStrength) - 50 end,
	scale = 2,
	offset = 0,
	uniforms = {
		color = { 0.4, 0.4, 1, 1 },
	}
}

local light0 = _G.instance{light, offset = 0}
local light1 = _G.instance{light, offset = 100}
local light2 = _G.instance{light, offset = 200}

local rays = {
	texture = "effect3",
	fs = "radial_blur_x3",
	layer = "rays2",
	enabled = function(self) return self.light.enabled end,
	uniforms = {
		source0 = { function() return light0.x(light0) / _G.config.width + 0.5 end, function() return light0.y(light0) / _G.config.height + 0.5 end }, --uniform vec2 source;
		source1 = { function() return light1.x(light1) / _G.config.width + 0.5 end, function() return light1.y(light1) / _G.config.height + 0.5 end }, --uniform vec2 source;
		source2 = { function() return light2.x(light2) / _G.config.width + 0.5 end, function() return light2.y(light2) / _G.config.height + 0.5 end }, --uniform vec2 source;
		decay = 1, --uniform float decay;
		samples = 100, --uniform float samples;
		density = 1,
		strength0 = 6,
		strength1 = 6,
		strength2 = 6,
	},
}

local fog = {
	texture = "fog1_small",
	layer = "fog",
	fs = "fog",
	width = config.width * 2,
	height = config.height * 2,
	scale = 2,
	speed = 0.6,
	uniforms = {
		color = { 0.7, 0.6, 0.6, 1 },
		offset = { function(self) return _G.time / 5 * self.speed end, function(self) return -_G.time / 8 * self.speed end },
		threshold = 0--function(self) return (math.sin(time * self.speed) + 1) / 2 * 0.2 end,
	},
}

local birds = {
	x = -1000,
	y = -200,
	layer = "birds",
	particles = {
		sprites = { "Swallow-in-flight_1", "Swallow-in-flight_2", "Swallow-in-flight_3", "Swallow-in-flight_4" },
		frequency = 200,
		emit = function()
			local randomDir = (math.random() - 0.5) * 2
			local sign = (randomDir < 0 and -1 or 1)
			local dir = math.pow(randomDir / 0.8, 1.2) * 3.141593 / 4 * sign + 0.1
			local startOffsetX = math.random() * 100
			local startOffsetY = math.random() * 100 - 200
			local shouldComeCloser = math.random() < 0.015
			local dist = math.random() * 200 + 1400 + (shouldComeCloser and 1200 or 0)
			return {
				lifeTime = shouldComeCloser and 3 or 2.5,
				sprite = function(i)
					local modifiedI = i * 40
					if math.floor(modifiedI / 4) % 2 == 0 then return modifiedI % 4 else return 4 - (modifiedI % 4) end
				end,
				x = function(i) return i * dist * math.cos(dir) + startOffsetX end,
				y = function(i) return math.pow(i, 1.4) * dist * math.sin(dir) + startOffsetY end,
				scale = function(i) if shouldComeCloser then return 0.7 + i * 2 else return 0.7 - math.pow(i, 2) * 0.7 + 0.1 end end,
				rotation = dir / 10,
				alpha = function(i) if shouldComeCloser then return 1 else return 0.9 - math.pow(i, 4) * 0.9 + 0.1 end end,
			}
		end,
	},
}

local waterTexture = { texture = "effect4", layer = "water", y = 0, scaleY = -1, fs = "pt_offset", uniforms = { offsetTextureSampler = "perlin_noise", offset = { function() return _G.time * 0.4 end, function() return _G.time * 0.4 end }, strength = _G.tween(0, 0.3, 60, 0, false, _G.bezier.make({0.000,0.000,0.791,0.223,0.564,1.000,1.000,1.000,})) } }

local moon = {
	enabled = false,
	{ texture = "moon", layer = "moon", uniforms = { color = { 1, 1, 1, 0.5 } } },
	{ camera = { layer = "moon", target = "effect4" } }
}

_G.world = {
	light0, light1, light2,
	rays,
	{ _G.instance{model, model = "Dead_Trees_01", scale = 0.4, y = -30, rotationZ = -2, layer = "mask", fs = "black", uniforms_ambientLight = 0, uniforms_intensity = 0.1} },
	{ _G.instance{model, model = "Dead_Trees_01", scale = 0.4, y = -30, rotationZ = -2, layer = "trees", fs = "trees", vs = "trees", uniforms_rimIntensity = 0.3, uniforms_rimDist = 20, uniforms_forward = { 0, 0, 1 }, uniforms_ambientLight = 0, uniforms_intensity = 0.1, } },
	_G.instance{fog, scale = 1.5, speed = 0.3, texture = "fog2_small", uniforms_color_4 = 0.8},
	_G.instance{fog, x = 0, speed = 0.5, uniforms_color_4 = 0.5},
--	{ texture = "effect2", layer = "effect2", y = config.height / 2 - 20 },
	waterTexture,
--	{ texture = "perlin_noise", layer = "waterFog", scale = 0.04, rotationX = -70, y = -4.6, width = config.width * 2, fs = "fog", uniforms = { color = { 1, 1, 1, 0.1 }, threshold = 0, offset = { function(self) return -time / 30 * self.speed end, function(self) return time / 40 * self.speed end } } },
	{ camera = { layer = "rays1", target = "effect1" } },
	birds,
	{ camera = { layer = "birds", target = "birds" } },
	{ texture = "birds", layer = "birdsMask", uniforms = { color = { 0, 0, 0, 0.5 } } },
	{ texture = "birds", layer = "birdsScreen" },
	{ camera = { layer = "birdsMask", target = "effect1" } },
	{
		offset = 0,
		xBezier = _G.bezier.make({0.000,0.000,0.300,0.000,0.327,0.041,0.500,0.386,0.500,0.386,0.800,0.800,0.782,0.677,1.000,1.000,}),
		x = function(self) return self.xBezier(self, math.min(1.0, _G.time / 60), -100, 60) end,
		--x = function(self) return getPosition(0, self.offset) / 200 + self.xCurve(_, _G.time / 10) end,
		y = function(self) return getPosition(1, self.offset) / 200 end,
		z = function(self) return getPosition(2, self.offset) / 200 end,
		{ camera = { fov = 70, layer = "mask",  target = "effect1" }, z = 20 },
		{ camera = { fov = 70, layer = "trees", target = "effect4" }, z = 20 },
		{ camera = { layer = "fog", target = "effect4" } },
	},
	moon,
	{ camera = { layer = "birdsScreen", target = "effect4" } },
	{ texture = "effect1", layer = "blur1", fs = "pt_blur_horizontal", uniforms = { strength = 1, spread = 2 } },
	{ texture = "effect2", layer = "blur2", fs = "pt_blur_vertical", uniforms = { strength = 1, spread = 2 } },
	{ camera = { layer = "blur1", target = "effect2" } },
	{ camera = { layer = "blur2", target = "effect3" } },
	{ camera = { layer = "rays2", target = "effect4" } },
	{ camera = { layer = "water" } },
--	{ camera = { fov = 70, layer = "waterFog" }, z = 20 },
--	{ texture = "effect1", layer = "test", scaleY = -1 },
--	{ camera = { layer = "test" } },
}

--_G.timeScale = 60
birds.enabled = false
local lightAppearBezier = _G.bezier.make({0.000,0.000,0.136,0.986,0.400,0.986,0.409,0.477,0.409,0.477,0.445,0.000,0.791,0.000,1.000,0.5,})
light0.enabled = false
light1.enabled = false
light2.enabled = false
rays.uniforms.strength0 = 0
rays.uniforms.strength1 = 0
rays.uniforms.strength2 = 0
_G.wait(1)
_G.audio.playMusic("swamp.mp3")
_G.wait(8)
rays.uniforms.strength0 = 6
light0.enabled = true
light0.scale = _G.tween(0, 4, 1, 0, false, lightAppearBezier)
_G.wait(7)
light0.scale = _G.tween(1, 2, 1, 0, false, _G.bezier.make({0.000,1.000,0.409,0.000,0.636,0.000,1.000,1.000,}))
_G.wait(1)
rays.uniforms.strength1 = 6
light1.enabled = true
light1.scale = _G.tween(0, 4, 1, 0, false, lightAppearBezier)
_G.wait(7)
light0.scale = _G.tween(1, 2, 0.5, 0, false, _G.bezier.make({0.000,1.000,0.409,0.000,0.636,0.000,1.000,1.000,}))
_G.wait(0.5)
light1.scale = _G.tween(1, 2, 0.5, 0, false, _G.bezier.make({0.000,1.000,0.409,0.000,0.636,0.000,1.000,1.000,}))
_G.wait(0.5)
rays.uniforms.strength2 = 6
light2.enabled = true
light2.scale = _G.tween(0, 4, 1, 0, false, lightAppearBezier)
_G.wait(22)
--_G.timeScale = 1
light0.scale = _G.tween(2, 4, 0.5, 0, true, _G.bezier.make({0.000,0.000,0.000,0.427,0.045,1.000,0.264,1.000,0.264,1.000,0.445,1.000,0.518,0.491,0.518,0.000,0.518,0.000,0.764,0.000,0.909,0.000,1.000,0.000,}))
light1.scale = _G.tween(2, 4, 0.5, 0, true, _G.bezier.make({0.000,0.000,0.000,0.427,0.045,1.000,0.264,1.000,0.264,1.000,0.445,1.000,0.518,0.491,0.564,0.000,0.564,0.000,0.764,0.000,0.909,0.000,1.000,0.000,}))
light2.scale = _G.tween(2, 4, 0.5, 0, true, _G.bezier.make({0.000,0.000,0.000,0.427,0.045,1.000,0.264,1.000,0.264,1.000,0.445,1.000,0.518,0.491,0.664,0.000,0.664,0.000,0.764,0.000,0.909,0.000,1.000,0.000,}))
_G.wait(10)
light0.scale = 2
light1.scale = 2
light2.scale = 2
_G.wait(10)
light0.perlinStrength = _G.tween(light0.perlinStrength, 0, 5, 0, false)
light1.perlinStrength = _G.tween(light1.perlinStrength, 0, 5, 0, false)
light2.perlinStrength = _G.tween(light2.perlinStrength, 0, 5, 0, false)
light0.scale = _G.tween(_G.get(light0.scale), 4, 5, 0, false)
light1.scale = _G.tween(_G.get(light1.scale), 4, 5, 0, false)
light2.scale = _G.tween(_G.get(light2.scale), 4, 5, 0, false)
_G.wait(6)
waterTexture.uniforms.strength = _G.tween(_G.get(waterTexture.uniforms.strength), 0.1, 4, 0, false)
local lightScaleBezier = _G.bezier.make({0.000,0.000,0.636,0.000,0.445,1.000,1.000,1.000,})
light2.scale = _G.tween(_G.get(light0.scale), 20, 5, 0, false, lightScaleBezier)
light1.scale = _G.tween(_G.get(light0.scale), 20, 5, 0, false, lightScaleBezier)
light0.scale = _G.tween(_G.get(light0.scale), 20, 5, 0, false, lightScaleBezier)
rays.uniforms.strength0 = _G.tween(_G.get(rays.uniforms.strength0), 1.6, 0.5, 0, false, lightScaleBezier)
rays.uniforms.strength1 = _G.tween(_G.get(rays.uniforms.strength0), 1.6, 0.5, 0, false, lightScaleBezier)
rays.uniforms.strength2 = _G.tween(_G.get(rays.uniforms.strength0), 1.6, 0.5, 0, false, lightScaleBezier)
moon.enabled = true
moon[1].uniforms.color[4] = _G.tween(0, 0.5, 3, 2)
_G.timeScale = 1
_G.wait(2)
birds.enabled = true
--rays.uniforms.strength0 = 2.3
--rays.uniforms.strength1 = 2.3
--rays.uniforms.strength2 = 2.3
birds.particles.frequency = _G.tween(0, 400, 8, 0, false, _G.bezier.make({0.000,0.000,0.518,0.036,0.891,0.086,1.000,1.000,}))
_G.wait(10)
waterTexture.uniforms.strength = _G.tween(0, 1.5, 4, 0, false)
_G.wait(1)
rays.uniforms.strength0 = _G.tween(_G.get(rays.uniforms.strength0), 6, 4, 0, false, lightScaleBezier)
rays.uniforms.strength1 = _G.tween(_G.get(rays.uniforms.strength0), 6, 4, 0, false, lightScaleBezier)
rays.uniforms.strength2 = _G.tween(_G.get(rays.uniforms.strength0), 6, 4, 0, false, lightScaleBezier)
_G.wait(3)
light0.scale = _G.tween(_G.get(light0.scale), 50, 5, 0, false)
light1.scale = _G.tween(_G.get(light0.scale), 50, 5, 0, false)
light2.scale = _G.tween(_G.get(light0.scale), 50, 5, 0, false)
_G.wait(5)
table.insert(_G.world, { { texture = "square", width = _G.config.width, height = _G.config.height, layer = "overlay", uniforms = { color = { 1, 1, 1, _G.tween(0, 1, 3, 0, false) } } }, { camera = { layer = "overlay" } } })

_G.wait(4)
_G.loadLevel("tunnel.lua")
