-- table extensions

local expect = require("Assets/Cutscenes/RotationCollab/expect")
local tablex = {}


function tablex.find(tab, value)
  expect(1, tab, "table")
  for i, v in pairs(tab) do
    if v == value then return i end
  end
  return nil
end


function tablex.filter(tab, func)
  expect(1, tab, "table")
  expect(2, func, "function")
  local out = {}
  for k, v in pairs(tab) do
    if func(v, k, tab) then table.insert(out, v) end
  end
  return out
end

function tablex.filterk(tab, func)
  expect(1, tab, "table")
  expect(2, func, "function")
  local out = {}
  for k, v in pairs(tab) do
    if func(v, k, tab) then out[k] = v end
  end
  return out
end


function tablex.fold(tab, default, func)
  expect(1, tab, "table")
  expect(3, func, "function")
  local val = default
  for k, v in ipairs(tab) do
    val = func(v, k, val, tab)
  end
  return val
end

function tablex.count(tab, func)
  expect(1, tab, "table")
  expect(2, func, "function")
  local n = 0
  for k, v in pairs(tab) do
    if func(v, k, n, tab) then n = n + 1 end
  end
  return n
end


function tablex.any(tab, func)
  expect(1, tab, "table")
  expect(2, func, "function")
  for k, v in pairs(tab) do
    if func(v, k, tab) then return true end
  end
  return false
end

function tablex.all(tab, func)
  expect(1, tab, "table")
  expect(2, func, "function")
  for k, v in pairs(tab) do
    if not func(v, k, tab) then return false end
  end
  return true
end


function tablex.keys(tab)
  expect(1, tab, "table")
  local keys = {}
  for key, _ in pairs(tab) do
    table.insert(keys, key)
  end
  return keys
end


function tablex.apply(...)
  local out = {}
  for i, tab in ipairs({...}) do
    expect(1, tab, "table")
    for k, v in pairs(tab) do out[k] = v end
  end
  return out
end


return tablex
