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

_G.time = 0

local blurTextureSize = 8
local lightValueSize = 1

_G.renderTextureTargets = {
	test = { width = 64, height = 64 },
	effect1 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	effect2 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	effect3 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	effect4 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	effect5 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	effect6 = { width = config.width / blurTextureSize, height = config.height / blurTextureSize },
	bushDirectionalLightMask1 = { width = config.width / lightValueSize, height = config.height / lightValueSize },
	bushDirectionalLightMask2 = { width = config.width / lightValueSize, height = config.height / lightValueSize },
	bushDirectionalLightMask3 = { width = config.width / lightValueSize, height = config.height / lightValueSize },
}
_G.graphics.createRenderTargets()

local letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 136<"
local letterSettings = {}
for i = 1, #letters do
	local c = string.sub(letters, i,i)
	letterSettings[c] = {
		advance = _G.resources.getGlyphAdvance("TrashHand", c),
		left = _G.resources.getGlyphLeft("TrashHand", c),
	}
end
letterSettings["V"].advance = 19
letterSettings["I"].left = -4
letterSettings["S"].left = -4
letterSettings["<"].advance = 20

local letter = {
	model = "A",
	layer = "letter",
	--rotationZ = function() return _G.time * 5 end,
	uniforms = {
		textureSampler = "square",
		intensity = 1,
		ambientLight = 0.5,
		directionalLight = { 0, 1, 1 },
		color = { 1, 0.4, 0.4, 1 },
	},
}

local write = function(text)
	local result = {  }
	local x = 0
	for i = 1, #text do
		local c = string.sub(text, i,i)
		local settings = letterSettings[c]
		if c == "," then settings = letterSettings["A"]; c = "AE" end
		if c == "." then settings = letterSettings["B"]; c = "OE" end
		if c == "<" then c = "LT" end
		--print("LEFT " .. c .. " " .. settings.left .. " " .. settings.advance)
		if c ~= " " then
			table.insert(result, instance{letter, model = c, x = x + settings.left })
		end
		if i ~= #text then x = x + settings.advance * 0.8 + 12 end
	end
	for i = 1, #result do
		result[i].x = result[i].x - x / 2
		result[i].z = -math.sin(result[i].x / 50 + 3.142 / 2) * 20
		result[i].rotationY = -result[i].x / 4
		result[i].rotationZ = function() return math.sin(_G.time * 2 + i / 2) * 5 end
		result[i].y = function() return math.sin(_G.time * 2 + i / 2) * 5 end

	end
	return result;
end

local textRotationCurve = _G.bezier.make({0.000,0.000,0.000,1.000,1.000,0.000,1.000,1.000,})
local textIntensityCurve = _G.bezier.make({0.000,0.000,0.000,0.445,0.000,1.000,0.545,1.000,0.545,1.000,1.000,1.000,1.000,0.264,1.000,0.000,})
local textTweenDuration = 6

local blurStrength = function() return (math.sin(_G.time) + 1) / 40 + 1 end
local lightDirection = _G.tween(-3.142, 3.142, textTweenDuration, 0, true, textRotationCurve)
local directionalLightForFlowers = {
	function() return math.cos(_G.get(lightDirection)) end,
	function() return math.sin(_G.get(lightDirection)) end,
	function() return math.sin(_G.get(lightDirection)) end,
	--function() return -math.sin(_G.get(lightDirection)) * 0.5 end,
}

local makeBush = function(layer, fs, uniforms, enabled) return {
	{ i = 1, model = "Flower11_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 2, model = "Flower10_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 3, model = "Flower2_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 4, model = "Flower3_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 5, model = "Flower4_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 6, model = "Flower5_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 7, model = "Flower6_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 8, model = "Flower7_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 9, model = "Flower8_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 10, model = "Flower9_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 11, model = "Leaves_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	{ i = 12, model = "Roots_Bush", enabled = enabled, layer = layer, fs = fs, uniforms = uniforms },
	scale = 0.05,
	x = 3,
	y = -2,
	z = -8,
	--rotationY = 90,
} end

local text = {
}

local lightEnabledFlag = true
local lightEnabled = function() return _G.random > 0.05 and lightEnabledFlag end
local flowerChangeInterval = 2
_G.world = {
--	{ write("ABBA"), scale = 0.1 },
--	{ write("ABBA"), scale = 0.1 },
--	{ model = "Flower02", scale = 0.1, uniforms = { textureSampler = "square", directionalLight = { 1, 1, 1 }, ambientLight = 0.5, intensity = 0.4 } },
	{
		{ write("ABCDEFGHIJKLMNOPQRSTUVWXYZ136<.,"), layer = "preload", scale = 0, x = 100000 },
		{ camera = { layer = "preload" } },
	},
	{
		rotationZ = function() return math.sin(_G.time) * 2 - 15 end,
		rotationY = _G.tween(-110, 90, textTweenDuration, 0, true, textRotationCurve),
		{
			text,
			scale = 0.08,
			z = -30,
			y = 4,
		}
	},
	{ camera = { fov = 35, layer = "letter", target = "effect1" } },

	{ texture = "effect1", layer = "textEffect1", scale = blurTextureSize, uniforms = { color = { 100, 100, 100, 1 } } },
	{ camera = { layer = "textEffect1", target = "effect2" } },

	{ texture = "effect2", layer = "textEffect2", scale = blurTextureSize, fs = "blur_horizontal_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "textEffect2", target = "effect3" } },

	{ texture = "effect3", layer = "textEffect3", scale = blurTextureSize, fs = "blur_vertical_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "textEffect3", target = "effect4" } },

	{ texture = "effect4", layer = "textEffect4", scale = blurTextureSize, fs = "blur_horizontal_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "textEffect4", target = "effect5" } },

	{ texture = "effect5", layer = "textEffect5", scale = blurTextureSize, fs = "blur_vertical_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "textEffect5", target = "effect6" } },

	{ texture = "effect5", layer = "textEffect7", scale = blurTextureSize * 1.1, fs = "pt_additive", uniforms = { color = { 0.5, 0.2, 1, 1 } }, enabled = lightEnabled },
	{ camera = { layer = "textEffect7" } },

	{ camera = { fov = 35, layer = "letter" } },

	{ texture = "effect5", layer = "textEffect6", scale = blurTextureSize, fs = "pt_additive", uniforms = { color = { 1, 0.4, 0.5, 1 } }, enabled = lightEnabled },
	{ camera = { layer = "textEffect6" } },

	--makeBush("bush", "pnt", { ambientLight = ambientLightForFlowers, intensity = intensityForFlowers, directionalLight = directionalLightForFlowers, textureSampler = "flowertunnel_FlowersTexture_dark" }, true),
	makeBush("bushDirectionalLightMask1", "lightValue", { ambientLight = 0.2, intensity = _G.tween(0.0, 1, textTweenDuration, 0, true, textIntensityCurve), directionalLight = directionalLightForFlowers, textureSampler = "flowertunnel_FlowersTexture_dark" }, true),
	makeBush("bushSingleFlower", "pnt", { color = { 0.6, 0.1, 1, 1 }, ambientLight = _G.tween(0, 0.5, flowerChangeInterval, 0, true, textIntensityCurve), intensity = _G.tween(0, 1, flowerChangeInterval, 0, true, textIntensityCurve), directionalLight = directionalLightForFlowers, textureSampler = "flowertunnel_FlowersTexture_Bright" }, function(self) return (_G.time / flowerChangeInterval % 10 > self.i - 1) and (_G.time / flowerChangeInterval % 10 < self.i) end),

	{ camera = { fov = 66, layer = "bushSingleFlower", target = "bushDirectionalLightMask1", clearTarget = true } },
	{ texture = "bushDirectionalLightMask1", layer = "blurFlower1", scale = lightValueSize, fs = "blur_horizontal_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "blurFlower1", target = "bushDirectionalLightMask2", clearTarget = true } },
	{ texture = "bushDirectionalLightMask2", layer = "blurFlower2", scale = lightValueSize, fs = "blur_vertical_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "blurFlower2", target = "bushDirectionalLightMask3", clearTarget = true } },
	{ texture = "bushDirectionalLightMask3", layer = "blurFlower3", scale = lightValueSize, fs = "pt_additive" },
	{ camera = { layer = "blurFlower3" } },
	{ texture = "bushDirectionalLightMask3", layer = "blurFlower4", scale = lightValueSize },
	{ camera = { layer = "blurFlower4", target = "effect1", clearTarget = true } },
	{ texture = "effect1", layer = "blurFlower5", scale = blurTextureSize, fs = "blur_horizontal_big", uniforms = { spread = 1, strength = blurStrength } },
	{ camera = { layer = "blurFlower5", target = "effect2", clearTarget = true } },
	{ texture = "effect2", layer = "blurFlower6", scale = blurTextureSize, fs = "blur_vertical_big", uniforms = { spread = 1, strength = blurStrength } },
	{ camera = { layer = "blurFlower6", target = "effect3", clearTarget = true } },
	{ texture = "effect3", layer = "blurFlower7", scale = blurTextureSize },
	{ camera = { layer = "blurFlower7" } },


	{ camera = { fov = 66, layer = "bushDirectionalLightMask1", target = "bushDirectionalLightMask1", clearTarget = true }  },
	{ texture = "flower_lightmask", layer = "bushDirectionalLightMask2", scaleY = -2, scale = 2, x = -489, y = -188},
	{ camera = { layer = "bushDirectionalLightMask2", target = "bushDirectionalLightMask2", clearTarget = true } },
	{ texture = "bushDirectionalLightMask2", layer = "bushDirectionalLightMask3", scale = lightValueSize, fs = "pt_mask", uniforms = { maskTextureSampler = "bushDirectionalLightMask1" } },
	{ camera = { layer = "bushDirectionalLightMask3", target = "bushDirectionalLightMask3", clearTarget = true } },
	{ texture = "bushDirectionalLightMask3", layer = "bushDirectionalLightMask4", scale = lightValueSize },
	{ camera = { layer = "bushDirectionalLightMask4", target = "effect1", clearTarget = true } },
	{ camera = { layer = "bushDirectionalLightMask4" } },

	{ texture = "effect1", layer = "blurBush1", scale = blurTextureSize, fs = "blur_horizontal_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "blurBush1", target = "effect2", clearTarget = true } },
	{ texture = "effect2", layer = "blurBush2", scale = blurTextureSize, fs = "blur_vertical_big", uniforms = { spread = 0.5, strength = blurStrength } },
	{ camera = { layer = "blurBush2", target = "effect3", clearTarget = true } },
	{ texture = "effect3", layer = "blurBush3", scale = blurTextureSize, enabled = lightEnabled },
	{ camera = { layer = "blurBush3" } },

	{
		layer = "particles",
		uniforms = { color = { 0.8, 0.2, 1, 1} },
		particles = {
			fs = "ptc_additive",
			frequency = 350,
			sprite = "light",
			emit = function()
				local offsetX = -1000 + math.random() * 2000
				local offsetY = -300 + math.random() * 100
				local offsetZ = -math.random() * 3000
				local lifeTime = math.random() * 2 + 7
				local alpha = math.random() * 0.2 + 0.2
				local sinX = math.random() * 70
				local sinXSpeed = math.random() * 20
				local z = math.random()
				local createdAt = _G.time
				local scale = math.pow(math.random(), 10) * 10 + 0.2
				local totalXOffset = 0
				local wind = 0
				local windFactor = math.random() * 0.6 + 0.1 + (10.1 - scale) * 0.05
				local windCatchOffset = math.random() * 0.02
				return {
					lifeTime = lifeTime,
					x = function(i, self)
						if self then
							if not (createdAt < textTweenDuration) and not (createdAt > textTweenDuration * 5) then
								local time = createdAt + i * lifeTime
								local startTime = 0.82 - offsetX / 15000 + windCatchOffset
								wind = wind + math.pow(math.max(0, (time % textTweenDuration) / textTweenDuration - startTime) / (1 - startTime), 2) * -200 * windFactor
								totalXOffset = (totalXOffset + wind)
								wind = wind * 0.9
							end
						end
						return offsetX + math.sin(i * sinXSpeed) * sinX + totalXOffset
					end,
					y = function(i) return i * (800 + z * 500) + offsetY - math.abs(offsetX - (-500)) / 2 + 400 end,
					z = function() return offsetZ end,
					scale = scale,
					alpha = function(i, self)
						return math.max(0, math.sin(i * 3.141) * alpha - math.max(0, offsetX) / 1000)
					end,
				}
			end
		},
	},
	{ camera = { layer = "particles" }, z = 10 },

	{ texture = "square", width = _G.config.width, height = _G.config.height, layer = "overlay", uniforms = { color = { 0, 0, 0, _G.tween(1, 0, 2, 1, false) } } },
  	{ camera = { layer = "overlay" } },
--	{ texture = "blurtest", layer = "blurtest", fs = "pt_blur_vertical", scale = 2, uniforms = { spread = 1, strength = 1 } },
--	{ camera = { layer = "blurtest", width = 128, height = 128, target = "test" } },
--	{ texture = "test", layer = "blurtest2" },
--	{ camera = { layer = "blurtest2", width = 64, height = 64 } },

 --uniforms = { color = { 1, 1, 1, _G.tween(0, 1, textTweenDuration, 0, true, textIntensityCurve) } }
}

--_G.wait(textTweenDuration)
_G.wait(textTweenDuration)

table.remove(_G.world, 1)

_G.audio.playMusic("credits.mp3")

table.insert(text, { { write("RHODODENDRON"), scale = 0.7 } } )
_G.wait(textTweenDuration)
_G.clear(text)
table.insert(text, { { write("CREATED BY"), scale = 0.6 }, { write("VIHANNES"), scale = 0.8, y = -35 } })
_G.wait(textTweenDuration)
_G.clear(text)
table.insert(text, { { write("CODE AND MUSIC"), scale = 0.6 }, { write("TIKOTUS"), scale = 0.7, y = -37 } })
_G.wait(textTweenDuration)
_G.clear(text)
table.insert(text, { { write("ART"), scale = 0.7 }, { write("VILMA"), scale = 0.7, y = -34 } })
_G.wait(textTweenDuration)
_G.clear(text)
table.insert(text, { write("GREETS"), scale = 0.7 })
_G.wait(textTweenDuration / 2)
lightDirection = _G.get(lightDirection)
_G.world[1].rotationY = _G.get(_G.world[1].rotationY)
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("SIVU"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("DZARG"), scale = 0.8 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("XMUNKKI"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("DIDUCT"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("POTRI"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("PIKKI"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("NYSTUL"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { { write("SERIOUSLY"), scale = 0.6 }, { write("DIGITAL"), scale = 0.6, y = -34 }, { write("ENTERTAINMENT"), scale = 0.6, y = -68 } })
_G.wait(2.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { write("ASM16"), scale = 0.7 })
_G.wait(1.8)
lightEnabledFlag = false
_G.wait(0.2)
lightEnabledFlag = true
_G.clear(text)
table.insert(text, { { write("THANK YOU"), scale = 0.7 }, { write("<3"), scale = 0.9, y = -40 } } )
_G.wait(2.8)
lightEnabledFlag = false
_G.clearColor = { red = 0, green = 0, blue = 0 }
_G.world = {}
_G.wait(2)
_G.app.quit()
