-- Remember latpack?
-- Heres the lua for the changing textures in SPIRAL.

-- I had to sacrifice moving textures for this.

-- Texture and flat lookup tables
local textures = {}
local floors = {}
local skies = {}

-- where we save the base textures for everything so we know what we're doing...
local mapsides = {}
local mapfloors = {}

-- Target textures
local targetmapsides = {}
local targetmapfloors = {}

-- Last color
local lastcolor = 0
local changetimer = 0

-- Manual tables yeah
floors["GROVF3"] = {"GFZFLR01", "NFBRKA01", "NFBRKA02", "NFBRKA03", "GAYWL", "NFBRKA01", "NFBRKA02", "NFBRKA03", "GAYWL", "GROVF3", "~024"}

-- GFZROCK the game
textures["GROVW0"] = {"GFZROCK", "NFBRKA02", "NFBRKA03", "NFBRKA01", "GAYWL", "GROVW0", "GROVW0", "GROVW0", "GROVW0", "GAYWL", "~018"}

skies = {1, 4546, 4547, 4548}

local texturebynum = {}

-- we CANNOT do this on script load for SOME REASON
local function Init_TextureNums()
	for k, v in pairs(textures)
		local newt = {}

		for i = 1, #v

			newt[#newt+1] = R_TextureNumForName(v[i])
		end
		local newkey = R_TextureNumForName(k)
		texturebynum[newkey] = newt
	end
end

-- synch everything, that's important.
-- the only real reason we synch this is because we don't want joining mid game to affect us in a bad way
addHook("NetVars", function(net)
	lastcolor = net(lastcolor)
	changetimer = net(changetimer)
	mapsides = net(mapsides)
	mapfloors = net(mapfloors)
	targetmapsides = net(targetmapsides)
	targetmapfloors = net(targetmapfloors)
end)

-- generate the sides, floors etc tables
local function FL_GenerateTextures()
	mapsides = {}
	mapfloors = {}

	for i = 0, #sectors do

		local s = sectors[i]
		if not s continue end

		mapfloors[i] = {false, false}	-- {floor, ceiling}
		local success

		for k, v in pairs(floors)
			if k == s.floorpic
				mapfloors[i][1] = s.floorpic
				success = true
			end
			if k == s.ceilingpic
				mapfloors[i][2] = s.ceilingpic
				success = true
			end
		end

		if not success
			mapfloors[i] = nil
		end
	end


	-- for sides, it's a bit more complex since we can have up to 3 textures, but nothing out of the ordinary.
	for i = 0, #sides do
		local s = sides[i]

		if not s continue end

		mapsides[i] = {false, false, false}	-- top, mid, bottom

		local success

		for k, v in pairs(textures)
			local n = R_TextureNumForName(k)	-- get texturenum from the table key

			if s.toptexture == n
				mapsides[i][1] = s.toptexture
				success = true
			end
			if s.midtexture == n
				mapsides[i][2] = s.midtexture
				success = true
			end
			if s.bottomtexture == n
				mapsides[i][3] = s.bottomtexture
				success = true
			end
		end

		if not success
			mapsides[i] = nil
		end

	end
end

addHook("MapLoad", do
	mapsides = {}
	mapfloors = {}
	targetmapsides = {}
	targetmapfloors = {}

	if mapheaderinfo[gamemap].spiral_r
		Init_TextureNums()
		if not #texturebynum
			FL_GenerateTextures()
		end
	end

	changetimer = 0
	lastcolor = 0
end)

local function FL_RandomizeTextures()
	if changetimer return end	-- lol DON'T

	-- set random target textures for everything!
	local newtarget = lastcolor
	while newtarget == lastcolor
		newtarget = FP_RandomRange(2, 11)
	end
	
	P_SetupLevelSky(skies[(newtarget % 4) + 1], consoleplayer)

	-- never pick the same target twice
	for i = 0, #sectors do
		if not mapfloors[i] continue end
		if not sectors[i] continue end
		local f = mapfloors[i]
		targetmapfloors[i] = {}

		-- floor
		if mapfloors[i][1]
			targetmapfloors[i][1] = floors[f[1]][newtarget]
		end

		-- ceiling
		if mapfloors[i][2]
			targetmapfloors[i][2] = floors[f[2]][newtarget]
		end
	end

	-- do the same for sides
	for i = 0, #sides do
		if not mapsides[i] continue end
		if not sides[i] continue end
		local s = mapsides[i]

		targetmapsides[i] = {}

		if s[1]
			targetmapsides[i][1] = texturebynum[s[1]][newtarget]
		end
		if s[2]
			targetmapsides[i][2] = texturebynum[s[2]][newtarget]
		end
		if s[3]
			targetmapsides[i][3] = texturebynum[s[3]][newtarget]
		end
	end

	changetimer = 1
	lastcolor = newtarget
end

addHook("LinedefExecute", function(line, mobj)
	if not (mobj and mobj.valid and mobj.player and mobj.player.valid) then return end
	mobj.player.spiral_funny = 80
end, "RNGTEXT")

addHook("ThinkFrame", do
	if not mapheaderinfo[gamemap].spiral_r return end

	if not consoleplayer or not consoleplayer.valid return end
	if consoleplayer.spiral_funny and consoleplayer.spiral_funny == 79
		FL_RandomizeTextures()
	end

	if changetimer
		-- flicker the lights for 1 sec and apply new textures!
		changetimer = $+1
		if changetimer >= TICRATE/2
			changetimer = nil
			return
		end

		local flicker = changetimer%5 < 2

		for i = 0, #sectors do
			local s = sectors[i]
			if not s continue end
			local tgt = targetmapfloors[i]

			if not tgt continue end
			local base = mapfloors[i]

			if tgt[1]
				s.floorpic = tgt[1]
			end
			if tgt[2]
				s.ceilingpic = tgt[2]
			end
		end


		-- do the same for sides
		for i = 0, #sides do
			local s = sides[i]
			local tgt = targetmapsides[i]

			if not tgt continue end
			local base = mapsides[i]

			if tgt[1]
				s.toptexture = tgt[1]
			end
			if tgt[2]
				s.midtexture = tgt[2]
			end
			if tgt[3]
				s.bottomtexture = tgt[3]
			end
		end
	end
	
	for p in players.iterate do
		if p.spiral_funny then
			p.spiral_funny = $ - 1
		end
	end
end)
