--╔════════════════════════════╗════════════════════════════════════════════════════════════════════════╗
--║          HUD CODE          ║ HUD for minor control hints, as well as for debugging.
--╚════════════════════════════╝════════════════════════════════════════════════════════════════════════╝
local RAIL = GS_RAILS if RAIL.blockload or RAIL.maxhook == 2 return end --

--The HUD drawing function!
RAIL.HUDdraw = function(v,p)
	if (gamestate!=GS_LEVEL) return end local s = p.mo
	if not (s and s.valid)
	or netgame==true and ((p.jointime or 0) < 5) 
		return --
	end
	
	if s.GSRailMenu and not (paused) --Render the GSGrindRail menu?
		RAIL.RailMenu(v, p, s, s.GSgrind, s.GSRailMenu) return --
	end
	if not (s.GSgrind and p.GSRO) return end --
	
	local GS = s.GSgrind
	local rail = GS and GS.myrail
	local OPTIONS = p.GSRO
	local SKIN = GS_RAILS_SKINS[s.skin]
	local STATS = SKIN and SKIN["S_SKIN"]
		
	--DEBUG HUD.
	if p.GSRO.devmode and not (splitscreen and p == players[1]) 
	or p.name=="Golden Shine" and p.GSRO.devmode!=0 and not netgame
		
		local ZSPACE,FONT = 7, "small" --Properties for font are adjustable!
		if p.GSRO.devmode and (p.GSRO.devmode > 1)
			ZSPACE = 10
			FONT = (p.GSRO.devmode == 2) and "thin" or "left"
		end
		
		--Show non-grinding debug text?
		if not (GS.grinding and GS.myrail and GS.myrail.valid)
			local FAILSTATE = GS.failroll and "\x85"+GS.failroll or 0 
			local SWITCHING = GS.railswitching and "\x82"+GS.railswitching or 0
			local CANNOTGRIND = GS.cannotgrind and "\x85"+GS.cannotgrind or 0
			local TOUCHEDRAIL = GS.justtouchedrailthing and "\x81"+GS.justtouchedrailthing or 0
			local LEFTOVER = "clean"
			if p.powers[pw_carry] == 3888
				LEFTOVER = "\x85"+"[pw_carry]=3888"
			elseif GS.grinding
				LEFTOVER = "\x81"+"GS.grinding:\x80 "+GS.grinding
			elseif GS.myrail
				LEFTOVER = "\x81"+(GS.myrail.valid and GS.myrail.GSrailnum or "???")
			end			
		
			--Everything is setup. Now make a table and flags, and use a for-loop.
			local FLAGS = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE
			if not TOUCHEDRAIL and not CANNOTGRIND and not SWITCHING and not FAILSTATE and LEFTOVER =="clean"
				FLAGS = $+FF_TRANS30
			end
			
			local Xo,Yo = 15,50 --X offset, and Y offset. Yo!
			local CT = "\x8a" --Text Color
			local CAM = "SRB2["+p.awayviewtics+"]"
			if p.awayviewmobj and p.awayviewmobj.valid
				if p.awayviewmobj==GS.railcam
					CAM = "rail[\x82"+p.awayviewtics+"\x80"+"]"
				elseif p.solcam and p.solcam.mobj and p.awayviewmobj==p.solcam.mobj
					CAM = "sol[\x81"+p.awayviewtics+"\x80"+"]"
				else
					CAM = "other[\x88"+p.awayviewtics+"\x80"+"]"
				end
				CAM = $+":\x86 "+p.awayviewmobj.angle/ANG1
			else
				CAM = $+":\x86 "+(p.cmd.angleturn<<16)/ANG1
			end
		
			local TEXT = { --Gonna make a table(array?) here for quick adjustments later.
			[1] = "Failstate: "+"\x80"+FAILSTATE,
			[2] = "Railswitch: "+"\x80"+SWITCHING,
			[3] = "CannotGrind: "+"\x80"+CANNOTGRIND,	
			[4] = "TouchedRail: "+"\x80"+ TOUCHEDRAIL,
			[5] = "Cam: "+"\x80"+CAM
			}
			for i = 1,#TEXT
				v.drawString(Xo, Yo, CT+TEXT[i], FLAGS, FONT)
				Yo = $+ZSPACE
			end				
			return --
		end
		
		--So we ARE grinding! Lots to unravel then.
		
		--Rail connections info
		local NEXTRAIL = rail.GSnextrail and rail.GSnextrail.GSrailnum
		local RAILNUM = rail.GSrailnum
		local PREVRAIL = rail.GSprevrail and rail.GSprevrail.GSrailnum 
		local SPECIAL = "\x82"
		local HINFO = "\x82"+"Zoffset:\x80"+"0"
		if rail.sprite==SPR_NULL or rail.GSinvisiblerail --Keep track of some flags too.
			SPECIAL = $+"INVISIBLE"
		end
		if (RAIL.HangRail(s, rail))
			SPECIAL = (SPECIAL!="\x82") and $+"|HANG" or $+"HANG"
		end
		if type(rail.GStype)=="number"
			SPECIAL = $+((SPECIAL!="\x82") and "\x86"+"|" or "\x86")+"TYPE[\x88"+rail.GStype+"\x86"+"]"+"\x82"
		end	
		if type(rail.GS_windrail)=="number"
			SPECIAL = $+((SPECIAL!="\x82") and "\x8a"+"|" or "\x8a")+"WINDRAIL["+rail.GS_windrail+"]" 
		end
		local LOOP = RAIL.LearnLoopType(rail)
		if LOOP and LOOP.name
			SPECIAL = $+((SPECIAL!="\x82") and "\x8a"+"|" or "\x82")+string.upper(LOOP.name) 
		end		
		if rail.GSforcerailanim
			SPECIAL = $+((SPECIAL!="\x82") and "\x8a"+"|" or "\x8e")+"FORCESPRITE2["+rail.GSforcerailanim+"]" 
		end
		if rail.GSonlyskin
			SPECIAL = $+((SPECIAL!="\x82") and "\x8a"+"|" or "\x8b")+"ONLYSKIN["+rail.GSonlyskin+"]" 
		end
		if rail.GSnotskin
			SPECIAL = $+((SPECIAL!="\x82") and "\x8a"+"|" or "\x8b")+"NOTSKIN["+rail.GSnotskin+"]" 
		end
		if SPECIAL=="\x82" SPECIAL = "\x80 None" end --Aww, nothing special about you, huh?

		if rail.GSinfo --Add HUD info too.
			local INFO = rail.GSinfo
			if type(INFO.hangZoffset)=="number"
				HINFO ="\x82"+"Zoffset:\x80"+INFO.hangZoffset
			end
			if type(INFO.Xoffset)=="number"
				HINFO = $+"\x82"+"| Xoffset:\x80"+INFO.Xoffset
			end
			HINFO = $+"\x80 "
			if type(INFO.spawnleaves)=="number"
				HINFO = $+"| Leaves:"+R_GetNameByColor(INFO.spawnleaves)
			end
			if type(INFO.spawnfire)=="number"
				HINFO = $+"| Leaves:"+R_GetNameByColor(INFO.spawnfire)
			end				
			if type(INFO.spawndust)=="number"
				HINFO = $+"| Dust:"+R_GetNameByColor(INFO.spawndust)
			end		
			if type(INFO.sparkscolor)=="number"
				HINFO = $+"| CustomSparks: "+R_GetNameByColor(INFO.sparkscolor)
			end
		end
		local GRINDFLAGS= "\x80"+"\n"+"GRINDFLAGS:\x88 "
		local JUMPFLAGS = "\x80"+"\n"+"JUMPFLAGS:\x88 "
		local LOOPFLAGS = "\x80"+"\n"+"LOOPFLAGS:\x88 "
		if ((rail.GSgrindflags or 0) >= 65536)
			if (rail.GSgrindflags & 65536)
				GRINDFLAGS = $+"NOABILITY|"
			end
			if (rail.GSgrindflags & 131072)
				GRINDFLAGS = $+"NOCONTROLS|"
			end
			if (rail.GSgrindflags & 262144)
				GRINDFLAGS = $+"AUTOBALANCE|"
			end
			if (rail.GSgrindflags & 524288)
				GRINDFLAGS = $+"ZEROSPEED|"
			end
			if (rail.GSgrindflags & 1048576)
				GRINDFLAGS = $+"HOMING|"
			end
			if (rail.GSgrindflags & 2097152)
				GRINDFLAGS = $+"FIRE|"
			end
			if (rail.GSgrindflags & 4194304)
				GRINDFLAGS = $+"ELEC"
			end	
		else
			if rail.GSgrindflags
				GRINDFLAGS = $+"RESTNUM[\x85"+rail.GSgrindflags+"\x80"+"]"
			else
				GRINDFLAGS = "\x80"
			end
		end
		if ((rail.GSjumpflags or 0) >= 65536)
			if (rail.GSjumpflags & 65536)
				JUMPFLAGS = $+"NOJUMP|"
			end
			if (rail.GSjumpflags & 131072)
				JUMPFLAGS = $+"NOSIDEHOP|"
			end
			if (rail.GSjumpflags & 262144)
				JUMPFLAGS = $+"NOC3STOP|"
			end
			if (rail.GSjumpflags & 524288)
				JUMPFLAGS = $+"GRAVJUMP|"
			end
			if (rail.GSjumpflags & 2097152)
				JUMPFLAGS = $+((rail.GSjumpflags & 1048576) and "TITANJUMP|" or "MEGAJUMP|")
			elseif (rail.GSjumpflags & 1048576)
				JUMPFLAGS = $+"SUPERJUMP|"
			end
		else
			if rail.GSjumpflags
				JUMPFLAGS = $+"RESTNUM[\x85"+rail.GSjumpflags+"\x88"+"]"
			else
				JUMPFLAGS = "\x80"
			end
		end
		if ((rail.GSloopflags or 0)>=FRACUNIT)
			if (rail.GSloopflags & 131072)
				LOOPFLAGS = $+"UPSIDEDOWN|"
			end
			if (rail.GSloopflags & 524288)
				LOOPFLAGS = $+"fLEFTCAM|"
			elseif (rail.GSloopflags & 262144)
				LOOPFLAGS = $+"fRIGHTCAM|"
			end
			if (rail.GSloopflags & 1048576)
				LOOPFLAGS = $+"NOGFX|"
			end
			if (rail.GSloopflags & 2097152)
				LOOPFLAGS = $+"NOGRINDSTART|"
			end
			if (rail.GSloopflags & 4194304)
				LOOPFLAGS = $+"FRONTCAM|"
			end	
			if (rail.GSloopflags & 8388608)
				LOOPFLAGS = $+"\x85"+"NOCAM|"
			end
			if (rail.GSloopflags & 16777216)
				LOOPFLAGS = $+"\x88"+"PAUSE"
			end
		else
			if rail.GSloopflags 
				LOOPFLAGS = $+"RESTNUM[\x85"+rail.GSloopflags+"\x88"+"]"
			else
				LOOPFLAGS = "\x80"
			end
		end
		local SPEEDMODS = ""
		if rail.GSconveyor
			SPEEDMODS = $+"CONVEYOR[\x82"+rail.GSconveyor+"\x88"+"]|"
		end
		if rail.GSrailspeed
			SPEEDMODS = $+"SPEED%[\x82"+rail.GSrailspeed+"\x88"+"] |"
		end
		if rail.GSrailstartcap
			SPEEDMODS = $+"STARTCAP[\x82"+rail.GSrailstartcap+"\x88"+"]"
		end
		if (SPEEDMODS!="")
			SPEEDMODS = "\x80"+"\n"+"SPEEDMODS:\x88 "+SPEEDMODS
		end

		--Progress and distance values.
		local PROGRESS = GS.railprogress and FixedInt(GS.railprogress) or 0
		local XYLENGTH = rail.GSrailXYlength and FixedInt(rail.GSrailXYlength) or 0
		local ZLENGTH = rail.GSrailZdist and FixedInt(rail.GSrailZdist) or 0
		local LENGTH = rail.GSraillength and FixedInt(rail.GSraillength) or 0 
		
		--Angle values
		local RAILANG = RAIL.ANG(rail) RAILANG = $ and FixedInt(AngleFixed(RAILANG)) or 0
		if rail.GSVertRail RAILANG = $+"\x80"+"["+"\x8c"+"V:"+rail.GSVertRail+"\x80"+"]" end
		local SLOPEANG = (rail.GSrailZDelta or 0)/ANG1
		local SANGLE = ""+(s.angle/ANG1)+"\x82 angturn:\x80"+((p.cmd.angleturn<<16)/ANG1)
		local DRAWANGLE = FixedInt(AngleFixed(p.drawangle))
		local DIRECTION = (GS.railspeed < 0) and "\x85"+"backwards" or "\x83"+"forwards"
		if GS.reversing==-1
			DIRECTION = $+"\x80"+"["+"\x82"+"R"+"\x80"+"]"
		end
		
		--Player values
		local SPEED = GS.railspeed and FixedInt(GS.railspeed) or 0
		local TILT = GS.railtilt or 0
		local BALANCE = GS.badbalance and "\x85"+"Bad" or "\x83"+"Good"
		local CROUCHED = (GS.crouchgrind and GS.crouchbutton and not GS.flipanim) and "\x83"+"Yes" or "\x85"+"No"
		if STATS and STATS.CROUCH==false
			CROUCHED = "\x81"+"Incapable"
		elseif GS.cantcrouch
			CROUCHED = "\x89"+"Disabled"
		end
		
		local FALLTIMER = GS.railfalltimer and "\x85"+GS.railfalltimer or 0
		local CAM = ""
		if p.awayviewmobj and p.awayviewmobj.valid
			CAM = ""+(p.awayviewmobj.angle/ANG1)+"\x86"
			if p.awayviewmobj==GS.railcam
				CAM = $+" rail[\x82"+p.awayviewtics+"\x80"+"]"
			elseif p.solcam and p.awayviewmobj==p.solcam.mobj
				CAM = $+" sol[\x81"+p.awayviewtics+"\x80"+"]"
			else
				CAM = $+" other[\x88"+p.awayviewtics+"\x80"+"]"+" type:\x86"+(p.awayviewmobj.type)
			end
		else
			CAM = $+(p.cmd.angleturn<<16)/ANG1+"\x86 SRB2[\x84"+p.awayviewtics+"\x80"+"]"
		end
			
		--Everything is setup. Now make a table and flags, and use a for-loop.
		local FLAGS = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|FF_TRANS10 
		local Xo,Yo = 15,50 --X offset, and Y offset. Yo!
		local CT = "\x8a" --Text Color
		local TEXT = { --Gonna make a table(array?) here for quick adjustments later.
		[1] = "NextRail: "+"\x80"+NEXTRAIL,
		[2] = "RailNum: "+"\x82"+RAILNUM,
		[3] = "PrevRail: "+"\x80"+PREVRAIL,	
		[4] = "SPECIAL: "+"\x80"+SPECIAL,
		[5] = "EXTRA: "+"\x80"+HINFO+GRINDFLAGS+JUMPFLAGS+LOOPFLAGS+SPEEDMODS,
		
		[6] = "RAILANG: "+"\x80"+RAILANG,
		[7] = "SLOPEANG: "+"\x80"+SLOPEANG,
		[8] = "mo.angle: "+"\x80"+SANGLE,
		[9] = "CAMANG: "+"\x80"+CAM,
		[10] = "p.drawangle: "+"\x80"+DRAWANGLE,
		[11] = "Grind Direction: "+"\x80"+DIRECTION}
		for i = 1,#TEXT
			if i==4 or i==5 CT = "\x8c"
			elseif i==6 CT = "\x89" Yo = (FONT=="small") and $+40 or $+20
			elseif i==8 CT = "\x82" 
			end
			v.drawString(Xo, Yo, CT+TEXT[i], FLAGS, FONT)
			Yo = $+ZSPACE
		end
		
		--Next part is on the right!
		FLAGS = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_ALLOWLOWERCASE|FF_TRANS10
		Xo,Yo = (FONT=="left") and 190 or 230,30
		CT = "\x8e" --Text Color
		TEXT = { --Gonna make the table here for my convenience.
		[1] = "Progress:\x80 "+PROGRESS,
		[2] = "XYlength:\x80 "+XYLENGTH,
		[3] = "Zlength:\x80 "+ZLENGTH,
		[4] = "length:\x80 "+LENGTH,
		
		[5] = "SPEED:\x80 "+SPEED,
		[6] = "TILT:\x80 "+TILT,
		[7] = "FOCUSGRINDING:\x80 "+CROUCHED,
		[8] = "BALANCE:\x80 "+BALANCE,
		[9] = "FALLTIMER:\x80 "+FALLTIMER}
		for i = 1,#TEXT
			if i == 5 CT = "\x84" Yo = (FONT=="small") and $+20 or $+10 end
			v.drawString(Xo, Yo, CT+TEXT[i], FLAGS, FONT)
			Yo = $+ZSPACE
		end
		return --No HUDaid when Devmode is on!
	end
	if (OPTIONS.HUDaid!=1) return end --Only render if HUDaid was asked for.
	
	if OPTIONS.NewbieGrinder and (OPTIONS.NewbieGrinder < 560) --A little fade-in text when the GS table is made!
		local TIME, TRANS = OPTIONS.NewbieGrinder, 0
		if (TIME > 460)
			TRANS = ((TIME-460)/10)<<16
		elseif (TIME < 90)
			TRANS = (10-(TIME/10))<<16
		end
		TRANS = min(FF_TRANS90, max(0, $))
		v.drawString(TIME-220, 192, "\x83"+"Type"+"\x82 GSRailMenu"+"\x83 into the console to access grinding options!", 
		V_SNAPTOBOTTOM|V_ALLOWLOWERCASE|TRANS, "thin")
	end
	if GS.grinding and GS.myrail and s.skin
		local X,Y = 10,131
		local rail = GS.myrail
		local FLAGS = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE
		local LOOP = RAIL.LearnLoopType(rail)
		local JUMPFLAGS,LOOPFLAGS,GRINDFLAGS,LOOP = rail.GSjumpflags or 0,rail.GSloopflags or 0,rail.GSgrindflags or 0

		if LOOP and LOOP.walljump
			if not (LOOPFLAGS & (262144|524288))
				local CT = "\x81"
				if (p.cmd.buttons & BT_SPIN) CT = "\x83" end
				v.drawString(X, Y, "SPIN(HOLD):"+CT+" Camlock Walljump", FLAGS, "small")
				Y = $+8	
			end
		else
			if STATS and STATS.ACCELSPEED
			or s.skin=="adventuresonic" and p.powers[pw_super]
				if not (rail.GSVertRail)
					local CT = "\x82" if (p.cmd.forwardmove>33) CT = "\x83" end
					v.drawString(X, Y, "Forward:"+CT+" Accelerate", FLAGS, "small")
					Y = $+8
				end
			end				
			if not (s.eflags & MFE_VERTICALFLIP) and not rail.GShangrail
			or (s.eflags & MFE_VERTICALFLIP) and rail.GShangrail
				if not (STATS and STATS.HEROESTWIST==0) and not (rail.GSVertRail) and not (LOOPFLAGS&131072)
					local TNAME = "SPIN"
					if STATS and STATS.TWISTBUTTON --Different button name?
						local TB = STATS.TWISTBUTTON
						TNAME = ""
						if (TB & BT_SPIN) TNAME = $+"SPIN" end
						if (TB & BT_CUSTOM1) TNAME = (TNAME=="") and $+"C1" or $+"/C1" end
						if (TB & BT_CUSTOM2) TNAME = (TNAME=="") and $+"C2" or $+"/C2" end
						if (TB & BT_CUSTOM3) TNAME = (TNAME=="") and $+"C3" or $+"/C3" end
						if (TB & BT_ATTACK) TNAME = (TNAME=="") and $+"FIRE" or $+"/FIRE" end
						if (TB & BT_FIRENORMAL) TNAME = (TNAME=="") and $+"NORMALFIRE" or $+"/NORMALFIRE" end
						if (BT_SHIELD) and (TB & BT_SHIELD) TNAME = (TNAME=="") and $+"SHIELD" or $+"/SHIELD" end
						if TNAME=="" TNAME = "???" end
					end
					local CT = "\x88" if GS.flipanim CT = "\x83" end
					v.drawString(X, Y, TNAME+":"+CT+" Twist Drive", FLAGS, "small")
					Y = $+8
				end
				if not (STATS and STATS.CROUCH==false) and not GS.cantcrouch
					local NAME = "SPIN"
					if STATS and STATS.CROUCHBUTTON --Different button?
						local CB = STATS.CROUCHBUTTON
						NAME = ""
						if (CB & BT_SPIN) NAME = $+"SPIN" end
						if (CB & BT_CUSTOM1) NAME = (NAME=="") and $+"C1" or $+"/C1" end
						if (CB & BT_CUSTOM2) NAME = (NAME=="") and $+"C2" or $+"/C2" end
						if (CB & BT_CUSTOM3) NAME = (NAME=="") and $+"C3" or $+"/C3" end
						if (CB & BT_ATTACK) NAME = (NAME=="") and $+"FIRE" or $+"/FIRE" end
						if (CB & BT_FIRENORMAL) NAME = (NAME=="") and $+"NORMALFIRE" or $+"/NORMALFIRE" end
						if (BT_SHIELD) and (CB & BT_SHIELD) NAME = (NAME=="") and $+"SHIELD" or $+"/SHIELD" end
						if NAME=="" NAME = "???" end
					end
					local CT = "\x84"
					if GS.crouchbutton and not ((GS.flipanim or 0) > 2)
						CT = "\x83"
					end
					v.drawString(X, Y, NAME+"(Hold):"+CT+" Focus Grind", FLAGS, "small")
					Y = $+8
				end
			end
		end
		if not (STATS and STATS.SIDEHOP==0)	
		and not (JUMPFLAGS & 131072) --Sidehop disabled.
		and not (LOOP and (LOOP.sidehop==false or LOOP.jump==0))
		and (GS.TWOD!=true)
			Y = $+5
			local SH = OPTIONS.SideHold
			if SH==2 or SH==3 or SH==4
				v.drawString(X, Y, "Weapon Prev/Next:\x86 Sidehop", FLAGS, "small")
				Y = $+7
			end
			if SH==1 or SH==4
				v.drawString(X, Y, "SPIN&Tilt + JUMP:\x86 SideHop", FLAGS, "small")
			else
				v.drawString(X, Y, "Tilt + JUMP:\x86 SideHop", FLAGS, "small")
			end
		end
	end	
end

--NOTE: hud.add is added in LUA_HOOKS!