require("gui/WindowUtils")
require("GameUtils")
require("GameMath")

local GameCoreHelper = CS.GameCoreHelper

HeroAttributeSubWin = {
	curRole = nil,
	RefreshParentListCallback = nil,
	isShowInstBox = true,
}

HeroAttributeSubWin.meta = {__index = HeroAttributeSubWin}

local constValShowEquipCount = 4;

function HeroAttributeSubWin:Create()
	local tagClass = {}
    setmetatable(tagClass, self.meta)
    return tagClass
end

function HeroAttributeSubWin:Init(_tagComp, _showInstBox)
	self.mainView = _tagComp;

	self.ctlViewStyle = _tagComp:GetController("show_style");

	local groupRoleBox = _tagComp:GetChild("g_rolebox").asGroup;
	self.imgCurRoleHead = _tagComp:GetChildInGroup(groupRoleBox, "head_cliper"):GetChild("head_holder").asImage;
	self.equipSlots = {};
	for i = 0, constValShowEquipCount-1 do
		local tagBtn = _tagComp:GetChildInGroup(groupRoleBox, "equip_slot_"..i).asButton;
		local tagSlot = InitCommonItemSlot(tagBtn, i, 1, nil, true);
		tagSlot:SetDefaultItemIconPath(GetEquipSlotDefaultIconPath(i));
		self.equipSlots[i] = tagSlot;
	end
	self.txtRoleEquipType = _tagComp:GetChildInGroup(groupRoleBox, "weapon_limit").asTextField;

	self.expBarView = _tagComp:GetChildInGroup(groupRoleBox, "exp_bar").asCom;
	self.imgProgExp = self.expBarView:GetChild("exp_bar").asImage;
	self.txtExp = self.expBarView:GetChild("txt_exp").asTextField;
	self.lbLevel = _tagComp:GetChildInGroup(groupRoleBox, "lb_level").asLabel;
	self.lbFv = _tagComp:GetChildInGroup(groupRoleBox, "lb_repval").asLabel;

	self.groupDesc = _tagComp:GetChild("g_desc").asGroup;
	self.lvDescList = _tagComp:GetChildInGroup(self.groupDesc, "role_desclist").asList;

	self.playerRanksBox = _tagComp:GetChild("player_ranks").asCom;
	self.ctlFightRank = CreateRankTitleBox(self.playerRanksBox:GetChild("fight_stat").asCom);
	self.ctlNobleRank = CreateRankTitleBox(self.playerRanksBox:GetChild("noble_stat").asCom);

	local groupAttrBox = _tagComp:GetChild("g_attrboxs").asGroup;

	local tagStatBox = _tagComp:GetChildInGroup(groupAttrBox, "statbox_1").asLabel;
	local tagStatLv = tagStatBox:GetChild("stat_list").asList;
	tagStatLv.numItems = 6;
	local tagLb = tagStatLv:GetChildAt(0).asLabel;
	tagLb.title = GetGameString("lua_script_str_183");
	SetAttributeStatViewType(tagLb, 0, 0);
	self.lbHpMax = tagLb;
	tagLb = tagStatLv:GetChildAt(1).asLabel;
	tagLb.title = GetGameString("lua_script_str_184");
	SetAttributeStatViewType(tagLb, 0, 1);
	self.lbMpMax = tagLb;
	tagLb = tagStatLv:GetChildAt(2).asLabel;
	tagLb.title = GetGameString("lua_script_str_185");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbStrVal = tagLb;
	tagLb = tagStatLv:GetChildAt(3).asLabel;
	tagLb.title = GetGameString("lua_script_str_186");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbAgiVal = tagLb;
	tagLb = tagStatLv:GetChildAt(4).asLabel;
	tagLb.title = GetGameString("lua_script_str_187");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbSprVal = tagLb;
	tagLb = tagStatLv:GetChildAt(5).asLabel;
	tagLb.title = GetGameString("lua_script_str_188");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbStmVal = tagLb;

	tagStatBox = _tagComp:GetChildInGroup(groupAttrBox, "statbox_2").asLabel;
	tagStatLv = tagStatBox:GetChild("stat_list").asList;
	tagStatLv.numItems = 5;
	tagLb = tagStatLv:GetChildAt(0).asLabel;
	tagLb.title = GetGameString("lua_script_str_189");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbPhyAtk = tagLb;
	tagLb = tagStatLv:GetChildAt(1).asLabel;
	tagLb.title = GetGameString("lua_script_str_190");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbMagAtk = tagLb;
	tagLb = tagStatLv:GetChildAt(2).asLabel;
	tagLb.title = GetGameString("lua_script_str_191");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbPhyDef = tagLb;
	tagLb = tagStatLv:GetChildAt(3).asLabel;
	tagLb.title = GetGameString("lua_script_str_192");
	SetAttributeStatViewType(tagLb, 0, 2);
	self.lbMagDef = tagLb;
	tagLb = tagStatLv:GetChildAt(4).asLabel;
	tagLb.title = GetGameString("lua_script_str_193");
	SetAttributeStatViewType(tagLb, 1, 0);
	self.lbMagTalent = tagLb;

	tagStatBox = _tagComp:GetChildInGroup(groupAttrBox, "statbox_3").asLabel;
	tagStatLv = tagStatBox:GetChild("stat_list").asList;
	tagStatLv.numItems = 5;

	tagLb = tagStatLv:GetChildAt(0).asLabel;
	tagLb.title = GetGameString("lua_script_xsth_cri");
	SetAttributeStatViewType(tagLb, 1, 0);
	self.lbMoveSpeed = tagLb;

	tagLb = tagStatLv:GetChildAt(1).asLabel;
	tagLb.title = GetGameString("lua_script_xsth_dodge");
	SetAttributeStatViewType(tagLb, 1, 0);
	self.lbAtkRange = tagLb;

	tagLb = tagStatLv:GetChildAt(2).asLabel;
	tagLb.title = GetGameString("lua_script_str_195");
	SetAttributeStatViewType(tagLb, 1, 0);
	self.lbAtkSpeed = tagLb;

	tagLb = tagStatLv:GetChildAt(3).asLabel;
	tagLb.title = GetGameString("lua_script_str_197");
	SetAttributeStatViewType(tagLb, 0, 0);
	self.lbHpRes = tagLb;

	tagLb = tagStatLv:GetChildAt(4).asLabel;
	tagLb.title = GetGameString("lua_script_str_198");
	SetAttributeStatViewType(tagLb, 0, 1);
	self.lbMpRes = tagLb;

	tagStatBox = _tagComp:GetChildInGroup(groupAttrBox, "statbox_4").asLabel;
	tagStatLv = tagStatBox:GetChild("stat_list").asList;
	tagStatLv.numItems = 0;
	
	self.lvSkills = _tagComp:GetChildInGroup(groupAttrBox, "skill_list").asList;
	self.cmdSkillBox = tagStatBox;

	self.instBox = _tagComp:GetChild("instruct_box").asCom;
	self.lvInsTabs = self.instBox:GetChild("tab_list").asList;
	self.ctlInstTabs = InitPartyInstruceBox(self.lvInsTabs);
	self.isShowInstBox = _showInstBox;
	if _showInstBox then
		self.instBox.visible = true;
		self.ctlInstTabs:SetSelectChangeCallback(function(_tagKey)
			local _setInst = math.floor(tonumber(_tagKey));
			GameCoreHelper.SetGroupDefInstruct(self.curRole.BindCard:GetPartyGroupNo(), _setInst);
		end);
	else
		self.instBox.visible = false;
	end

	self.cmbGroups = self.instBox:GetChild("cmb_group").asComboBox;
	InitPartyMemberGroupSelCombo(self.cmbGroups);
	self.cmbGroups.onChanged:Set(function()
		local tagSelectNo = self.cmbGroups.selectedIndex + 1;
		self:SetCurCardGroup(tagSelectNo);
	end);

end

function HeroAttributeSubWin:SetViewStyle(_style)
	self.ctlViewStyle.selectedIndex = _style;
end

function HeroAttributeSubWin:SetCurRole(_tagRole)
	self.curRole = _tagRole;
	self:UpdateRoleStat();
end

function HeroAttributeSubWin:UpdateRoleStat()
	if self.curRole == nil then
		self.mainView.visible = false;
	else
		self.mainView.visible = true;

		local curRole = self.curRole;

		CS.GUIHelper.GenerateRoleHeadAvataImage(curRole.HeadAvata, self.imgCurRoleHead);

		local curCard = curRole.BindCard;
		local curExp = curCard.Exp;
		local levelUpVal = curCard:GetLevelUpExp(curRole.roleLevel);
		local maxLevel = curCard:GetCardMaxLevel();
		local pct = 0;
		if levelUpVal > 0 then
			pct = Clamp(curExp / levelUpVal, 0, 1);
		end
		if curCard.Level >= maxLevel then
			self.txtExp.visible = false;
			pct = 1;
		else
			self.txtExp.visible = true;
		end
		self.imgProgExp.fillAmount = pct;
		self.txtExp.text = curExp .. "/" .. levelUpVal;
		UpdateUnitLevelBoxView(self.lbLevel, curRole.roleLevel, maxLevel);

		self.lvDescList.numItems = 0;
		if not curRole:IsPlayer() then
			self.lbFv.visible = true;
			self.lbFv.title = curRole:GetRelationValWithOtherRole(ID_PLAYER_ID);

			self.groupDesc.visible = true;
			self:AddRoleDescInfoText(curRole:getRoleTemplate():GetTagValue("Desc"));
			self.playerRanksBox.visible = false;
			
			if self.isShowInstBox then
				self.instBox.visible = true;
			end
		else
			self.lbFv.visible = false;

			self.groupDesc.visible = false;
			self.instBox.visible = false;

			--显示角色RANK信息
			self.playerRanksBox.visible = true;
			local nobleInfo = curRole:GetNobilityRankInfo();
			if nobleInfo ~= nil then
				self.ctlNobleRank.bindView.visible = true;
				local _titleNam = nobleInfo.title_name;
				local _curRank = nobleInfo.rank;
				local _curMerit = curRole.curMerit;
				local _statInfo;
				local _nextRankInfo = curRole:GetCampNobilityRankInfo(_curRank + 1);
				local nextMeritVal = 0;
				if _nextRankInfo ~= nil then
					nextMeritVal = _nextRankInfo.exploit_val;
				end
				local _statPct = 1;
				local _nextRankLeftVal = nextMeritVal - nobleInfo.exploit_val;
				if _nextRankLeftVal > 0 and nextMeritVal > 0 then
					_statInfo = _curMerit .. "/" .. nextMeritVal;
					_statPct = (_curMerit - nobleInfo.exploit_val) / _nextRankLeftVal;
				else
					_statInfo = "";
					_statPct = 1;
				end
				SetRankTitleBoxVal(self.ctlNobleRank, _statPct, _curRank, _statInfo, _titleNam);
			else
				self.ctlNobleRank.bindView.visible = false;
			end
			if IsTavernFightEnable() then
				self.ctlFightRank.bindView.visible = true;
				local curFightRank = GetCurTavernFightRank();
				local curExpVal = GetCurTavernFightExp();
				local _statPct = 1;
				local _statInfo;
				local curRankName = GetTavernFightRankTitle(curFightRank);
				local curRankExp = GetTavernFightRankExp(curFightRank);
				local nextRankExp = GetTavernFightRankExp(curFightRank + 1);
				local nextRankLeft = nextRankExp - curRankExp;
				if nextRankExp > 0 and nextRankLeft > 0 then
					_statInfo = curExpVal .. "/" .. nextRankExp;
					_statPct = (curExpVal - curRankExp) / nextRankLeft;
				else
					_statInfo = tostring(curExpVal);
					_statPct = 1;
				end
				SetRankTitleBoxVal(self.ctlFightRank, _statPct, curFightRank, _statInfo, curRankName);
			else
				self.ctlFightRank.bindView.visible = false;
			end
		end

		--更新装备列表
		local _showEquipLimit = false;
		if not curRole:IsPlayer() then
			local useWeaponType = curRole:GetUsedWeaponType();
			self.txtRoleEquipType.text = CS.GameTools.GetWeaponName(useWeaponType);
			_showEquipLimit = true;
		end

		self.txtRoleEquipType.visible = false;
		if self.equipSlots ~= nil then
			local tagEquipItem;
			for i = 0, constValShowEquipCount-1 do
				self.equipSlots[i].bindCard = curCard;
				tagEquipItem = curRole:GetEquipSlotByIndex(i);
				if i == 0 and tagEquipItem == nil and _showEquipLimit then
					self.txtRoleEquipType.visible = true;
				end
				self.equipSlots[i]:SetBindItem(tagEquipItem);
			end
		end

		--更新统率技能表
		local allCmdSkills = curRole:GetAllCmdSkillList();
		if (allCmdSkills.Count > 0) then
			UpdateSimpleSkillList(self.lvSkills, allCmdSkills, curRole.BindCard);
			self.cmdSkillBox.visible = true;
			self.lvSkills.visible = true;
		else
			self.cmdSkillBox.visible = false;
			self.lvSkills.visible = false;
		end

		--更新数值列表
		SetAttributeStatViewVal(self.lbHpMax, curRole:GetRoleStat("s_生命"), REF_VAL_MaxHp);
		SetAttributeStatViewVal(self.lbMpMax, curRole:GetRoleStat("s_气力"), REF_VAL_MaxMp);
		SetAttributeStatViewVal(self.lbStrVal, curRole:GetRoleStat("b_臂力"), REF_VAL_Str);
		SetAttributeStatViewVal(self.lbAgiVal, curRole:GetRoleStat("b_身法"), REF_VAL_Agi);
		SetAttributeStatViewVal(self.lbSprVal, curRole:GetRoleStat("b_精神"), REF_VAL_Spr);
		SetAttributeStatViewVal(self.lbStmVal, curRole:GetRoleStat("b_根骨"), REF_VAL_Stm);

		SetAttributeStatViewVal(self.lbPhyAtk, curRole:GetRoleStat("s_攻击"), REF_VAL_PhyAtk);
		SetAttributeStatViewVal(self.lbMagAtk, curRole:GetRoleStat("s_魔法攻击"), REF_VAL_MagAtk);
		SetAttributeStatViewVal(self.lbPhyDef, curRole:GetRoleStat("udatk_物理伤害减免") + curRole:GetRoleStat("udatk_伤害免除"), REF_VAL_PhyDef);
		SetAttributeStatViewVal(self.lbMagDef, curRole:GetRoleStat("udatk_巫术伤害减免") + curRole:GetRoleStat("udatk_伤害免除"), REF_VAL_MagDef);
		SetAttributeStatViewDesc(self.lbMagTalent, GetStatValMagicTalentDesc(curRole:GetRoleStat("magic_talent")));

		SetAttributeStatViewDesc(self.lbMoveSpeed, curRole:GetRoleStat("s_暴击").."%");
		SetAttributeStatViewDesc(self.lbAtkRange, curRole:GetRoleStat("s_闪避").."%");
		SetAttributeStatViewDesc(self.lbAtkSpeed, GetStatValDescAtkSpeed(curCard:GetWeaponSpeed()));
		SetAttributeStatViewVal(self.lbHpRes, curRole:GetRoleStat("s_生命回复"), REF_VAL_HpRes);
		SetAttributeStatViewVal(self.lbMpRes, curRole:GetRoleStat("s_气力回复"), REF_VAL_MpRes);

		--更新编队策略
		local cardGroup = curCard:GetPartyGroupNo();
		local _curInstruct = GameCoreHelper.GetGroupDefInstruct(cardGroup);
		self.ctlInstTabs:SetSeledItemByKey(tostring(_curInstruct), false);

		self.cmbGroups.selectedIndex = curCard:GetPartyGroupNo() - 1;
	end
end

function HeroAttributeSubWin:AddRoleDescInfoText(_txtInfo)
	local newLabel = self.lvDescList:AddItemFromPool().asLabel;
	if newLabel ~= nil then
		newLabel.title = CS.GUIHelper.ConvertUGUIStr(_txtInfo);
	end
end

function HeroAttributeSubWin:UpdateParentPartyList(_tagCard)
	if self.RefreshParentListCallback == nil then
		local playerTeam = GameCoreHelper.GetPlayerTeam();
		playerTeam.isTeamUpdated = true;
	else
		if self.RefreshParentListCallback ~= nil then
			self.RefreshParentListCallback(_tagCard, true);
		end
	end
end

function HeroAttributeSubWin:SetCurCardGroup(_newNo)
	if self.curRole ~= nil then
		local curCard = self.curRole.BindCard;
		if curCard ~= nil then
			curCard:SetPartyGroupNo(_newNo);
			self:UpdateParentPartyList(curCard);
		end
	end
end