-- UH OH THIS IS SOME SECRET ASS CODE AND SOME HARDCORE ASS SHIT
-- well as hardcore as I can get without my name being one of the following:
-- Chris Danford, Glenn Maynard, vdl

local Player = ...
assert( Player );

local prevLife = THEME:GetMetric("LifeMeterBar","InitialValue");
--local bIsDashHopes2 = GAMESTATE:GetCurrentSong():GetDisplayMainTitle() == "Dash Hopes II" and true or false;

local meter = Def.ActorFrame{
	Condition=GAMESTATE:IsSideJoined(Player) or GAMESTATE:IsDemonstration();
	
	-- // start meter background //
	-- danger (and dead since you don't see it anyways)
	LoadActor("_meterbg danger")..{
		InitCommand=cmd(diffusealpha,0);
		
		HealthStateChangedMessageCommand=function(self,params)
			-- first, check to see if it's this one that changed,
			-- if not we can ignore this bullshit
			if(params.PlayerNumber == Player) then
				-- ok it was for us, time to see what state it is
				if(params.HealthState == 'HealthState_Danger' or params.HealthState == 'HealthState_Dead') then
					self:linear(0.2);
					self:diffusealpha(1);
					--self:diffuseglow();
				-- ok it wasn't danger/dead
				else
					self:linear(0.2);
					self:diffusealpha(0);
					self:stopeffect();
				end;
			-- ok it wasn't for us, exit
			else return;
			end;
		end;
	};
	
	-- normal (and hot since you don't see it anyways)
	LoadActor("_meterbg normal")..{
		InitCommand=cmd(diffusealpha,1);
		
		HealthStateChangedMessageCommand=function(self,params)
			-- first, check to see if it's this one that changed,
			-- if not we can ignore this bullshit
			if(params.PlayerNumber == Player) then
				-- ok it was for us, time to see what state it is
				if(params.HealthState == 'HealthState_Alive' or params.HealthState == 'HealthState_Hot') then
					self:linear(0.2);
					self:diffusealpha(1);
				-- ok it wasn't normal/hot
				else
					self:linear(0.2);
					self:diffusealpha(0);
				end;
			-- ok it wasn't for us, exit
			else return;
			end;
		end;
	};
	-- // end meter background //
	
	-- // start meter proper //
	-- (before you die you see) the ring
	LoadActor("_meter ring")..{
		Name="MeterRing";
		InitCommand=cmd(diffusealpha,0);
		
		LifeChangedMessageCommand=function(self,params)
			if(params.Player == Player) then
				local life = params.LifeMeter:GetLife();
				
				-- the following if branch is a hack to stop infinite tween
				-- overflow that I experienced while playing DASH HOPES II.
				-- It seems to work just fine.
				if self:GetTweenTimeLeft() < 0.075 then
					if(life > prevLife) then
						self:diffuse(color("0,1,0,1"));
						self:zoom(0);
						self:smooth(0.075);
						self:zoom(1);
					elseif(life < prevLife) then
						self:diffuse(color("1,0,0,1"));
						self:zoom(1);
						self:smooth(0.075);
						self:zoom(0);
					else
						self:diffuse(color("1,1,1,1"));
						self:zoom(0);
						self:smooth(0.075);
						self:zoom(1);
					end;
					self:smooth(0.025);
					self:diffusealpha(0);
				else
					return;
				end;
				prevLife = params.LifeMeter:GetLife();
				
			else return;
			end;
		end;
	};
	
	-- oh god here it fucking comes!!!
	LoadActor("_meter bar")..{
		Name="MeterNormal";
		InitCommand=cmd(animate,false;setstate,9;diffusealpha,0.9);
		
		HealthStateChangedMessageCommand=function(self,params)
		
			if(params.PlayerNumber == Player) then
				if self:GetTweenTimeLeft() < 0.075 then
					if(params.HealthState == 'HealthState_Hot') then
						-- no need to re-set it
						if not self:GetVisible() then return; end;
						self:visible(false);
					else
						if self:GetVisible() then return; end;
						self:visible(true);
					end;
				else
					-- fuhgeddaboutit (I hate you Dash Hopes II)
					return;
				end;
			else return;
			end;
		end;
		
		LifeChangedMessageCommand=function(self,params)
			-- and this is where the bulk of the code lies. You'll notice it's
			-- very similar to the above. This is kinda intentional.
			
			-- dash hopes 2 ruins everything
			--if bIsDashHopes2 then return; end;
			
			local stateToSet = 0;
			
			if(params.Player == Player) then
				local life = params.LifeMeter:GetLife();
				
				-- 100%
				if life == 1 then stateToSet = 19;
					
				-- 95%
				elseif life >= 0.95 and life < 1 then stateToSet = 18;
				
				-- 90%
				elseif life >= 0.9 and life < 0.95 then stateToSet = 17;
				
				-- 85%
				elseif life >= 0.85 and life < 0.90 then stateToSet = 16;
				
				-- 80%
				elseif life >= 0.8 and life < 0.85 then stateToSet = 15;
				
				-- 75%
				elseif life >= 0.75 and life < 0.80 then stateToSet = 14;
				
				-- 70%
				elseif life >= 0.7 and life < 0.75 then stateToSet = 13;
				
				-- 65%
				elseif life >= 0.65 and life < 0.70 then stateToSet = 12;
				
				-- 60%
				elseif life >= 0.6 and life < 0.65 then stateToSet = 11;
				
				-- 55%
				elseif life >= 0.55 and life < 0.60 then stateToSet = 10;
				
				-- 50%
				elseif life >= 0.5 and life < 0.55 then stateToSet = 9;
				
				-- 45%
				elseif life >= 0.45 and life < 0.50 then stateToSet = 8;
				
				-- 40%
				elseif life >= 0.40 and life < 0.45 then stateToSet = 7;
				
				-- 35%
				elseif life >= 0.35 and life < 0.40 then stateToSet = 6;
				
				-- 30%
				elseif life >= 0.30 and life < 0.35 then stateToSet = 5;
				
				-- 25%
				elseif life >= 0.25 and life < 0.30 then stateToSet = 4;
				
				-- 20%
				elseif life >= 0.20 and life < 0.25 then stateToSet = 3;
				
				-- 15%
				elseif life >= 0.15 and life < 0.20 then stateToSet = 2;
				
				-- 10%
				elseif life >= 0.1 and life < 0.15 then stateToSet = 1;
				
				-- 5%
				elseif life > 0 and life < 0.05 then stateToSet = 0;
				
				-- otherwise
				else stateToSet = 1;
				end;
				
				-- if I ever commit the changes I made to CVS and they
				-- aren't reverted, you can uncomment this section
				-- and it may save you some cycles but I've seen
				-- no problems so far without it.
				
				--if self:GetState() == stateToSet then return;
				--else
				self:setstate(stateToSet);
				--end;
			else return;
			end;
		end;
	};
	
	-- hot meter fill
	LoadActor("_meter hotbar")..{
		Name="MeterHotBase";
		InitCommand=cmd(diffusealpha,0);
		
		HealthStateChangedMessageCommand=function(self,params)
			if(params.PlayerNumber == Player) then
				if(params.HealthState == 'HealthState_Hot') then
					--self:smooth(0.025);
					self:diffusealpha(0.9);
				else
					--self:smooth(0.025);
					self:diffusealpha(0);
				end;
			else return;
			end;
		end;
	};
	
	-- hot meter mask
	LoadActor("_meter mask")..{
		InitCommand=cmd(clearzbuffer,true;zwrite,true;blend,'BlendMode_NoEffect');
	};
	
	-- hot meter animation
	LoadActor("_meter hotanim")..{
		Name="MeterHotAnim";
		InitCommand=cmd(texcoordvelocity,0,1;blend,'BlendMode_Add';diffusealpha,0;ztest,true);
		OnCommand=cmd(diffuseshift;effectclock,"bgm";effectcolor1,color("1,1,1,1");effectcolor2,color("1,1,1,0.5"));
		HealthStateChangedMessageCommand=function(self,params)
			if(params.PlayerNumber == Player) then
				if(params.HealthState == 'HealthState_Hot') then
					--self:smooth(0.025);
					self:diffusealpha(1);
				else
					--self:smooth(0.025);
					self:diffusealpha(0);
				end;
			else return;
			end;
		end;
	};
	
	-- // end meter proper //
	
	-- // start meter overlay //
	-- frame, always shown, doesn't do a damn thing :v
	LoadActor("_meter frame");
	
	-- cap, appears when a player fails.
	LoadActor("_meter cap")..{
		InitCommand=cmd(diffusealpha,0;zoom,1.5);
		
		PlayerFailedMessageCommand=function(self,params)
			if(params.PlayerNumber == Player) then
				self:decelerate(0.2);
				self:zoom(1);
				self:diffusealpha(1);
			else return;
			end;
		end;
		-- on the off chance that someone can unfail themselves...
		HealthStateChangedMessageCommand=function(self,params)
			if(params.PlayerNumber == Player) then
				if(params.HealthState == 'HealthState_Dead') then return;
				else
					self:decelerate(0.2);
					self:zoom(1.5);
					self:diffusealpha(0);
				end;
			else return;
			end;
		end;
	};
	-- // end meter overlay //
};

return meter;

-- coded over two days (really I would say it took 4-5 hours?) by Synikal.
-- you are not expectd to understand this.