-- we need our own weapon switcher because the hl2 one skips empty weapons

local math = math
local draw = draw
local surface = surface
local table = table

WSWITCH = {}

WSWITCH.Show = false
WSWITCH.Selected = -1
WSWITCH.NextSwitch = -1
WSWITCH.WeaponCache = {}

WSWITCH.cv = {}
WSWITCH.cv.stay = CreateConVar("ttt_weaponswitcher_stay", "0", FCVAR_ARCHIVE)
WSWITCH.cv.fast = CreateConVar("ttt_weaponswitcher_fast", "0", FCVAR_ARCHIVE)
WSWITCH.cv.display = CreateConVar("ttt_weaponswitcher_displayfast", "0", FVCAR_ARCHIVE)

local delay = 0.075
local showtime = 3

local margin = 10
local width = 300
local height = 20





-- Draw a bar in the style of the the weapon pickup ones
local round = math.Round



local bgblack_d = bgwhite_d

local col_active = {
   bg = colormode.fontcolor,
   text = colormode.background,
};

local col_dark = {
   bg = colormode.darkfontc,
   text = colormode.background,
};

function WSWITCH:DrawBarBg(x, y, w, h, col)


   local rx = round(x - 4)
   local ry = round(y - (h / 2)-4)
   local rw = round(w + 9)
   local rh = round(h + 8)

   local b = 0 --bordersize
   local bh = b / 2

   local role = LocalPlayer():GetRole() or ROLE_INNOCENT



   -- Draw the colour tip
   draw.RoundedBox( 2, rx+b+h-4, ry, rw - (h - 4) - b*2, rh, bottomcolor)
      draw.RoundedBox( 2, rx+b+h-4, ry, rw - (h - 4) - b*2, rh / 2, uppercolor, true, true, false, false)
   draw.RoundedBox( 2, rx, ry+b, rh-b*2, rh-b*2, statecolor  )
   draw.RoundedBoxEx( 2, rx, ry+b + rh / 2 , rh-b*2, (rh-b*2) / 2, Color(0, 0, 0, 40) , false, false, true, true )
end

local TryTranslation = LANG.TryTranslation
function WSWITCH:DrawWeapon(x, y, c, wep)
   if not IsValid(wep) then return false end

   local name = TryTranslation(wep:GetPrintName() or wep.PrintName or "...")
   local cl1, am1 = wep:Clip1(), wep:Ammo1()
   local ammo = false

   -- Clip1 will be -1 if a melee weapon
   -- Ammo1 will be false if weapon has no owner (was just dropped)
   if cl1 != -1 and am1 != false then
      ammo = Format("%i + %02i", cl1, am1)
   end

   -- Slot
   local spec = {text=wep.Slot+1, font="New_font", pos={x + 3, y}, yalign=TEXT_ALIGN_CENTER, color=c.bg}
   local spec2 = {text=wep.Slot+1, font="New_font", pos={x + 4, y + 1}, yalign=TEXT_ALIGN_CENTER, color=shadowcolor}
   draw.Text(spec2)
   draw.Text(spec)

	local spec = {text=wep.Slot+1, font="New_font", pos={x + 3, y}, yalign=TEXT_ALIGN_CENTER, color=c.bg}
	local spec2 = {text=wep.Slot+1, font="New_font", pos={x + 4, y + 1}, yalign=TEXT_ALIGN_CENTER, color=shadowcolor}
   -- Name
   spec.text  = name
   spec.font  = "New_font"
   spec.pos[1] = x + 10 + height
   spec2.text  = name
   spec2.font  = "New_font"
   spec2.pos[1] = x + 10 + height + 1
   draw.Text(spec2)
   draw.Text(spec)

   if ammo then
      local col = c.bg

      if wep:Clip1() == 0 and wep:Ammo1() == 0 then
         col = c.text_empty
      end

      -- Ammo
      spec.text   = ammo
      spec.pos[1] = ScrW() - margin*3
      spec.xalign = TEXT_ALIGN_RIGHT
      spec.color  = col
	  spec2.text   = ammo
      spec2.pos[1] = ScrW() - margin*3 + 1
      spec2.xalign = TEXT_ALIGN_RIGHT
      spec2.color  = shadowcolor
	  draw.Text(spec2)
      draw.Text(spec)

   end

   return true
end

function WSWITCH:Draw(client)
shadowcolor = colormode.shadowcolor
 background  = colormode.background
 ammocolor   = colormode.ammocolor
 staminacolor         = colormode.staminacolor
 fontcolor    		 = 	colormode.fontcolor
 darkfontc		 	 = 	colormode.darkfontc
 notificationfontc    =    colormode.notificationfontc
if GAMEMODE.round_state != ROUND_ACTIVE then
 pic = colormode["wait"]["wicon"]
 uppercolor = colormode["wait"]["wuppercolor"]
 bottomcolor = colormode["wait"]["wbottomcolor"]
 statecolor = colormode["wait"]["wstatecolor"]
	elseif LocalPlayer():GetTraitor() then
		pic = colormode["traitor"]["ticon"]
		uppercolor = colormode["traitor"]["tuppercolor"]
		bottomcolor = colormode["traitor"]["tbottomcolor"]
		statecolor = colormode["traitor"]["tstatecolor"]
	elseif LocalPlayer():GetDetective() then
		pic = colormode["detective"]["dicon"]
		uppercolor = colormode["detective"]["duppercolor"]
		bottomcolor = colormode["detective"]["dbottomcolor"]
		statecolor = colormode["detective"]["dstatecolor"]
	else 
		pic = colormode["innocent"]["iicon"]
		uppercolor = colormode["innocent"]["iuppercolor"]
		bottomcolor = colormode["innocent"]["ibottomcolor"]
		statecolor = colormode["innocent"]["istatecolor"]
end

   if not self.Show then return end

   local weps = self.WeaponCache

   local x = ScrW() - width - margin*2
   local y = ScrH() - (#weps * (height + margin))

   local col = col_dark
   for k, wep in pairs(weps) do
      if self.Selected == k then
         col = col_active
      else
         col = col_dark
      end

      self:DrawBarBg(x, y, width, height, col)
      if not self:DrawWeapon(x, y, col, wep) then
         
         self:UpdateWeaponCache()
         return
      end

      y = y + height + margin
   end
end

local function SlotSort(a, b)
   return a and b and a.Slot and b.Slot and a.Slot < b.Slot
end

local function CopyVals(src, dest)
   table.Empty(dest)
   for k, v in pairs(src) do
      if IsValid(v) then
         table.insert(dest, v)
      end
   end   
end

function WSWITCH:UpdateWeaponCache()
   -- GetWeapons does not always return a proper numeric table it seems
   --   self.WeaponCache = LocalPlayer():GetWeapons()
   -- So copy over the weapon refs
   self.WeaponCache = {}
   CopyVals(LocalPlayer():GetWeapons(), self.WeaponCache)

   table.sort(self.WeaponCache, SlotSort)
end

function WSWITCH:SetSelected(idx)
   self.Selected = idx

   self:UpdateWeaponCache()
end

function WSWITCH:SelectNext()
   if self.NextSwitch > CurTime() then return end
   self:Enable()

   local s = self.Selected + 1
   if s > #self.WeaponCache then
      s = 1
   end

   self:DoSelect(s)

   self.NextSwitch = CurTime() + delay
end

function WSWITCH:SelectPrev()
   if self.NextSwitch > CurTime() then return end
   self:Enable()

   local s = self.Selected - 1
   if s < 1 then
      s = #self.WeaponCache
   end

   self:DoSelect(s)

   self.NextSwitch = CurTime() + delay
end

-- Select by index
function WSWITCH:DoSelect(idx)
   self:SetSelected(idx)

   if self.cv.fast:GetBool() then
      -- immediately confirm if fastswitch is on
      self:ConfirmSelection(self.cv.display:GetBool())
   end   
end

-- Numeric key access to direct slots
function WSWITCH:SelectSlot(slot)
   if not slot then return end

   self:Enable()

   self:UpdateWeaponCache()

   slot = slot - 1

   -- find which idx in the weapon table has the slot we want
   local toselect = self.Selected
   for k, w in pairs(self.WeaponCache) do
      if w.Slot == slot then
         toselect = k
         break
      end
   end

   self:DoSelect(toselect)

   self.NextSwitch = CurTime() + delay
end

-- Show the weapon switcher
function WSWITCH:Enable()
   if self.Show == false then
      self.Show = true

      local wep_active = LocalPlayer():GetActiveWeapon()

      self:UpdateWeaponCache()

      -- make our active weapon the initial selection
      local toselect = 1
      for k, w in pairs(self.WeaponCache) do
         if w == wep_active then
            toselect = k
            break
         end
      end
      self:SetSelected(toselect)
   end

   -- cache for speed, checked every Think
   self.Stay = self.cv.stay:GetBool()
end

-- Hide switcher
function WSWITCH:Disable()
   self.Show = false
end

-- Switch to the currently selected weapon
function WSWITCH:ConfirmSelection(noHide)
   if not noHide then self:Disable() end

   for k, w in pairs(self.WeaponCache) do
      if k == self.Selected and IsValid(w) then
         RunConsoleCommand("wepswitch", w:GetClass())
         return
      end
   end   
end

-- Allow for suppression of the attack command
function WSWITCH:PreventAttack()
   return self.Show and !self.cv.fast:GetBool()
end

function WSWITCH:Think()
   if (not self.Show) or self.Stay then return end

   -- hide after period of inaction
   if self.NextSwitch < (CurTime() - showtime) then
      self:Disable()
   end
end

-- Instantly select a slot and switch to it, without spending time in menu
function WSWITCH:SelectAndConfirm(slot)
   if not slot then return end
   WSWITCH:SelectSlot(slot)
   WSWITCH:ConfirmSelection()
end

local function QuickSlot(ply, cmd, args)
   if (not IsValid(ply)) or (not args) or #args != 1 then return end

   local slot = tonumber(args[1])
   if not slot then return end

   local wep = ply:GetActiveWeapon()
   if IsValid(wep) then
      if wep.Slot == (slot - 1) then
         RunConsoleCommand("lastinv")
      else
         WSWITCH:SelectAndConfirm(slot)
      end
   end   
end
concommand.Add("ttt_quickslot", QuickSlot)


local function SwitchToEquipment(ply, cmd, args)
   RunConsoleCommand("ttt_quickslot", tostring(7))
end
concommand.Add("ttt_equipswitch", SwitchToEquipment)