-- Bundled by luabundle {"version":"1.6.0"}
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
	local loadingPlaceholder = {[{}] = true}

	local register
	local modules = {}

	local require
	local loaded = {}

	register = function(name, body)
		if not modules[name] then
			modules[name] = body
		end
	end

	require = function(name)
		local loadedModule = loaded[name]

		if loadedModule then
			if loadedModule == loadingPlaceholder then
				return nil
			end
		else
			if not modules[name] then
				if not superRequire then
					local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
					error('Tried to require ' .. identifier .. ', but no such module has been registered')
				else
					return superRequire(name)
				end
			end

			loaded[name] = loadingPlaceholder
			loadedModule = modules[name](require, loaded, register, modules)
			loaded[name] = loadedModule
		end

		return loadedModule
	end

	return require, loaded, register, modules
end)(nil)
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
require("accessories/SearchAssistant")
end)
__bundle_register("accessories/SearchAssistant", function(require, _LOADED, __bundle_register, __bundle_modules)
local playmatAPI = require("playermat/PlaymatApi")

-- forward declaration of variables that are used across functions
local matColor
local setAsidePosition
local setAsideRotation
local drawDeckPosition

local quickParameters          = {}
quickParameters.function_owner = self
quickParameters.font_size      = 165
quickParameters.width          = 275
quickParameters.height         = 275
quickParameters.color          = "White"

-- common parameters
local buttonParameters          = {}
buttonParameters.function_owner = self
buttonParameters.font_size      = 125
buttonParameters.width          = 650
buttonParameters.height         = 225
buttonParameters.color          = "White"

local inputParameters          = {}
inputParameters.function_owner = self
inputParameters.input_function = "updateSearchNumber"
inputParameters.tooltip        = "custom search amount"
inputParameters.label          = "#"
inputParameters.font_size      = 175
inputParameters.width          = 400
inputParameters.height         = inputParameters.font_size + 23
inputParameters.position       = { 0, 0.11, 0 }
inputParameters.alignment      = 3
inputParameters.validation     = 2

function onLoad()
  normalView()
end

-- regular view with search box
function normalView()
  self.clearButtons()
  self.clearInputs()
  self.createInput(inputParameters)

  -- create custom search button
  buttonParameters.click_function = "searchCustom"
  buttonParameters.tooltip        = "Search the entered number of cards"
  buttonParameters.position       = { 0, 0.11, 0.65 }
  buttonParameters.label          = "Search"
  self.createButton(buttonParameters)

  -- create buttons to search 3, 6 or 9 cards
  quickParameters.click_function = "search3"
  quickParameters.label          = "3"
  quickParameters.position       = { -0.65, 0.11, -0.65 }
  self.createButton(quickParameters)

  quickParameters.click_function = "search6"
  quickParameters.label          = "6"
  quickParameters.position       = { 0, 0.11, -0.65 }
  self.createButton(quickParameters)

  quickParameters.click_function = "search9"
  quickParameters.label          = "9"
  quickParameters.position       = { 0.65, 0.11, -0.65 }
  self.createButton(quickParameters)
end

-- click functions
function search3(_, playerColor) startSearch(playerColor, 3) end
function search6(_, playerColor) startSearch(playerColor, 6) end
function search9(_, playerColor) startSearch(playerColor, 9) end

-- view during a search with "done" buttons
function searchView()
  self.clearButtons()
  self.clearInputs()

  -- create the "End Search" button
  buttonParameters.click_function = "endSearch"
  buttonParameters.tooltip        = "Left-click: Return cards and shuffle\nRight-click: Return cards without shuffling"
  buttonParameters.position       = { 0, 0.11, 0 }
  buttonParameters.label          = "End Search"
  self.createButton(buttonParameters)
end

-- input_function to get number of cards to search
function updateSearchNumber(_, _, input)
  inputParameters.value = tonumber(input)
end

-- starts the search with the number from the input field
function searchCustom(_, messageColor)
  local number = inputParameters.value
  if number ~= nil then
    startSearch(messageColor, number)
  else
    printToColor("Enter the number of cards to search in the textbox.", messageColor, "Orange")
  end
end

-- start the search (change UI, set handCards aside, draw cards)
function startSearch(messageColor, number)
  matColor = playmatAPI.getMatColorByPosition(self.getPosition())

  -- get draw deck
  local drawDeck = playmatAPI.getDrawDeck(matColor)
  if drawDeck == nil then
    printToColor(matColor .. " draw deck could not be found!", messageColor, "Red")
    return
  end

  drawDeckPosition = drawDeck.getPosition()
  printToColor("Place target(s) of search on set aside hand.", messageColor, "Green")

  -- get playmat orientation
  local offset = -15
  if matColor == "Orange" or matColor == "Red" then
    offset = 15
  end

  -- get position and rotation for set aside cards
  local handData   = Player[matColor].getHandTransform()
  local handCards  = Player[matColor].getHandObjects()
  setAsidePosition = handData.position + offset * handData.right
  setAsideRotation = { handData.rotation.x, handData.rotation.y + 180, 180 }

  for i = #handCards, 1, -1 do
    handCards[i].setPosition(setAsidePosition - Vector(0, i * 0.3, 0))
    handCards[i].setRotation(setAsideRotation)
  end

  -- handling for Norman Withers
  for _, v in ipairs(searchArea(drawDeckPosition)) do
    local object = v.hit_object
    if object.tag == "Card" and not object.is_face_down then
      object.flip()
      Wait.time(function() drawDeck = playmatAPI.getDrawDeck(matColor) end, 1)
      break
    end
  end

  Wait.time(function() drawDeck.deal(number, matColor) end, 1)
  searchView()
end

-- place handCards back into deck and optionally shuffle
function endSearch(_, _, isRightClick)
  local handCards = Player[matColor].getHandObjects()

  for i = #handCards, 1, -1 do
    handCards[i].setPosition(drawDeckPosition + Vector(0, 6 - i * 0.3, 0))
    handCards[i].setRotation(setAsideRotation)
  end

  if not isRightClick then
    Wait.time(function()
      local deck = playmatAPI.getDrawDeck(matColor)
      if deck ~= nil then
        deck.shuffle()
      end
    end, 2)
  end

  -- draw set aside cards (from the ground!)
  for _, v in ipairs(searchArea(setAsidePosition - Vector(0, 5, 0))) do
    local obj = v.hit_object
    if obj.tag == "Deck" then
      Wait.time(function()
        obj.deal(#obj.getObjects(), matColor)
      end, 1)
      break
    elseif obj.tag == "Card" then
      obj.setPosition(Player[matColor].getHandTransform().position)
      obj.flip()
      break
    end
  end

  normalView()
end

-- utility function
function searchArea(position)
  return Physics.cast({
    origin = position,
    direction = { 0, 1, 0 },
    type = 3,
    size = { 2, 2, 2 },
    max_distance = 0
  })
end
end)
__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
do
  local PlaymatApi = { }
  local internal = { }

  local MAT_IDS = {
    White  = "8b081b",
    Orange = "bd0ff4",
    Green  = "383d8b",
    Red    = "0840d5"
  }

  local CLUE_COUNTER_GUIDS = {
    White  = "37be78",
    Orange = "1769ed",
    Green  = "032300",
    Red    = "d86b7c"
  }

  local CLUE_CLICKER_GUIDS = {
    White  = "db85d6",
    Orange = "3f22e5",
    Green  = "891403",
    Red    = "4111de"
  }

  -- Returns the color of the by position requested playermat as string
  ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat
  PlaymatApi.getMatColorByPosition = function(startPos)
    if startPos.x < -42 then
      if startPos.z > 0 then
        return "White"
      else
        return "Orange"
      end
    else
      if startPos.z > 0 then
        return "Green"
      else
        return "Red"
      end
    end
  end

  -- Returns the draw deck of the requested playmat
  ---@param matColor String Color of the playermat
  PlaymatApi.getDrawDeck = function(matColor)
    local mat = getObjectFromGUID(MAT_IDS[matColor])
    mat.call("getDrawDiscardDecks")
    return mat.getVar("drawDeck")
  end

  -- Returns the position of the discard pile of the requested playmat
  ---@param matColor String Color of the playermat
  PlaymatApi.getDiscardPosition = function(matColor)
    local mat = getObjectFromGUID(MAT_IDS[matColor])
    return mat.call("returnGlobalDiscardPosition")
  end

  -- Sets the requested playermat's snap points to limit snapping to matching card types or not.  If
  -- matchTypes is true, the main card slot snap points will only snap assets, while the
  -- investigator area point will only snap Investigators.  If matchTypes is false, snap points will
  -- be reset to snap all cards.
  ---@param matchCardTypes Boolean.  Whether snap points should only snap for the matching card
  --     types.
  ---@param matColor String for one of the active player colors - White, Orange, Green, Red.  Also
  --     accepts "All" as a special value which will apply the setting to all four mats.
  PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
    for _, mat in ipairs(internal.getMatForColor(matColor)) do
      mat.call("setLimitSnapsByType", matchCardTypes)
    end
  end

  -- Sets the requested playermat's draw 1 button to visible
  ---@param isDrawButtonVisible Boolean.  Whether the draw 1 button should be visible or not
  ---@param matColor String for one of the active player colors - White, Orange, Green, Red.  Also
  --     accepts "All" as a special value which will apply the setting to all four mats.
  PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor)
    for _, mat in ipairs(internal.getMatForColor(matColor)) do
      mat.call("showDrawButton", isDrawButtonVisible)
    end
  end

  -- Shows or hides the clickable clue counter for the requested playermat
  ---@param showCounter Boolean.  Whether the clickable counter should be present or not
  ---@param matColor String for one of the active player colors - White, Orange, Green, Red.  Also
  --     accepts "All" as a special value which will apply the setting to all four mats.
  PlaymatApi.clickableClues = function(showCounter, matColor)
    for _, mat in ipairs(internal.getMatForColor(matColor)) do
      mat.call("clickableClues", showCounter)
    end
  end

  -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat
  ---@param matColor String for one of the active player colors - White, Orange, Green, Red.  Also
  --     accepts "All" as a special value which will apply the setting to all four mats.
  PlaymatApi.removeClues = function(matColor)
    for _, mat in ipairs(internal.getMatForColor(matColor)) do
      mat.call("removeClues")
    end
  end

  -- Reports the clue count for the requested playermat
  ---@param useClickableCounters Boolean Controls which type of counter is getting checked
  PlaymatApi.getClueCount = function(useClickableCounters, matColor)
    local count = 0
    for _, mat in ipairs(internal.getMatForColor(matColor)) do
      count = count + tonumber(mat.call("getClueCount", useClickableCounters))
    end
    return count
  end

  -- Convenience function to look up a mat's object by color, or get all mats.
  ---@param matColor String for one of the active player colors - White, Orange, Green, Red.  Also
  --     accepts "All" as a special value which will return all four mats.
  ---@return: Array of playermat objects.  If a single mat is requested, will return a single-element
  --     array to simplify processing by consumers.
  internal.getMatForColor = function(matColor)
    local targetMatGuid = MAT_IDS[matColor]
    if targetMatGuid != nil then
      return { getObjectFromGUID(targetMatGuid) }
    end
    if matColor == "All" then
      return {
        getObjectFromGUID(MAT_IDS.White),
        getObjectFromGUID(MAT_IDS.Orange),
        getObjectFromGUID(MAT_IDS.Green),
        getObjectFromGUID(MAT_IDS.Red),
      }
    end
  end

  return PlaymatApi
end
end)
return __bundle_require("__root")