local P=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\116\097\108\101\110\116\115")local E=require("\112\108\046\099\108\097\115\115")local C=require("\109\111\115\101\115")local u=E()local F=8 local Z="\094\065\098\105\108\105\116\121\040\037\100\043\041\036"function u._init(u,P,E)local F=C.extend({},{Name=P},E)C.extend(u,F)u.__data=F end function u.Serialize(P)return P.__data end function u.Entries(P)return pairs(P:Serialize())end local function r(P,E)local C=P:match(Z)if C~=nil and E~=""then return tonumber(C),E end return nil,nil end function u.Abilities(P)if P.abilities==nil then P.abilities=C.map(P:Serialize(),C.rearg(r,{2,1}))end return P.abilities end function u.Talents(E)if E.talents==nil then local u=E.AbilityTalentStart local Z=(u+F)-1 local r=(((C.chain(E:Abilities())):slice(u,Z)):compact()):value()E.talents=P.NamesArrayToEnumsTable(r)end return E.talents end return u
--- HeroKeyValues class.
-- @classmod invokation.dota2.kv.HeroKeyValues
local Talents = require("invokation.dota2.talents")
local class = require("pl.class")
local m = require("moses")

local M = class()

local MAX_TALENTS_COUNT = 8
local ABILITY_KEY_PATT = "^Ability(%d+)$"

--- Constructor.
-- @tparam string name Hero name
-- @tparam {[string]=any,...} kv KeyValues data
function M:_init(name, kv)
  local fields = m.extend({}, { Name = name }, kv)

  m.extend(self, fields)

  self.__data = fields
end

--- Serializes the KeyValues data
-- @treturn {[string]=any,...} Serialized data
function M:Serialize()
  return self.__data
end

--- Returns an iterator function that iterates over the KeyValues entries.
-- @treturn iter(string,any)
function M:Entries()
  return pairs(self:Serialize())
end

local function selectAbilityEntry(key, value)
  local mAbilityId = key:match(ABILITY_KEY_PATT)

  if mAbilityId ~= nil and value ~= "" then
    return tonumber(mAbilityId), value
  end

  return nil, nil
end

--- Returns an array of ability names.
-- @treturn {string,...} Array of ability names
function M:Abilities()
  if self.abilities == nil then
    self.abilities = m.map(self:Serialize(), m.rearg(selectAbilityEntry, { 2, 1 }))
  end

  return self.abilities
end

--- Returns an array of talent ability names.
-- @treturn talents.Talents Table of talent ability names
function M:Talents()
  if self.talents == nil then
    local start = self.AbilityTalentStart
    local finish = start + MAX_TALENTS_COUNT - 1
    local abilities = m.chain(self:Abilities()):slice(start, finish):compact():value()

    self.talents = Talents.NamesArrayToEnumsTable(abilities)
  end

  return self.talents
end

return M
