-- Monochrome Rift Lua, nothing special

-- lookup tables for textures
local textures = {}
local floors = {}

-- where we save the base textures for everything so we know what we're doing...

local mapsides = {}
local mapfloors = {}

-- here we save the target textures we want

local targetmapsides = {}
local targetmapfloors = {}


-- last color used:
local lastcolor = 0
local changetimer = 0


-- typed the tables by hand because it's easier to comprehend AND debug, but could easily optimize this

-- do flats first, they're fast n easy~
floors["MR_FLR1"] = {"MR_FLR0", "MR_FLR2", "MR_FLR3", "MR_FLR4", "MR_FLR5", "MR_FLR6", "MR_FLR7"}
floors["MR_OFR1"] = {"MR_OFR0", "MR_OFR2", "MR_OFR3", "MR_OFR4", "MR_OFR5", "MR_OFR6", "MR_OFR7"}

-- for sides: (arrowed barriers)
textures["MR_SIDE1"] = {"MR_SIDE0", "MR_SIDE3", "MR_SIDE5", "MR_SIDE7", "MR_SIDE9", "MR_SIDEB", "MR_SIDED"}
textures["MR_SIDE2"] = {"MR_SIDE0", "MR_SIDE4", "MR_SIDE6", "MR_SIDE8", "MR_SIDEA", "MR_SIDEC", "MR_SIDEE"}

-- buildings:
textures["MR_BUD1"] = {"MR_BUD0", "MR_BUD2", "MR_BUD3", "MR_BUD4", "MR_BUD5", "MR_BUD6", "MR_BUD7"}
textures["MR_BUD21"] = {"MR_BUD20", "MR_BUD22", "MR_BUD23", "MR_BUD24", "MR_BUD25", "MR_BUD26", "MR_BUD27"}

-- arrows: (this is quite long, there's like 8 textures :oh:)
textures["MR_ARR11"] = {"MR_ARR01", "MR_ARR31", "MR_ARR51", "MR_ARR71", "MR_ARR91", "MR_ARRB1", "MR_ARRD1"}
textures["MR_ARR12"] = {"MR_ARR01", "MR_ARR32", "MR_ARR52", "MR_ARR72", "MR_ARR92", "MR_ARRB2", "MR_ARRD2"}
textures["MR_ARR13"] = {"MR_ARR01", "MR_ARR33", "MR_ARR53", "MR_ARR73", "MR_ARR93", "MR_ARRB3", "MR_ARRD3"}
textures["MR_ARR14"] = {"MR_ARR01", "MR_ARR34", "MR_ARR54", "MR_ARR74", "MR_ARR94", "MR_ARRB4", "MR_ARRD4"}

textures["MR_ARR21"] = {"MR_ARR02", "MR_ARR41", "MR_ARR61", "MR_ARR81", "MR_ARRA1", "MR_ARRC1", "MR_ARRE1"}
textures["MR_ARR22"] = {"MR_ARR02", "MR_ARR42", "MR_ARR62", "MR_ARR82", "MR_ARRA2", "MR_ARRC2", "MR_ARRE2"}
textures["MR_ARR23"] = {"MR_ARR02", "MR_ARR43", "MR_ARR63", "MR_ARR83", "MR_ARRA3", "MR_ARRC3", "MR_ARRE3"}
textures["MR_ARR24"] = {"MR_ARR02", "MR_ARR44", "MR_ARR64", "MR_ARR84", "MR_ARRA4", "MR_ARRC4", "MR_ARRE4"}

local texturebynum = {}

-- we CANNOT do this on script load for SOME REASON
local function init_texturebynum()

	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 MR_generatetables()
	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].monochrome

		init_texturebynum()
		if not #texturebynum
			MR_generatetables()
		end
	end

	changetimer = 0
	lastcolor = 0

end)


local function MR_randomtexture()

	if changetimer return end	-- lol DON'T

	-- set random target textures for everything!
	local newtarget = lastcolor
	while newtarget == lastcolor
		newtarget = N_RandomRange(2, 7)
	end

	-- 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

-- HAHAHAHAHAHAHAHAHHA
local consoleplayer
addHook("PlayerCmd", function(p)
	consoleplayer = p
end)

local v2 = k_rings

addHook("ThinkFrame", do

	if not mapheaderinfo[gamemap].monochrome return end

	if not consoleplayer or not consoleplayer.valid return end
	if v2

	else
		if consoleplayer.kartstuff[k_lapanimation] == 79
			MR_randomtexture()
		end
	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 flicker
				if tgt[1]
					s.floorpic = tgt[1]
				end
				if tgt[2]
					s.ceilingpic = tgt[2]
				end

			else
				local texture = base[1]
				if floors[texture]
					s.floorpic = floors[texture][1]
				end

				texture = base[2]
				if floors[texture]
					s.ceilingpic = floors[texture][1]
				end
			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 flicker
				if tgt[1]
					s.toptexture = tgt[1]
				end
				if tgt[2]
					s.midtexture = tgt[2]
				end
				if tgt[3]
					s.bottomtexture = tgt[3]
				end

			else

				local texture = base[1]

				if texturebynum[texture]
					s.toptexture = texturebynum[texture][1]
				end

				texture = base[2]
				if texturebynum[texture]
					s.midtexture = texturebynum[texture][1]
				end

				texture = base[3]
				if texturebynum[texture]
					s.bottomtexture = texturebynum[texture][1]
				end

			end
		end
	end
end)
