-- generic cover adjustment script
local thisPlayer = ...;
assert(thisPlayer);

-- input variables
local holdMovesByFull = 5;
local moveByClamped = 5;
local holdMovesByClamped = 5;

local pName = pname(thisPlayer);

local coverAmount;
if GetUserPref("CoverPosition"..pName) == nil then
	-- write fallback
	coverAmount = 0;
	SetUserPref("CoverPosition"..pName, coverAmount);
else
	coverAmount = GetUserPrefN("CoverPosition"..pName)
end;

local position = THEME:GetMetric("ScreenGameplay","Player".. pName .."OnePlayerOneSideX");

local arrowsStandard = THEME:GetMetric("Player","ReceptorArrowsYStandard");
local arrowsReversed = THEME:GetMetric("Player","ReceptorArrowsYReverse")
local fieldHeight = arrowsReversed - arrowsStandard;
local notefieldMiddle = (arrowsStandard + arrowsReversed) / 2;
local maxCoverAmount = fieldHeight * 1.25;

local coverFile;
if File.Read("Themes/moonlight/Graphics/_gameplay covers/setting.cfg") then
	coverFile = tostring( File.Read("Themes/moonlight/Graphics/_gameplay covers/setting.cfg") );
else
	coverFile = "default";
end;

--[[ welcome to the hard part ]]
local currentGame = string.lower(GAMESTATE:GetCurrentGame():GetName());

local arrowsAndLocations = {
	dance = {
		Left  = -96,
		Up    = -32,
		Down  = 32,
		Right = 96,
	},

	pump = {
		DownLeft = -100,
		UpLeft = -50,
		Center = 0,
		UpRight = 50,
		DownRight = 100,
	},

	para = {
		Left = -108,
		UpLeft = -54,
		Up = 0,
		UpRight = 54,
		Right = 108,
	},

	-- technomotion was 56
};

-- XXX: this can't be the correct Y position...
local arrows = Def.ActorFrame{
	Name = "Arrows";
	InitCommand=cmd(x,position;y,(SCREEN_CENTER_X+arrowsStandard)/2);
};
-- xxx: daisuke master's old default pump noteskins use names like
-- "UpLeft Receptor". pro's fallback noteskin uses _Tap Receptor.

-- this is why things suck in StepMania, everyone starts to standardize to
-- different things. It happened with versions, it's going to end up happening
-- with the noteskins, unless everyone just uses Pro's now. Can I get a headcount?
-- check the alpha readme for threads you can post in.

for button,location in pairs( arrowsAndLocations[ currentGame ] ) do
	arrows[#arrows+1] = NOTESKIN:LoadActorForNoteSkin( button, "Receptor", "default" )..{
		InitCommand=cmd(x,location);
	};
end;

t[#t+1] = arrows;

t[#t+1] = Def.ActorFrame{
	InitCommand=cmd(x,position);

	-- cover
	LoadActor( THEME:GetPathG("_gameplay","covers/".. coverFile .."/4panel") )..{
		Name="Cover"..pName;
		InitCommand=cmd(vertalign,top;y,SCREEN_BOTTOM - coverAmount;);
		--BeginCommand=function(self) Trace("[editcover] cover y position: ".. coverAmount); end;

		CodeMessageCommand=function(self,params)
			--Trace("Cover Amount Before = ".. coverAmount);
			if params.PlayerNumber == thisPlayer then
				if params.Name == "ShiftUp" or
				params.Name == "ShiftUp1" or params.Name == "ShiftUp2" then
					if( coverAmount < maxCoverAmount ) then
						coverAmount = coverAmount + moveByClamped;
					end;
				end;

				if params.Name == "ShiftDown" or
				params.Name == "ShiftDown1" or params.Name == "ShiftDown2" then
					if( coverAmount > 0 ) then
						coverAmount = coverAmount - moveByClamped;
					end;
				end;

				if params.Name == "HoldUp" or
				params.Name == "HoldUp1" or params.Name == "HoldUp2" then
					if( (coverAmount - holdMovesByClamped) < maxCoverAmount ) then
						coverAmount = coverAmount + holdMovesByClamped;
					else coverAmount = 0;
					end;
				end;

				if params.Name == "HoldDown" or
				params.Name == "HoldDown1" or params.Name == "HoldDown2" then
					if( (coverAmount + holdMovesByClamped) > 0 ) then
						coverAmount = coverAmount - holdMovesByClamped;
					else coverAmount = maxCoverAmount;
					end;
				end;

				self:y( SCREEN_BOTTOM - coverAmount );

				MESSAGEMAN:Broadcast("AmountChanged",{ Player = thisPlayer });
				--Trace("Cover Amount After = ".. coverAmount);
			end;
		end;

		OffCommand=function(self)
			SetUserPref("CoverPosition"..pName,coverAmount);
		end;
	};

	-- show pixels
	AutoText("blaster_shiny")..{
		Name="Counter"..pName;
		Text=coverAmount;
		InitCommand=cmd(y,SCREEN_BOTTOM*0.75;shadowlength,1;NoStroke;diffuse,PlayerColor(thisPlayer));
		AmountChangedMessageCommand=function(self,param)
			if param.Player == thisPlayer then
				self:settext(coverAmount);
			end;
		end;
	};
};
return t;