local player = ...
assert(player, "Which player is this for?!")
local xMod = player == PLAYER_1 and 0 or -14
local chart = GAMESTATE:GetCurrentSteps(player)

local isEx = ShouldUseEXGraphics()
local isTraining = getenv("LifeBarType" .. ToEnumShortString(player)) == "training"
local fileAppend = isEx and "ex_" or ""

local t = Def.ActorFrame{
	-- Main quad
	-- Def.Quad{
		-- OnCommand=function(self)
			-- self:y(-7):zoomto(280,60):diffuse(LocalBlueColor(0.75)):skewx(player == PLAYER_1 and -0.1 or 0.1)
		-- end
	-- },
	
	-- Darker quad under the score
	-- Def.Quad{
		-- OnCommand=function(self)
			-- self:xy(125,-24):horizalign(right):zoomto(140,20):diffuse(LocalBlueColor(0.5))
		-- end
	-- },
	CurrentStepsP1ChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	CurrentStepsP2ChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	CurrentTrailP1ChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	CurrentTrailP2ChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	CurrentCourseChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	CurrentSongChangedMessageCommand=function(self) self:playcommand("CheckRefresh") end,
	
	CheckRefreshCommand=function(self)
		local newChart = GAMESTATE:GetCurrentSteps(player)
		if newChart and newChart ~= chart then
			chart = newChart
			self:playcommand("Refresh")
		end
	end,
	
	-- Backing behind everything else.
	LoadActor(fileAppend .. "lifescoreback") .. {
		OnCommand=function(self)
			self:y(-7):zoomy(player == PLAYER_1 and 1 or -1)
			--SM(GAMESTATE:GetPlayerState(player):GetPlayerOptions("ModsLevel_Current"):FailSetting())
		end
	},
	
	-- Difficulty indicator, PIU Pro style I guess
	LoadActor("difficultyLight") .. {
		OnCommand=function(self)
			local THISxMod = player == PLAYER_1 and xMod or xMod-3
			self:xy(154+THISxMod,-25):horizalign(right)
			if chart then self:playcommand("Refresh") end
		end,
		RefreshCommand=function(self)
			self:diffuse(CustomDifficultyToColor(chart:GetDifficulty(), chart:GetChartName())):zoomy(player == PLAYER_1 and 1 or -1)
		end
	},
	Def.BitmapText{
		Font = "Common Normal",
		OnCommand=function(self)
			local THISxMod = player == PLAYER_1 and xMod or xMod-3
			self:xy(132+THISxMod,-26):zoom(0.5):strokecolor(Color.Black):maxwidth(46)
			if chart then self:playcommand("Refresh") end
		end,
		RefreshCommand=function(self)
			self:settext(chart:GetMeter())
		end
	},
	
	-- Big ol' frame!
	LoadActor(fileAppend .. "life_" .. ToEnumShortString(player)) .. {
		OnCommand=function(self)
			self:x(player == PLAYER_1 and -5 or 5):y(-7)
		end
	},

	-- Quad "containing" the life bar
	Def.Quad{
		OnCommand=function(self)
			self:x(isTraining and 26 or -26):zoomto(isTraining and 170 or 200,18):diffuse(isEx and Color.Stealth or Color.Black)
		end
	},
	
	LoadActor(fileAppend .. "lifeIcon_" .. (getenv("LifeBarType" .. ToEnumShortString(player)) or "fallback")) .. {
		OnCommand=function(self)
			self:xy(player == PLAYER_1 and -138 or 138,10):zoomx(player == PLAYER_1 and 1 or -1)
		end
	},
	
	-- Life percentage display.
	Def.BitmapText{
		Font = "Common Normal",
		OnCommand=function(self)
			self:xy(125,-1):horizalign(right):zoom(0.6):diffuse(isEx and LocalGoldColor(1) or Color.Black)
			self:visible(not isTraining)
			self:playcommand("Set")
		end,
		LifeChangedMessageCommand=function(self,param)
			if param.Player == player then
				self:playcommand("Set")
			end
		end,
		SetCommand=function(self)
			-- failsafe; actually to prevent an error right at the start of the screen, lol
			if not SCREENMAN:GetTopScreen() or SCREENMAN:GetTopScreen():GetName() == "ScreenStageInformation" then return end
			
			local curLife = SCREENMAN:GetTopScreen():GetLifeMeter(player):GetLife()
			self:settext(tostring(math.floor(curLife*100)) .. "%")
		end
	},
	
	-- "SCORE" header
	Def.BitmapText{
		Font = "Common Large",
		Text = "SCORE",
		OnCommand=function(self)
			self:xy(-126+xMod,isTraining and 5 or -13):horizalign(left):vertalign(bottom):zoom(0.8):rotationz(-5):strokecolor(LocalBlueColor(0)):diffuse(isEx and LocalBlueColor(1) or Color.White)
		end
	},
	-- Lua replacement for the score display. Nobody will EVER KNOW
	Def.RollingNumbers {
		Name = "ScoreNumbers",
		Font = "Common Value",
		InitCommand=cmd(Load,"RollingNumbers"),
		OnCommand=function(self)
			self:horizalign(right):vertalign(bottom):xy(106+xMod,isTraining and 7 or -18):zoom(0.6):
				diffuse(isEx and LocalBlueColor(1) or Color.White):strokecolor(isTraining and Color.Black or Color.Stealth)
			self:playcommand("Set")
		end,
		-- check: might miss a few things?
		JudgmentMessageCommand=function(self,param)
			if param.Player == player then
				self:playcommand("Set")
			end
		end,
		-- can't be too safe
		ScoreChangedMessageCommand=function(self,param)
			if param.PlayerNumber == player then
				self:playcommand("Set")
			end
		end,
		SetCommand=function(self)
			local playerStats = STATSMAN:GetCurStageStats():GetPlayerStageStats(player)
			self:targetnumber(playerStats:GetPercentDancePoints()*100000)
		end
	},
}

-- #############################
-- Let's make a custom life bar thingy.
--190w 20h
local barCount = 39
-- Calculate how much life a single pill will measure.
local lifeSegment = 1 / barCount

local barHold = Def.ActorFrame{
	InitCommand=function(self)
		self:x(-127.5)
	end,
	OnCommand=function(self) self:playcommand("Set") self:visible(not isTraining) end,
	LifeChangedMessageCommand=function(self, param)
		if param.Player == player then
			self:playcommand("Set")
		end
	end,
	SetCommand=function(self)
		-- failsafe; actually to prevent an error right at the start of the screen, lol
		if not SCREENMAN:GetTopScreen() or SCREENMAN:GetTopScreen():GetName() == "ScreenStageInformation" then return end
		
		local lifeMeter = SCREENMAN:GetTopScreen():GetLifeMeter(player)
		local curLife = lifeMeter:GetLife()
		--local curLife = STATSMAN:GetCurStageStats():GetPlayerStageStats(player):GetCurrentLife()
		local segmentFocus = math.floor(curLife / lifeSegment) 
		self:GetChild("LifeMarker"):x(5*segmentFocus)
		
		for i=1, barCount do
			local theBar = self:GetChild(tostring(i))
			theBar:finishtweening()
			
			local pMark = GAMESTATE:GetPlayerState(player):GetPlayerOptions("ModsLevel_Current"):Passmark()
			local lifeType = getenv("LifeBarType" .. ToEnumShortString(player))
			--SM(pMark)
			
			if segmentFocus >= i then
				local theColor = pMark > 0 and ((lifeSegment*i) <= pMark and NeonColor.Blue or NeonColor.Green) or (lifeMeter:IsFailing() and GameColor.HealthState.UnderPassmark or lifeMeter:IsHot() and GameColor.HealthState.Hot or lifeMeter:IsInDanger() and GameColor.HealthState.Danger or GameColor.HealthState.Alive)
				
				theBar:decelerate(0.1):diffuse(theColor)
				if lifeType == "pressure" then
					theBar:diffuseshift():effectcolor1(NeonColor.Gold):effectcolor2(NeonColor.Red):effectperiod(2):effectclock("bgm"):effectoffset(i/barCount)
				end
			else
				local theColor = pMark > 0 and ((lifeSegment*i) <= pMark and ColorBlend(NeonColor.Blue, Color.Outline) or ColorBlend(NeonColor.Green, Color.Outline)) or LocalGoldColor(0.1)
				theBar:decelerate(0.1):diffuse(theColor):stopeffect()
			end
			
			if lifeType ~= "pressure" then
				if lifeMeter:IsHot() then
					theBar:rainbow():effectoffset(i/20)
				else
					theBar:stopeffect()
				end
			end
		end
	end
}

for i=1, barCount do
	barHold[#barHold+1] = LoadActor("blip") .. {
		Name = tostring(i),
		InitCommand=function(self)
			self:x(5*i):halign(0.25):diffuse(LocalGoldColor(0.25))
		end
	}
end

-- Lil' indicator thingy.
barHold[#barHold+1] = LoadActor("blip") .. {
	Name = "LifeMarker",
	InitCommand=function(self)
		self:halign(0.25):diffuse(Color.White):x(5):zoomy(1.1)
	end
}

t[#t+1] = barHold

-- Low life indicator (15%, which on most life difficulties would be one or two misses away from 0%... oops!)
t[#t+1] = Def.BitmapText{
	Font = "Common Small",
	Text = "DANGER!",
	InitCommand=function(self)
		self:horizalign(right):x(72):zoom(0.45):strokecolor(Color.Black):diffuse(NeonColor.Red):glowblink():
			effectcolor1(Color.Stealth):effectcolor2(Color.White):effecttiming(0.1,0.1,0.1,0.1,0.6):effectclock("bgm")
	end,
	OnCommand=function(self) self:playcommand("Set") end,
	LifeChangedMessageCommand=function(self, param)
		if param.Player == player then
			self:playcommand("Set")
		end
	end,
	SetCommand=function(self)
		-- failsafe; actually to prevent an error right at the start of the screen, lol
		if not SCREENMAN:GetTopScreen() or SCREENMAN:GetTopScreen():GetName() == "ScreenStageInformation" then return end
		
		local failType = GAMESTATE:GetPlayerState(player):GetPlayerOptions("ModsLevel_Current"):FailSetting()
		local lifeMeter = SCREENMAN:GetTopScreen():GetLifeMeter(player)
		
		self:visible(failType ~= "FailType_Off" and ((string.find(failType, "Immediate") and lifeMeter:IsInDanger()) or lifeMeter:GetLife() == 0))
	end
}
--]]

return t
