local FormationData = class("FormationData", BaseData)

function FormationData:ctor()
	self.data.dirty = false
	self.formations = {}
end

-- 初始化主线阵容
function FormationData:init(data)
	if self.formations == nil then
		self.formations = {}
	end

	if data and data.heroes then
		local clientFormation = {}
		for matchType, heroId in pairs(data.heroes) do
			clientFormation[tonumber(matchType)] = heroId
		end
		self.formations[GConst.BattleConst.FORMATION_TYPE.STAGE] = clientFormation
	end
	self:setDirty()
end

-- 初始化竞技场阵容
function FormationData:initArena(attack, defend)
	if self.formations == nil then
		self.formations = {}
	end

	-- 位置顺序特殊处理
	self.formations[GConst.BattleConst.FORMATION_TYPE.ARENA_ATTACK] = {0,0,0,0,0}
	self.formations[GConst.BattleConst.FORMATION_TYPE.ARENA_DEFEND] = {0,0,0,0,0}

	for idx, id in pairs(attack) do
		if id and id ~= 0 then
			local type = DataManager.HeroData:getHeroById(id):getMatchType()
			self.formations[GConst.BattleConst.FORMATION_TYPE.ARENA_ATTACK][type] = id
		end
	end
	for idx, id in pairs(defend) do
		if id and id ~= 0 then
			local type = DataManager.HeroData:getHeroById(id):getMatchType()
			self.formations[GConst.BattleConst.FORMATION_TYPE.ARENA_DEFEND][type] = id
		end
	end
	self:setDirty()
end

function FormationData:initDungeonWeapon(heroes)
	if self.formations == nil then
		self.formations = {}
	end

	self.formations[GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON] = {}
	for idx, id in pairs(heroes) do
		if id and id ~= 0 then
			local matchType = DataManager.HeroData:getHeroById(id):getMatchType()
			self.formations[GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON][matchType] = id
		end
	end
end

function FormationData:initDungeonArmor(heroes)
	if self.formations == nil then
		self.formations = {}
	end

	self.formations[GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR] = {}
	for idx, id in pairs(heroes) do
		if id and id ~= 0 then
			local matchType = DataManager.HeroData:getHeroById(id):getMatchType()
			self.formations[GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR][matchType] = id
		end
	end
end

function FormationData:initFormationByType(formationType, heroes)
	if self.formations == nil then
		self.formations = {}
	end

	self.formations[formationType] = {}
	for idx, id in pairs(heroes) do
		if id and id ~= 0 then
			local matchType = DataManager.HeroData:getHeroById(id):getMatchType()
			self.formations[formationType][matchType] = id
		end
	end
end

function FormationData:getStageFormation()
	return self:getFormation(GConst.BattleConst.FORMATION_TYPE.STAGE)
end

function FormationData:getArenaAttackFormation()
	return self:getFormation(GConst.BattleConst.FORMATION_TYPE.ARENA_ATTACK)
end

function FormationData:getArenaDefendFormation()
	return self:getFormation(GConst.BattleConst.FORMATION_TYPE.ARENA_DEFEND)
end

function FormationData:getDungeonWeaponFormation()
	local formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON)
	if table.nums(formation) <= 0 then
		self:setFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON, self:getFormation(GConst.BattleConst.FORMATION_TYPE.STAGE)) -- 如果没有，则用默认关卡
		formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON)
	end
	return formation
end

function FormationData:getDungeonArmorFormation()
	local formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR)
	if table.nums(formation) <= 0 then
		self:setFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR, self:getFormation(GConst.BattleConst.FORMATION_TYPE.STAGE)) -- 如果没有，则用默认关卡
		formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR)
	end
	return formation
end

function FormationData:getBossRushFormation()
	local formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.BOSS_RUSH)
	if table.nums(formation) <= 0 then
		self:setFormation(GConst.BattleConst.FORMATION_TYPE.BOSS_RUSH, self:getFormation(GConst.BattleConst.FORMATION_TYPE.STAGE)) -- 如果没有，则用默认关卡
		formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.BOSS_RUSH)
	end
	return formation
end

function FormationData:getDungeonRuneFormation()
	local formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE)
	if table.nums(formation) <= 0 then
		self:setFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE, self:getFormation(GConst.BattleConst.FORMATION_TYPE.STAGE)) -- 如果没有，则用默认关卡
		formation = self:getFormation(GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE)
	end
	return formation
end

function FormationData:getFormation(formationType)
	local formation = self.formations[formationType]
	if formation == nil then
		formation = {}
		self.formations[formationType] = formation
	end
	return formation
end

function FormationData:setFormation(formationType, formation)
	self.formations[formationType] = GFunc.getTable(formation)
	self:setDirty()
end

function FormationData:upHeroToFormation(formationType, matchType, heroId)
	local formation = self:getFormation(formationType)
	if formation[matchType] == heroId then
		return
	end
	formation[matchType] = heroId
	self:setDirty()
end

function FormationData:heroInFormation(formationType, heroId)
	local formation = self:getFormation(formationType)
	if not formation then
		return false
	end
	for matchType, id in pairs(formation) do
		if id == heroId then
			return true
		end
	end

	return false
end

function FormationData:formationIsFull(formationType)
	local actvieMap = DataManager.HeroData:getMatchActiveHeroMap()
	local formation = self:getFormation(formationType)
	local count = 0
	for matchtype = 1, GConst.BattleConst.ELEMENT_TYPE_COUNT do
		if not formation[matchtype] or formation[matchtype] <= 0 then
			if actvieMap[matchtype] and table.nums(actvieMap[matchtype]) > 0 then
				return false
			end
		else
			count = count + 1
		end
	end

	if count <= 0 then
		return false
	end

	return true
end

function FormationData:setDirty()
	self.data.dirty = not self.data.dirty
end

function FormationData:getStageFormationBIStr()
	local str
	local totalLevel = 0
	local allAtk = 0
	local allHp = 0
	for matchType, heroId in pairs(self:getStageFormation()) do
		local entity = DataManager.HeroData:getHeroById(heroId)
		if entity then
			if str then
				str = str .. "|"
			else
				str = GConst.EMPTY_STRING
			end
			str = str .. heroId .. ":" .. entity:getLv()
			totalLevel = totalLevel + entity:getLv()
			allAtk = allAtk + entity:getAtk()
			allHp = allHp + entity:getHp()
		end
	end
	allAtk = allAtk // GConst.BattleConst.DEFAULT_FACTOR
	allHp = allHp // GConst.BattleConst.DEFAULT_FACTOR
	return str, totalLevel, allAtk, allHp
end

return FormationData