local c;
local player = Var "Player";
local bTiltJudgments = GetUserPrefB("TiltJudgments");

local JudgeCmds = {
	TapNoteScore_W1 = THEME:GetMetric( "Judgment", "JudgmentW1Command" );
	TapNoteScore_W2 = THEME:GetMetric( "Judgment", "JudgmentW2Command" );
	TapNoteScore_W3 = THEME:GetMetric( "Judgment", "JudgmentW3Command" );
	TapNoteScore_W4 = THEME:GetMetric( "Judgment", "JudgmentW4Command" );
	TapNoteScore_W5 = THEME:GetMetric( "Judgment", "JudgmentW5Command" );
	TapNoteScore_Miss = THEME:GetMetric( "Judgment", "JudgmentMissCommand" );
};

local TNSFrames = {
	TapNoteScore_W1 = 0;
	TapNoteScore_W2 = 1;
	TapNoteScore_W3 = 2;
	TapNoteScore_W4 = 3;
	TapNoteScore_W5 = 4;
	TapNoteScore_Miss = 5;
};

local judgmentSet;

local t = Def.ActorFrame {
	InitCommand=cmd(fov,90);

	LoadActor( HDActor("judgments") ) .. {
		Name="JudgmentNormal";
		InitCommand=cmd(pause;visible,false;);
		ResetCommand=cmd(finishtweening;x,0;y,0;stopeffect;visible,false);
	};
	LoadActor( HDActor("offset judgments") ) .. {
		Name="JudgmentWithOffsets";
		InitCommand=cmd(pause;visible,false;);
		ResetCommand=cmd(finishtweening;x,0;y,0;stopeffect;visible,false);
	};
	InitCommand = function(self)
		c = self:GetChildren();
		if GetUserPref("JudgmentSet") == "Offset" then
			judgmentSet = c.JudgmentWithOffsets;
		else
			judgmentSet = c.JudgmentNormal;
		end;
	end;

	JudgmentMessageCommand=function(self, param)
		if param.Player ~= player then return end;
		if not param.TapNoteScore then return end;
		if param.HoldNoteScore then return end;

		-- frame check; actually relevant now.
		local iNumStates = judgmentSet:GetNumStates();
		local iFrame = TNSFrames[param.TapNoteScore];
		if not iFrame then return end
		if iNumStates == 12 then
			iFrame = iFrame * 2;
			if not param.Early then
				iFrame = iFrame + 1;
			end
		end
		self:playcommand("Reset");

		-- begin commands
		judgmentSet:visible( true );
		judgmentSet:setstate( iFrame );

		local iOffset = param.TapNoteOffset;
		if iFrame == 0 then
			-- compare to 5 decimal places
			local cmpOffset = round(iOffset,5);
			-- xxx: some people may have changed their judges so that this
			-- falls in a non-W1 window:
			if cmpOffset > -0.01000 and cmpOffset < 0.01000 then
				-- "exactly on the dot" = PLATINUM
				judgmentSet:glowshift();
				if cmpOffset == 0.00000 then
					judgmentSet:effectcolor1( color("0.875,0.97,1,0") );
					judgmentSet:effectcolor2( color("0.875,0.97,1,0.75") );
				else
					judgmentSet:effectcolor1( color("1,1,1,0") );
					judgmentSet:effectcolor2( color("1,1,1,0.75") );
				end;
				judgmentSet:effectperiod( 0.01 );
				if not GAMESTATE:IsDemonstration() then
					local curFlashMarvs = getenv("FlashingMarvs"..pname(player));
					if curFlashMarvs then
						setenv("FlashingMarvs"..pname(player), curFlashMarvs+1 );
					end
				end;
			end;
		end;

		judgmentSet:diffusealpha(1);
		if bTiltJudgments then
			judgmentSet:rotationx(-45);
			judgmentSet:rotationy(player == PLAYER_1 and -10 or 10)
			judgmentSet:rotationz(player == PLAYER_1 and -3 or 3);

			judgmentSet:linear(0.1);

			judgmentSet:rotationx(player == PLAYER_1 and -4.5 or 4.5);
			judgmentSet:rotationy(0);
		else
			judgmentSet:zoom(1.2);
			judgmentSet:bounceend(0.1);
			judgmentSet:zoom(1.0);
		end;
		(cmd(sleep,0.8;linear,0.1;rotationx,0;rotationz,0;diffusealpha,0))(judgmentSet);
		--JudgeCmds[param.TapNoteScore](judgmentSet);
	end;
};

return t;
