--[[
	Objectives:
		1. Air control (SRB2K does not normally allow this)
		2. Drifting in midair (ditto)
	Toggled through headers:
		Lua.jug_mkwiihandling = any value (enable this system)
		Lua.jug_midairspark = any value (enable drift spark midair)
]]

local FRACUNIT		= FRACUNIT
local ITEMTIME		= 8 * TICRATE
local ACCELMAX 		= 4000
local ORIG_FRICTION = 62914

local BT_ACCELERATE = BT_ACCELERATE
local BT_BRAKE 		= BT_BRAKE
local BT_DRIFT 		= BT_DRIFT

local ANG1		= ANG1
local ANGLE_45 	= ANGLE_45
local ANGLE_135 = ANGLE_135

local EASYSPEED 	= 0
local NORMALSPEED 	= 1
local HARDSPEED 	= 2

local MAXSKINCOLORS = MAXSKINCOLORS

-- IMPORTANT!! NEWER VERSION WILL OVERRIDE OLDER VERSIONS
local WIIMOVEMENTVER	= 1
if jug_wiimove == nil then
	rawset(_G, "jug_wiimove", {})
end

if jug_wiimove.ver == nil or jug_wiimove.ver < WIIMOVEMENTVER then

local isAirControlEnabled = false
local canBuildSparkMidAir = false

freeslot("MT_BRAKEDRIFT_JUG", "sfx_jugadr")
-- mobjinfo[MT_BRAKEDRIFT_JUG] = mobjinfo[MT_BRAKEDRIFT]
mobjinfo[MT_BRAKEDRIFT_JUG] =
{ 	
	doomednum = -1,
	spawnstate = S_BRAKEDRIFT,
	spawnhealth = 1000,
	seestate = S_NULL,
	seesound = sfx_None,
	reactiontime = 8,
	attacksound = sfx_None,
	painstate = S_NULL,
	painchance = 0,
	painsound = sfx_None,
	meleestate = S_NULL,
	missilestate = S_NULL,
	deathstate = S_NULL,
	xdeathstate = S_NULL,
	deathsound = sfx_None,
	speed = 8,
	radius = 8 * FRACUNIT,
	height = 8 * FRACUNIT,
	displayoffset = 1,
	mass = 100, 
	damage = 0,
	activesound = sfx_None,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, 
	raisestate = S_NULL
}

-- lmao of course this function is not exposed
local function K_SpawnDriftSparks(player, pulse)
	if player == nil or not player.valid or
		player.mo == nil or not player.mo.valid then return end
	if leveltime % 2 == 1 then return end

	local pks_drift = player.kartstuff[k_drift]
	local pks_charge = player.kartstuff[k_driftcharge]
	if not pks_drift or pks_charge < K_GetKartDriftSparkValue(player) then return end

	local playerMo		= player.mo
	local playerAngle 	= playerMo.angle
	local playerScale	= playerMo.scale
	local playerSpark	= K_GetKartDriftSparkValue(player)
	local cmdDriftTurn	= player.cmd.driftturn

	local travelangle = playerAngle - ((ANGLE_45 / 5) * pks_drift);

	for i = 0,2 do
		local fakeTerniary = 1;
		if i & 1 then fakeTerniary = -1 end 

		local newx = playerMo.x + P_ReturnThrustX(playerMo, travelangle + fakeTerniary * ANGLE_135, FixedMul(32 * FRACUNIT, playerScale))
		local newy = playerMo.y + P_ReturnThrustY(playerMo, travelangle + fakeTerniary * ANGLE_135, FixedMul(32 * FRACUNIT, playerScale))
		local sparkMobj = P_SpawnMobj(newx, newy, playerMo.z, MT_DRIFTSPARK)

		sparkMobj.target 	= playerMo
		sparkMobj.angle 	= travelangle - ((ANGLE_45 / 5) * pks_drift)
		sparkMobj.destscale = playerScale;
		P_SetScale(sparkMobj, playerScale);

		sparkMobj.momx = playerMo.momx / 2;
		sparkMobj.momy = playerMo.momy / 2;

		if pks_charge >= playerSpark * 4 then
			sparkMobj.color = 1 + (leveltime % (MAXSKINCOLORS - 1))

		elseif pks_charge >= playerSpark * 2 then
			if pks_charge <= (playerSpark * 2) + (24 * 3) then
				sparkMobj.color = SKINCOLOR_RASPBERRY -- transition
			else
				sparkMobj.color = SKINCOLOR_KETCHUP
			end
		else
			sparkMobj.color = SKINCOLOR_SAPPHIRE
		end

		if (pks_drift > 0 and cmdDriftTurn > 0) or -- Inward drifts
			(pks_drift < 0 and cmdDriftTurn < 0) then

			if (pks_drift < 0 and (i & 1)) or (pks_drift > 0 and not (i & 1)) then
				sparkMobj.state = S_DRIFTSPARK_A1
			elseif (pks_drift < 0 and not (i & 1)) or (pks_drift > 0 and (i & 1)) then
				sparkMobj.state =  S_DRIFTSPARK_C1
			end

		elseif (pks_drift > 0 and cmdDriftTurn < 0) or -- Outward drifts
				(pks_drift < 0 and cmdDriftTurn > 0) then

			if (pks_drift < 0 and (i & 1)) or (pks_drift > 0 and not (i & 1)) then
				sparkMobj.state = S_DRIFTSPARK_C1
			elseif (pks_drift < 0 and not (i & 1)) or (pks_drift > 0 and (i & 1)) then
				sparkMobj.state = S_DRIFTSPARK_A1
			end

		end

		K_MatchGenericExtraFlags(sparkMobj, playerMo)
	end
end

local function K_SpawnBrakeDriftSparks(player)
	if player == nil or not player.valid or
		player.mo == nil or not player.mo.valid then return end

	local playerMo = player.mo

	-- Position & etc are handled in its thinker, and its spawned invisible.
	-- This avoids needing to dupe code if we don't need it.
	local mobjSparks = P_SpawnMobj(playerMo.x, playerMo.y, playerMo.z, MT_BRAKEDRIFT_JUG)
	mobjSparks.target = playerMo

	mobjSparks.destscale = playerMo.scale
	P_SetScale(mobjSparks, mobjSparks.destscale)
	K_MatchGenericExtraFlags(mobjSparks, playerMo)

	mobjSparks.flags2 = $ | MF2_DONTDRAW;
end

local function K_SpawnAIZDust(player)
	if player == nil or not player.valid or
		player.mo == nil or not player.mo.valid then return end
	if leveltime % 2 == 1 then return end

	local playerMo = player.mo
	local travelangle = R_PointToAngle2(0, 0, playerMo.momx, playerMo.momy)

	local newx = playerMo.x + P_ReturnThrustX(playerMo,
		travelangle - (player.kartstuff[k_aizdriftstrat] * ANGLE_45), FixedMul(24*FRACUNIT, playerMo.scale))
	local newy = playerMo.y + P_ReturnThrustY(playerMo,
		travelangle - (player.kartstuff[k_aizdriftstrat] * ANGLE_45), FixedMul(24*FRACUNIT, playerMo.scale))
	local dustMobj = P_SpawnMobj(newx, newy, playerMo.z, MT_AIZDRIFTSTRAT)

	dustMobj.angle = travelangle + (player.kartstuff[k_aizdriftstrat] * ANGLE_90)
	dustMobj.destscale = (3 * playerMo.scale) >> 2
	P_SetScale(dustMobj, dustMobj.destscale)

	dustMobj.momx = (6 * playerMo.momx) / 5;
	dustMobj.momy = (6 * playerMo.momy) / 5;
	dustMobj.momz = playerMo.momz / 2;

	K_MatchGenericExtraFlags(dustMobj, playerMo)
	-- print("hello")
end

local function K_CreateRocketSneakers(playerMo)
	K_PlayBoostTaunt(playerMo)
	S_StartSound(playerMo, sfx_s3k3a)

	local player = playerMo.player

	player.kartstuff[k_rocketsneakertimer] = ITEMTIME * 3
	player.kartstuff[k_itemamount] = $ - 1
	
	-- We have to create the rocket sneakers ourselves.
	local prev = playerMo
	for i = 0,1 do
		local rocketSneakerMo = P_SpawnMobj(playerMo.x, playerMo.y, playerMo.z, MT_ROCKETSNEAKER)
		K_MatchGenericExtraFlags(rocketSneakerMo, playerMo)
		rocketSneakerMo.flags		= $ + MF_NOCLIPTHING
		rocketSneakerMo.angle 		= playerMo.angle
		rocketSneakerMo.threshold 	= 10 
		rocketSneakerMo.movecount 	= i % 2
		rocketSneakerMo.movedir		= i + 1
		rocketSneakerMo.lastlook 	= i + 1
		rocketSneakerMo.target 		= playerMo
		rocketSneakerMo.hprev 		= prev
		prev.hnext 					= rocketSneakerMo

		prev 						= rocketSneakerMo
	end
end

-- another edited version of a function that really does not need an onground check :)))))))
local function K_GetKartSpeed(player, doboostpower)
	local k_speed = 150
	local g_cc = FRACUNIT
	local xspd = 3072
	local kartspeed = player.kartspeed
	local finalspeed

	if gamespeed == EASYSPEED then
		g_cc = 53248 + xspd -- 50cc =  81.25 + 4.69 =  85.94%
	elseif gamespeed == HARDSPEED then
		g_cc = 77824 + xspd -- 150cc = 118.75 + 4.69 = 123.44%
	else -- NORMALSPEED
		g_cc = 65536 + xspd -- 100cc = 100.00 + 4.69 = 104.69%
	end

	if G_BattleGametype() and player.kartstuff[k_bumper] <= 0 then
		kartspeed = 1
	end

	k_speed = $ + kartspeed * 3 -- 153 - 177

	finalspeed = FixedMul(FixedMul(k_speed << 14, g_cc), player.mo.scale);

	if doboostpower then
		return FixedMul(finalspeed, player.kartstuff[k_boostpower] + player.kartstuff[k_speedboost])
	end

	return finalspeed
end

local function P_IsLocalPlayer(player)
	if player == consoleplayer then
		return true
	elseif splitscreen then
		for i = 1,#displayplayers do
			if player == displayplayers[i] then
				return true
			end
		end
	end

	return false
end

local function accelcode(player, playerMo)
	local playerButtons = player.cmd.buttons

	-- Turncode	
	local playerAngle = playerMo.angle
	local thrustAngle = playerAngle

	-- Only apply turnrate if the player has a minimum of speed.
	if player.speed > (20 * FRACUNIT) then
		-- naturally correct this momentum angle to the player's
		local thrustAngle = R_PointToAngle2(0, 0, playerMo.momx, playerMo.momy)
	
		-- turn rate calC
		local angleCorrectRate = FixedDiv((ANGLE_45 + ANG1) - (ANG1 * player.kartweight), FRACUNIT * 35)
	
	
		local angleMovementResult = angleCorrectRate
		local angleSidewaysMovementDiff = thrustAngle - playerAngle
		local angleAbsSidewaysMovement = abs(angleSidewaysMovementDiff)
	
		if angleAbsSidewaysMovement < angleCorrectRate then
			angleMovementResult = angleAbsSidewaysMovement
			-- print("angle less than one, correcting.")
		end
	
		if angleSidewaysMovementDiff > 0 then
			thrustAngle = $ - angleMovementResult
		elseif angleSidewaysMovementDiff < 0 then
			thrustAngle = $ + angleMovementResult
		end
	
		local thrustForce = R_PointToDist2(0, 0, playerMo.momx, playerMo.momy)

		-- let the player control themselves horizontally
		playerMo.momx = FixedMul(thrustForce, cos(thrustAngle))
		playerMo.momy = FixedMul(thrustForce, sin(thrustAngle))
	end

	-- Accelcode.
	local speedValue = K_GetKartSpeed(player, true)
	local accelValue = K_GetKartAccel(player)

	local oldSpeed = R_PointToDist2(0, 0, player.rmomx, player.rmomy) -- FixedMul(P_AproxDistance(player.rmomx, player.rmomy), player.mo.scale);
	local newSpeed = FixedDiv(FixedDiv(FixedMul(oldSpeed, ACCELMAX - accelValue) +
		FixedMul(speedValue, accelValue), ACCELMAX), ORIG_FRICTION)

	local finalSpeed = newSpeed - oldSpeed

	-- forwardmove is:
	--  50 while accelerating,
	--  25 while clutching,
	--   0 with no gas, and
	-- -25 when only braking.

	local forwardmove 	= 0
	local holdingGas 	= (playerButtons & BT_ACCELERATE) == BT_ACCELERATE
	local holdingBrake 	= (playerButtons & BT_BRAKE) == BT_BRAKE
	if holdingGas and not holdingBrake then -- Accelerating
		forwardmove = 50
	elseif holdingGas and holdingBrake then -- Clutching
		forwardmove = 25
	elseif not holdingGas and holdingBrake then -- Braking
		forwardmove = -25
	end

	finalSpeed = $ * (forwardmove/25)
	finalSpeed = $ / 2

	if forwardmove < 0 and finalSpeed > FRACUNIT*2 then
		finalSpeed = finalSpeed/2
	elseif forwardmove < 0 then
		finalSpeed = -FRACUNIT/2
	end

	if finalSpeed < 0 then finalSpeed = 0 end

	playerMo.momx = $ + P_ReturnThrustX(thrustAngle, finalSpeed)
	playerMo.momy = $ + P_ReturnThrustY(thrustAngle, finalSpeed)

	playerMo.momx = FixedMul(playerMo.momx, playerMo.friction)
	playerMo.momy = FixedMul(playerMo.momy, playerMo.friction)
end

local function driftcode_release(player,
	pks_charge, pks_boost, pks_drift,
	blueSpark, redSpark, rainbowSpark)

	-- Release
	local successSpark = false

	if pks_drift ~= -5 and pks_drift ~= 5
		-- print("Released.")
		if pks_charge < blueSpark then -- Nothing.
			-- print("Nothing.")
			player.kartstuff[k_driftcharge] = 0

		elseif pks_charge >= blueSpark and pks_charge < redSpark -- Blue
			-- print("Blue.")
			if pks_boost < 20 then
				player.kartstuff[k_driftboost] = 20
			end
			successSpark = true

		elseif pks_charge >= redSpark and pks_charge < rainbowSpark -- Red
			-- print("Red.")pks_drift
			if pks_boost < 50 then
				player.kartstuff[k_driftboost] = 50
			end
			successSpark = true

		elseif pks_charge >= rainbowSpark -- Rainbow
			-- print("Rainbow.")
			if pks_boost < 125 then
				player.kartstuff[k_driftboost] = 125
			end
			successSpark = true

		end
	end

	if successSpark then
		-- print("Release")
		S_StartSound(player.mo, sfx_s23c)
		player.kartstuff[k_driftcharge] = 0
	end
end

local function driftcode_start(player,
	pks_drift, pks_jmp,
	cmdDriftTurn, minSpeed)

	if cmdDriftTurn > 0 and player.speed > minSpeed and pks_jmp == 1 and 
		(pks_drift == 0 or player.kartstuff[k_driftend] == 1) then
		-- Starting left drift
		player.kartstuff[k_drift] = 1
		player.kartstuff[k_driftend] = 0
		player.kartstuff[k_driftcharge] = 0

	elseif cmdDriftTurn < 0 and player.speed > minSpeed and pks_jmp == 1 and
		(pks_drift == 0 or player.kartstuff[k_driftend] == 1) then
		-- Starting right drift
		player.kartstuff[k_drift] = -1
		player.kartstuff[k_driftend] = 0
		player.kartstuff[k_driftcharge] = 0

	elseif pks_jmp == 0 then
		-- Drift is not being performed so if we're just finishing set driftend and decrement counters
		if pks_drift > 0 then
			player.kartstuff[k_drift] = $ - 1
			player.kartstuff[k_driftend] = 1
		elseif pks_drift < 0 then
			player.kartstuff[k_drift] = $ + 1
			player.kartstuff[k_driftend] = 1
		else
			player.kartstuff[k_driftend] = 0
		end
	end
end

local function driftcode_performingit(player,
	pks_charge, pks_drift, pks_jmp,
	blueSpark, redSpark, rainbowSpark,
	cmdDriftTurn, minSpeed)

	-- Incease/decrease the drift value to continue drifting in that direction
	if player.kartstuff[k_spinouttimer] == 0 and pks_jmp == 1 and pks_drift ~= 0 then
		local driftadditive = 0

		if canBuildSparkMidAir then
			driftadditive = 24

			if pks_drift >= 1 then -- Drifting to the left
	
				player.kartstuff[k_drift] = $ + 1
				if player.kartstuff[k_drift] > 5 then
					player.kartstuff[k_drift] = 5
				end
	
				if cmdDriftTurn > 0 then -- Inward
					driftadditive = $ + (abs(cmdDriftTurn) / 100)
				elseif cmdDriftTurn < 0 then -- Outward
					driftadditive = $ - (abs(cmdDriftTurn) / 75)
				end
	
			elseif pks_drift <= -1 then -- Drifting to the right
				player.kartstuff[k_drift] = $ - 1
				if player.kartstuff[k_drift] < -5 then
					player.kartstuff[k_drift] = -5
				end
	
				if cmdDriftTurn < 0 then -- Inward
					driftadditive = $ + (abs(cmdDriftTurn) / 100)
				elseif cmdDriftTurn > 0 then -- Outward
					driftadditive = $ - (abs(cmdDriftTurn) / 75)
				end
			end
	
			-- Disable drift-sparks until you're going fast enough
			if player.kartstuff[k_getsparks] == 0 or
				(player.kartstuff[k_offroad] and
				not player.kartstuff[k_invincibilitytimer] and
				not player.kartstuff[k_hyudorotimer] and
				not player.kartstuff[k_sneakertimer]) then
				driftadditive = 0
			end
		end
		
		if player.speed > (minSpeed * 2) then
			player.kartstuff[k_getsparks] = 1
		end

		-- This spawns the drift sparks
		if player.kartstuff[k_driftcharge] + driftadditive >= blueSpark then
			K_SpawnDriftSparks(player)
		end

		-- Sound whenever you get a different tier of sparks
		if P_IsLocalPlayer(player) and
			((pks_charge < blueSpark and pks_charge + driftadditive >= blueSpark)
			or (pks_charge < redSpark and pks_charge + driftadditive >= redSpark)
			or (pks_charge < rainbowSpark and pks_charge + driftadditive >= rainbowSpark)) then

			S_StartSoundAtVolume(playerMo, sfx_s3ka2, 192)
		end

		-- Plays the sound, doesn't deserve
		-- its own function.
		if leveltime % 6 == 0 then
			S_StartSound(playerMo, sfx_jugadr)
		end

		player.kartstuff[k_driftcharge] = $ + driftadditive
		player.kartstuff[k_driftend] = 0
	end
end

local function driftcode_stop_misc(player,
	cmdDriftTurn, minSpeed)

	local playerButtons = player.cmd.buttons

	-- Stop drifting
	if player.kartstuff[k_spinouttimer] > 0 or player.speed < minSpeed then
		player.kartstuff[k_drift] = 0
		player.kartstuff[k_driftcharge] = 0
		player.kartstuff[k_aizdriftstrat] = 0
		player.kartstuff[k_brakedrift] = 0
		player.jug_mkwii_brakedrift	= 0
		player.kartstuff[k_getsparks] = 0
	end

	if not player.kartstuff[k_sneakertimer] or
		not cmdDriftTurn or
		not player.kartstuff[k_aizdriftstrat] or
		(cmdDriftTurn > 0) ~= (player.kartstuff[k_aizdriftstrat] > 0) then

		if not player.kartstuff[k_drift] then
			player.kartstuff[k_aizdriftstrat] = 0
		else
			local slipstream = -1
			if player.kartstuff[k_drift] > 0 then slipstream = 1 end

			player.kartstuff[k_aizdriftstrat] = slipstream
			-- print("does this work")
		end

	elseif player.kartstuff[k_aizdriftstrat] and not player.kartstuff[k_drift] then
		K_SpawnAIZDust(player)
	end

	if player.kartstuff[k_drift] and
		((playerButtons & BT_BRAKE) == BT_BRAKE or
		 (playerButtons & BT_ACCELERATE) ~= BT_ACCELERATE) then

		if player.jug_mkwii_brakedrift == 0 then
			K_SpawnBrakeDriftSparks(player)
		end

		player.jug_mkwii_brakedrift = 1
	else
		player.jug_mkwii_brakedrift = 0
	end

	-- print("holding brake: " + ((playerButtons & BT_BRAKE) == BT_BRAKE))
	-- print("letting go of accel: " + ((playerButtons & BT_ACCELERATE) ~= BT_ACCELERATE))
end

local function driftcode_frames(player, playerMo,
	pks_drift)
	-- Drifting Left - S_KART_DRIFT1_L
	if pks_drift > 0 then
		if not (playerMo.state >= #states[S_KART_DRIFT1_L] and playerMo.state <= #states[S_KART_DRIFT2_L]) then
			playerMo.state = S_KART_DRIFT1_L
		end
	-- Drifting Right - S_KART_DRIFT1_R
	elseif pks_drift < 0 then
		if not (playerMo.state >= #states[S_KART_DRIFT1_R] and playerMo.state <= #states[S_KART_DRIFT2_R]) then
			playerMo.state = S_KART_DRIFT1_R
		end
	end

end

local function driftcode(player, playerMo)
	local pks_charge 	= player.kartstuff[k_driftcharge]
	local pks_boost		= player.kartstuff[k_driftboost]
	local pks_drift 	= player.kartstuff[k_drift]
	local pks_jmp		= player.kartstuff[k_jmp]

	local minSpeed 		= 10 * playerMo.scale
	local blueSpark 	= K_GetKartDriftSparkValue(player)
	local redSpark 		= blueSpark * 2
	local rainbowSpark 	= redSpark * 2

	local cmdDriftTurn	= player.cmd.driftturn

	-- Release - it is handled first to prevent frame-perfect chaindrifts.
	driftcode_release(player,
		pks_charge, pks_boost, pks_drift,
		blueSpark, redSpark, rainbowSpark)

	-- Doing the actual drifting either left or right.
	driftcode_start(player,
		pks_drift, pks_jmp,
		cmdDriftTurn, minSpeed)

	-- These values were probably updated, refresh the copies
	pks_drift 	= player.kartstuff[k_drift]
	pks_charge 	= player.kartstuff[k_driftcharge]

	-- Performing the drift itself.
	driftcode_performingit(player,
		pks_charge, pks_drift, pks_jmp,
		blueSpark, redSpark, rainbowSpark,
		cmdDriftTurn, minSpeed)

	-- Ending the drift, and performing misc. actions like
	-- brakedrifting and sliptiding.
	driftcode_stop_misc(player,
		cmdDriftTurn, minSpeed)

	-- The visual part of the drift
	driftcode_frames(player, playerMo,
		pks_drift)

end

local function itemcode(player, playerMo)
	local playerButtons = player.cmd.buttons
	local pks = player.kartstuff

	-- Press item while holding a sneaker to enable the sneaker in mid-air
	-- Holding the button will not use multiple sneakers.
	player.holdingItemBTN = $ or false
	if (playerButtons & BT_ATTACK) == BT_ATTACK and
		player.holdingItemBTN == false then
		
		-- Because you normally cannot use speed items in the air, the
		-- whole behaviour has to be recreated from hardcode to Lua.

		-- Rocket Sneaker behaviour when already deployed.
		if pks[k_rocketsneakertimer] > 1 then
			K_DoSneaker(player, 2) -- taunt
			K_PlayBoostTaunt(playerMo)
			pks[k_rocketsneakertimer] = $ - (2 * TICRATE)
			
			if pks[k_rocketsneakertimer] < 1 then
				pks[k_rocketsneakertimer] = 1
			end
		--Rocket Sneaker behaviour when not deployed.
		elseif pks[k_itemtype] == KITEM_ROCKETSNEAKER then
			K_CreateRocketSneakers(playerMo)
		-- Sneaker behaviour
		elseif pks[k_itemtype] == KITEM_SNEAKER then
			K_DoSneaker(player, 1) -- taunt
			K_PlayBoostTaunt(playerMo)
			pks[k_itemamount] = $ - 1
		end

		-- Make item button holding persist between deaths.
		if player.holdingItemBTN == false then
			player.holdingItemBTN = true
		end
	elseif (playerButtons & BT_ATTACK) ~= BT_ATTACK and
		player.holdingItemBTN == true then -- Let go.
		player.holdingItemBTN = false
	end
end

jug_wiimove.mkwiihandling = function(playerMo)
	local player = playerMo.player
	local pks	= player.kartstuff

	-- print("k_aizdriftstrat (old): " + player.kartstuff[k_aizdriftstrat])
	-- print("k_drift (old): " + player.kartstuff[k_drift])
	-- if not player.mkwiihandling then return end
	if isAirControlEnabled == false or 
		P_IsObjectOnGround(playerMo) or
		(playerMo.paraglideMobj ~= nil and playerMo.paraglideMobj.valid) or
		player.playerstate == PST_DEAD or
		pks[k_respawn] > 0 or
		P_PlayerInPain(player) or
		pks[k_spinouttimer] > 0 or
		pks[k_squishedtimer] > 0 then return end

	-- itemcode
	itemcode(player, playerMo)

	-- accelcode
	accelcode(player, playerMo)

	-- Drifting spark release and charge
	driftcode(player, playerMo)

end

jug_wiimove.midairBrakeDriftSparks = function(sparkMobj)
	local playerMo 	= sparkMobj.target
	local player 	= playerMo.player
	local pks	 	= player.kartstuff

	if playerMo == nil or not playerMo.valid or not playerMo.health or 	-- is the player mobj invalid or dead?
		player == nil or not player.valid or		-- is the player invalid?
		not pks[k_drift] or not player.jug_mkwii_brakedrift or -- not drifting or brakedrifting
		-- not holding brake or letting go of accel
		not ((player.cmd.buttons & BT_BRAKE) == BT_BRAKE or
		 	(player.cmd.buttons & BT_ACCELERATE) ~= BT_ACCELERATE) then

		P_RemoveMobj(sparkMobj)
		return

	else
		local travelangle = playerMo.angle - ((ANGLE_45 / 5) * pks[k_drift])

		local newx = playerMo.x + P_ReturnThrustX(playerMo, travelangle + ANGLE_180, 24 * playerMo.scale)
		local newy = playerMo.y + P_ReturnThrustY(playerMo, travelangle + ANGLE_180, 24 * playerMo.scale)
		P_TeleportMove(sparkMobj, newx, newy, playerMo.z);

		sparkMobj.angle = travelangle - ((ANGLE_90 / 5) * pks[k_drift])
		sparkMobj.destscale = playerMo.scale
		P_SetScale(sparkMobj, sparkMobj.destscale)

		if pks[k_driftcharge] >= K_GetKartDriftSparkValue(player) * 4 then
			sparkMobj.color = 1 + (leveltime % (MAXSKINCOLORS-1))
		elseif pks[k_driftcharge] >= K_GetKartDriftSparkValue(player) * 2 then
			sparkMobj.color = SKINCOLOR_KETCHUP
		elseif pks[k_driftcharge] >= K_GetKartDriftSparkValue(player) then
			sparkMobj.color = SKINCOLOR_SAPPHIRE
		else
			sparkMobj.color = SKINCOLOR_SILVER
		end

		if not S_SoundPlaying(sparkMobj, sfx_cdfm17) then
			S_StartSound(sparkMobj, sfx_cdfm17)
		end

		K_MatchGenericExtraFlags(sparkMobj, playerMo)
		if leveltime & 1 then
			sparkMobj.flags2 = $ | MF2_DONTDRAW
		end
	end
end

local function preMapStartPrep()
	if leveltime ~= 3 then return end
	isAirControlEnabled = (mapheaderinfo[gamemap].jug_mkwiihandling ~= nil)
	canBuildSparkMidAir = (mapheaderinfo[gamemap].jug_midairspark ~= nil)

	-- if (isAirControlEnabled) then print("yes") end
end

addHook("ThinkFrame", preMapStartPrep)

if jug_wiimove.ver == nil then

	addHook("MobjThinker",
	function(mobj)
		jug_wiimove.mkwiihandling(mobj)
	end, MT_PLAYER)

	addHook("MobjThinker",
	function(mobj)
		jug_wiimove.midairBrakeDriftSparks(mobj)
	end, MT_BRAKEDRIFT_JUG)

end


jug_wiimove.ver = WIIMOVEMENTVER
end
