-- EASING --
local path = GAMESTATE:GetCurrentSong():GetSongDir()..'lua/'
loadfile(path..'easing.lua')()
loadfile(path.."mods.lua")()

local linear, inQuad, outQuad, inOutQuad, outInQuad, inCubic, outCubic, inOutCubic, outInCubic, inQuart,outQuart, inOutQuart, outInQuart, inQuint, outQuint, inOutQuint, outInQuint, inSine, outSine, inOutSine,outInSine, inExpo, outExpo, inOutExpo, outInExpo, inCirc, outCirc, inOutCirc, outInCirc, inElastic,outElastic, inOutElastic, outInElastic, inBack, outBack, inOutBack, outInBack, inBounce, outBounce,inOutBounce, outInBounce = ease.linear, ease.inQuad, ease.outQuad, ease.inOutQuad, ease.outInQuad,ease.inCubic, ease.outCubic, ease.inOutCubic, ease.outInCubic, ease.inQuart, ease.outQuart,ease.inOutQuart, ease.outInQuart, ease.inQuint, ease.outQuint, ease.inOutQuint, ease.outInQuint,ease.inSine, ease.outSine, ease.inOutSine, ease.outInSine, ease.inExpo, ease.outExpo, ease.inOutExpo,ease.outInExpo, ease.inCirc, ease.outCirc, ease.inOutCirc, ease.outInCirc, ease.inElastic,ease.outElastic, ease.inOutElastic, ease.outInElastic, ease.inBack, ease.outBack, ease.inOutBack,ease.outInBack, ease.inBounce, ease.outBounce, ease.inOutBounce, ease.outInBounce

local demon_glow_height_ratio = SCREEN_HEIGHT/480
local demon_glow_width_ratio = SCREEN_WIDTH/640
local demon_glow_sdwidth_ratio = (480*(SCREEN_WIDTH/SCREEN_HEIGHT))/640

	sw = SCREEN_WIDTH
	sh = SCREEN_HEIGHT --shortcuts
	
	scx = sw/2
	scy = sh/2
	
	item_scale = sh/480



local demon_glow_screenaft = --To help replicate nITG behavior, I'm using Kid's screen AFT
  Def.ActorFrameTexture{
    InitCommand= function(self)

    self:SetWidth(SCREEN_WIDTH);
    self:SetHeight(SCREEN_HEIGHT);
    self:EnableDepthBuffer( true );
    self:EnableAlphaBuffer( true );
    self:EnableFloat( false );
    self:EnablePreserveTexture( false );
    self:visible(true);
    self:Create();
    screenAft=self

    demon_glow_aft_height_ratio = SCREEN_HEIGHT/screenAft:GetTexture():GetTextureHeight()
    demon_glow_aft_width_ratio = SCREEN_WIDTH/screenAft:GetTexture():GetTextureWidth()

    end,
    --BACKINGQUAD
    --Def.Quad{
    --    OnCommand= function(self) self:Center():zoomto(SCREEN_WIDTH,SCREEN_HEIGHT):diffuse(0,0,0,1) end,
    --},
	
  }
  
  local demon_glow_screenaft2 =
  Def.ActorFrameTexture{
    InitCommand= function(self)

    self:SetWidth(SCREEN_WIDTH);
    self:SetHeight(SCREEN_HEIGHT);
    self:EnableDepthBuffer( true );
    self:EnableAlphaBuffer( true );
    self:EnableFloat( false );
    self:EnablePreserveTexture( false );
    self:visible(true);
    self:Create();
    screenAft2=self

    end,
    --BACKINGQUAD
    --Def.Quad{
    --    OnCommand= function(self) self:Center():zoomto(SCREEN_WIDTH,SCREEN_HEIGHT):diffuse(0,0,0,1) end,
    --},
	
  }
  
  demon_glow_accessible = {}

--Let's add to the AFT to replicate our screen. -Kid
local thingstoproxy = {'Underlay','PlayerP1','PlayerP2','Overlay','LifeP1','LifeP2','ScoreP1','ScoreP2','BPMDisplay','SongMeterDisplayP1', 'SongMeterDisplayP2', 'StepsDisplayP1', 'StepsDisplayP2', 'StageDisplay', 'SongTitle'}


d3d = false


if not string.find(string.lower(PREFSMAN:GetPreference('VideoRenderers')), 'opengl')
or string.find(string.lower(PREFSMAN:GetPreference('VideoRenderers')), 'd3d')
and string.find(string.lower(PREFSMAN:GetPreference('VideoRenderers')), 'opengl') 
and string.find(string.lower(PREFSMAN:GetPreference('VideoRenderers')), 'd3d') < 
string.find(string.lower(PREFSMAN:GetPreference('VideoRenderers')), 'opengl') then
	d3d = true
end

local addproxy = function(actor, name)
	local thing = SCREENMAN:GetTopScreen():GetChild(name)
	if thing and thing:GetVisible() and thing:GetDiffuseAlpha() ~= 0 then actor:SetTarget(thing) end
end

demon_bgb = PREFSMAN:GetPreference("BGBrightness")

if not d3d then

	demon_glow_screenaft[#demon_glow_screenaft+1] = LoadActor("../bg.png")..{
		OnCommand=cmd(scaletofit,0,0,SCREEN_WIDTH,SCREEN_HEIGHT;diffuse,demon_bgb,demon_bgb,demon_bgb,1;visible,false),
		ShowAFTMessageCommand=function(self)
			if d3d then
				self:visible(false)
			else
				self:visible(true)
			end
		end,
		HideAFTMessageCommand=cmd(visible,false)
	}
	
	for i,v in pairs(thingstoproxy)do
		demon_glow_screenaft[#demon_glow_screenaft+1] =
		Def.ActorProxy{
			ProxyStartMessageCommand= function(self)
				addproxy(self, v)
			end,
		}
	end
	
	demon_glow_screenaft2[#demon_glow_screenaft2+1] =
	Def.ActorProxy{
		ProxyStartMessageCommand= function(self)
			self:SetTarget(demon_glow_sprite)
		end,
	}
	
end

function mod_do(str,pn)
	if pn then if GAMESTATE:IsPlayerEnabled(pn-1) then handle_mods(str,pn) end
	else for pn=1,2 do if GAMESTATE:IsPlayerEnabled(pn-1) then handle_mods(str,pn) end end end
end

local diff = {0,0}
if GAMESTATE:IsHumanPlayer(PLAYER_1) then
	local stepsr = (GAMESTATE:GetCurrentSteps(PLAYER_1):GetDifficulty())
	if stepsr == "Difficulty_Beginner" then diff[1] = 0 end
	if stepsr == "Difficulty_Easy" then diff[1] = 1 end
	if stepsr == "Difficulty_Medium" then diff[1] = 2 end
	if stepsr == "Difficulty_Hard" then diff[1] = 3 end
	if stepsr == "Difficulty_Challenge" then diff[1] = 4 end
end
if GAMESTATE:IsHumanPlayer(PLAYER_2) then
	local stepsr = (GAMESTATE:GetCurrentSteps(PLAYER_2):GetDifficulty())
	if stepsr == "Difficulty_Beginner" then diff[2] = 0 end
	if stepsr == "Difficulty_Easy" then diff[2] = 1 end
	if stepsr == "Difficulty_Medium" then diff[2] = 2 end
	if stepsr == "Difficulty_Hard" then diff[2] = 3 end
	if stepsr == "Difficulty_Challenge" then diff[2] = 4 end
end

mes, ma, ca, mfsb = {}, {}, 1, GAMESTATE:GetSongBeat();
local l, e, me, m2 = 'len', 'end', function (t)
	local beat,len,str1,str2,mod,ease,sus,opt1,opt2 = unpack(t)
	for pn=1,2 do
		if not t.min and not t.only or t.only and diff[pn] == t.only or t.min and diff[pn] >= t.min then
			if not t.plr or pn == t.plr then
				table.insert(mes,{beat,len,str1,str2,mod,'len',ease,pn,sus,opt1,opt2})
			end
		end
	end
end, function (beat,fun,per) table.insert(ma,{beat,fun,per}) end

if PlayerOptions.DizzyHolds then
	me{0,999,100,100,'dizzyholds',linear}
end

me{56,4,0,30,'drunk',inOutCubic,min=3}
me{67,4,30,0,'drunk',inOutCubic,min=3}
me{56,4,0,80,'wave',inOutCubic,min=3}
me{65,4,80,0,'wave',inOutCubic,min=3}

me{197.9,.1,0,150,'drunk',linear,min=3}
me{198,.5,150,0,'drunk',outCubic,min=3}
me{198.9,.1,0,-150,'drunk',linear,min=3}
me{199,.5,-150,0,'drunk',outCubic,min=3}
me{199.9,.1,0,150,'drunk',linear,min=3}
me{200,.5,150,0,'drunk',outCubic,min=3}

m2(222,function()
	for pn=1,2 do
		local a = SCREENMAN:GetTopScreen():GetChild('PlayerP'..pn)
		if a then
			a:decelerate(30/112)
			a:zoomz(10)
			a:zoomx(0)
			a:decelerate(30/112)
			a:zoomz(0)
		end
	end
end)

m2(175,function()
	demon_scale:x(1)
	demon_scale:linear(60/112)
	demon_scale:x(4)
end)
m2(187.5,function()
	demon_scale:linear(90/112)
	demon_scale:x(1)
end)
m2(175,function() MESSAGEMAN:Broadcast('ShowAFT') print("show aft") end)
m2(189,function() MESSAGEMAN:Broadcast('HideAFT') print("hide aft") end)
m2(0,function() MESSAGEMAN:Broadcast('ProxyStart') end)

function cmp(a,b)
	return a[1] < b[1]
end
if table.getn(ma) > 1 then
	table.sort(ma, cmp)
end

local ac = Def.ActorFrame{
	
	
	demon_glow_screenaft,
	demon_glow_screenaft2,
	
	
	Def.Sprite{
		InitCommand=function(self) demon_glow_sprite = self end,
		ProxyStartMessageCommand= function(self)
			self:vibrate()
			self:effectmagnitude(0,0,0)
			self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y)
			self:rotationz(0);
			self:diffuse(1,1,1,1)
			--self:blend('add')
			self:visible(false)
			if not d3d then
				self:SetTexture(screenAft:GetTexture())
			end
			self:basezoomx(0.25)
			self:basezoomy(0.25)
		end,
		ShowAFTMessageCommand=function(self)
			if d3d then
				self:visible(false)
			else
				self:visible(true)
			end
		end,
		HideAFTMessageCommand=cmd(visible,false)
	},
	Def.Sprite{
		InitCommand=function(self) demon_glow_sprite2 = self end,
		ProxyStartMessageCommand= function(self)
			self:vibrate()
			self:effectmagnitude(0,0,0)
			self:xy(SCREEN_CENTER_X,SCREEN_CENTER_Y)
			self:rotationz(0);
			self:diffuse(1,1,1,1)
			--self:blend('add')
			self:visible(false)
			self:SetTextureFiltering(false)
			if not d3d then
				self:SetTexture(screenAft2:GetTexture())
			end
			self:basezoomx(4)
			self:basezoomy(4)
		end,
		ShowAFTMessageCommand=function(self)
			if d3d then
				self:visible(false)
			else
				self:visible(true)
			end
		end,
		HideAFTMessageCommand=cmd(visible,false)
	},
	
	Def.Actor{
		OnCommand=function(s)
			s:queuecommand('Loop')
		end,
		LoopCommand=function(self)
			local beat = GAMESTATE:GetSongBeat()
			if beat > mfsb+0.1 then
				for i,v in pairs(mes) do
					if beat >=v[1] then
						if (v[6] == 'len' and beat <=v[1]+v[2]) or (v[6] == 'end' and beat <=v[2]) then
							local duration, curtime, diff, startstrength, curve, mod = v[2], beat - v[1], v[4] - v[3], v[3], v[7], v[5]
							if v[6] == 'end' then duration = v[2] - v[1] end
							local strength = curve(curtime, startstrength, diff, duration, v[10], v[11])
							local modstr = v[5] == 'xmod' and strength..'x' or (v[5] == 'cmod' and 'C'..strength or strength..' '..v[5])
							mod_do('*10000 '..modstr,v[8])
						elseif (v[9] and ((v[6] == 'len' and beat <=v[1]+v[2]+v[9]) or (v[6] == 'end' and beat <=v[9]))) then
							local strength, modstr = v[4], v[5] == 'xmod' and strength..'x' or (v[5] == 'cmod' and 'C'..strength or strength..' '..v[5])
							mod_do('*10000 '..modstr,v[8])
						end
					end
				end
				
				demon_glow_sprite:basezoomx(1/demon_scale:GetX())
				demon_glow_sprite:basezoomy(1/demon_scale:GetX())
				demon_glow_sprite2:basezoomx(demon_scale:GetX())
				demon_glow_sprite2:basezoomy(demon_scale:GetX())
				
				while ca<=table.getn(ma) and GAMESTATE:GetSongBeat()>=ma[ca][1] do
					if ma[ca][3] or GAMESTATE:GetSongBeat() < ma[ca][1]+2 then
						ma[ca][2]()
					end
					ca = ca+1;
				end
			end
			self:sleep(1/60) self:queuecommand('Loop')
		end
	},
	
	Def.Actor{ OnCommand= function(s) mod_firstSeenBeat = GAMESTATE:GetSongBeat() s:sleep(9e9) end },
	Def.Quad{ InitCommand=function(self) demon_fader = self end, OnCommand=cmd(diffuse,0,0,0,0;stretchto,0,0,SCREEN_WIDTH,SCREEN_HEIGHT) },
	Def.Quad{ InitCommand=function(self) demon_scale = self end, OnCommand=cmd(x,1;y,1;visible,false) },
	Def.Quad{ OnCommand=cmd(diffuse,1,1,1,0;stretchto,0,0,SCREEN_WIDTH,SCREEN_HEIGHT), FlashMessageCommand=cmd(diffusealpha,1;linear,2;diffusealpha,0;) }
}
return ac