---@diagnostic disable: param-type-mismatch
vx.markers = {}

local defaultRotation = vector3(0, 0, 0)
local defaultDirection = vector3(0, 0, 0)
local defaultColor = { r = 255, g = 255, b = 255, a = 100 }
local defaultSize = { width = 2, height = 1 }
local defaultRotate = false

local markerTypesMap = {
   UpsideDownCone = 0,
   VerticalCylinder = 1,
   ThickChevronUp = 2,
   ThinChevronUp = 3,
   CheckeredFlagRect = 4,
   CheckeredFlagCircle = 5,
   VerticleCircle = 6,
   PlaneModel = 7,
   LostMCTransparent = 8,
   LostMC = 9,
   Number0 = 10,
   Number1 = 11,
   Number2 = 12,
   Number3 = 13,
   Number4 = 14,
   Number5 = 15,
   Number6 = 16,
   Number7 = 17,
   Number8 = 18,
   Number9 = 19,
   ChevronUpx1 = 20,
   ChevronUpx2 = 21,
   ChevronUpx3 = 22,
   HorizontalCircleFat = 23,
   ReplayIcon = 24,
   HorizontalCircleSkinny = 25,
   HorizontalCircleSkinny_Arrow = 26,
   HorizontalSplitArrowCircle = 27,
   DebugSphere = 28,
   DollarSign = 29,
   HorizontalBars = 30,
   WolfHead = 31,
   QuestionMark = 32,
   PlaneSymbol = 33,
   HelicopterSymbol = 34,
   BoatSymbol = 35,
   CarSymbol = 36,
   MotorcycleSymbol = 37,
   BikeSymbol = 38,
   TruckSymbol = 39,
   ParachuteSymbol = 40,
   Unknown41 = 41,
   SawbladeSymbol = 42,
   Unknown43 = 43,
}

---@alias MarkerTypeName
---| "UpsideDownCone"
---| "VerticalCylinder"
---| "ThickChevronUp"
---| "ThinChevronUp"
---| "CheckeredFlagRect"
---| "CheckeredFlagCircle"
---| "VerticleCircle"
---| "PlaneModel"
---| "LostMCTransparent"
---| "LostMC"
---| "Number0"
---| "Number1"
---| "Number2"
---| "Number3"
---| "Number4"
---| "Number5"
---| "Number6"
---| "Number7"
---| "Number8"
---| "Number9"
---| "ChevronUpx1"
---| "ChevronUpx2"
---| "ChevronUpx3"
---| "HorizontalCircleFat"
---| "ReplayIcon"
---| "HorizontalCircleSkinny"
---| "HorizontalCircleSkinny_Arrow"
---| "HorizontalSplitArrowCircle"
---| "DebugSphere"
---| "DollarSign"
---| "HorizontalBars"
---| "WolfHead"
---| "QuestionMark"
---| "PlaneSymbol"
---| "HelicopterSymbol"
---| "BoatSymbol"
---| "CarSymbol"
---| "MotorcycleSymbol"
---| "BikeSymbol"
---| "TruckSymbol"
---| "ParachuteSymbol"
---| "Unknown41"
---| "SawbladeSymbol"
---| "Unknown43"

---@class MarkerProperties
---@field type MarkerTypeName | number
---@field coords { x: number, y: number, z: number } | vector3
---@field color? { r: number, g: number, b: number, a: number }
---@field rotation? { x: number, y: number, z: number } | vector3
---@field direction? { x: number, y: number, z: number } | vector3
---@field rotate? boolean
---@field width? number
---@field height? number

---@param self MarkerProperties
local function drawMarker(self)
   DrawMarker(
      self.type,
      self.coords.x, self.coords.y, self.coords.z,
      self.direction.x, self.direction.y, self.direction.z,
      self.rotation.x, self.rotation.y, self.rotation.z,
      self.width, self.width, self.height,
      self.color.r, self.color.g, self.color.b, self.color.a,
      false, true, 2, self.rotate, nil, nil, false)
end

---@param options MarkerProperties
function vx.markers.new(options)
   local markerType
   if type(options.type) == "string" then
      markerType = markerTypesMap[options.type]
      if markerType == nil then
         error(("unknown marker type '%s'"):format(options.type))
      end
   elseif type(options.type) == "number" then
      markerType = options.type
   else
      error(("expected marker type to have type 'string' or 'number' (received %s)"):format(type(options.type)))
   end

   local self = {}
   self.type = markerType
   self.coords = options.coords
   self.color = options.color or defaultColor
   self.rotation = options.rotation or defaultRotation
   self.direction = options.direction or defaultDirection
   self.height = options.height or defaultSize.height
   self.width = options.width or defaultSize.width
   self.rotate = options.rotate or defaultRotate

   self.draw = drawMarker

   self.width += 0.0
   self.height += 0.0

   return self
end

return vx.markers
