local max_burst = 10000
local max_spent = 3000
local max_charge = 30
local idle_bleed = 3
local otrx_mul = CV_FindVar("otrx_mul")

local function Burst_Initialize(player)
  player.OpenTricks.Burst = {["last_drift"] = 0, ["storage"] = 0, ["charge"] = 0, ["first_burst"] = true, ["mini"] = 0}
end

local function Burst_Bleed(player, trying)
  player.OpenTricks.Burst.storage = max(0, $ - trying)
  player.OpenTricks.Burst.charge = max(0, $ - trying)
end

local function Burst_Charge(player, trying)
  local bleed = min(trying, player.OpenTricks.Burst.storage)
  player.OpenTricks.Burst.storage = $ - bleed
  player.OpenTricks.Burst.charge = $ + bleed
end

local function Burst_Activate(player, spent)
  local mobj = player.mo
  local burst_t = player.OpenTricks.Burst
  if not burst_t.charge return end
  
  local thrust_speed = FixedMul(K_GetKartSpeed(player, false) * 10 / 10, otrx_mul.value) 
  
  if not P_IsObjectOnGround(mobj)
    thrust_speed = $ / 2
  elseif player.kartstuff[k_offroad]
    thrust_speed = $ / 2
  end
  
  local spent = min(max_spent, burst_t.charge)
  local spent_ratio = (FRACUNIT * spent) / max_spent
  thrust_speed = FixedMul($ * 18 / 10, spent_ratio)

  burst_t.charge = max(0, min($ - spent, max_burst))
  
  S_StartSound(mobj, sfx_cdfm62)
  S_StartSound(mobj, sfx_s3k48)

  P_Thrust(mobj, mobj.angle - (270 * player.kartstuff[k_driftend]), thrust_speed)
end

local function Burst_Thinker(player)
  local mobj = player.mo
  local burst_t = player.OpenTricks.Burst
  
  OpenTricks_AutoMiniBoost(player, burst_t)
  
  local dsone = K_GetKartDriftSparkValue(player)
  local dstwo = dsone * 2
  local dsthree = dstwo * 2
  
  if burst_t.storage or burst_t.charge
    if player.speed >= mobj.scale * 10 -- hide visuals at low speeds.
      if player.kartstuff[k_driftcharge] > 0
        OpenTricks_MakeBurstRing(player, SKINCOLOR_FLAME)
      else
        OpenTricks_MakeBurstRing(player, SKINCOLOR_RED)
      end
    end
  else
    burst_t.first_burst = true
  end
  
  if (player.kartstuff[k_driftcharge] and burst_t.storage and burst_t.charge < max_spent) -- transfer storage into charge if not capped)
    Burst_Charge(player, max_charge)
  elseif (burst_t.last_drift >= dsone) and burst_t.charge and not player.kartstuff[k_driftcharge] -- use charge if drift charged
    Burst_Activate(player, min(max_spent, burst_t.charge))
  elseif not player.kartstuff[k_driftcharge] -- bleed storage and charge
    Burst_Bleed(player, idle_bleed)
  end

  burst_t.last_drift = player.kartstuff[k_driftcharge]
end

local function Burst_Landing(player)
  local mobj = player.mo
  local burst_t = player.OpenTricks.Burst
  S_StartSound(mobj, sfx_s23c)
  player.OpenTricks.Burst.storage = $ + (1500 * player.OpenTricks.combo)
  player.OpenTricks.Burst.mini = $ + TICRATE
  
  if burst_t.storage > max_burst -- storage over cap immediately turns into charge at a 1:5 rate
    burst_t.charge = min(max_spent, $ + ((burst_t.storage - max_burst)/5))
	burst_t.storage = max_burst
  end
end

OPENTRICKS_ADD_FOURICONS("burst", "drift to burst forward", "TRXTGN7", "TRXTGN8", "TRXTGN8", "TRXTGN18", false, Burst_Initialize, Burst_Thinker, nil, Burst_Landing)

local function Burst_Drawer(othud, player, cam)
  if not player.OpenTricks or not OpenTricks_Table
    return
  elseif OpenTricks_GetRange(player, false) == 0
    return
  elseif not player.OpenTricks.Burst
    return
  elseif player.OpenTricks.key ~= "burst"
    return
  elseif OpenTricks_CanSelect(player)
    return
  end
  
  local icon_x, icon_y = OR_GetOTricksIconCoords(cam)
  
  local burst_text = (player.OpenTricks.Burst.storage * 100)/max_burst
  local burst_charge = (player.OpenTricks.Burst.charge * 100)/max_spent
  
  local burst_x = othud.stringWidth(burst_text .. "/" .. burst_charge, V_20TRANS, "thin")
  othud.drawString(icon_x - (burst_x/2), icon_y - 4, "\x85" .. burst_text .. "\x8D/" .. burst_charge, V_HUDTRANS, "thin")
end

hud.add(Burst_Drawer)