#include "../mainproc/GameMain.h"
#include "../Interface/WorldFrames/ChatFrame.h"
#include "../Interface/WorldFrames/PartyFrame.h"
#include "../Interface/WorldFrames/UnitFrame.h"
#include "../Interface/WorldFrames/LootFrame.h"
#include "NetCli_PartyChild.h"

//-----------------------------------------------------------------------------
PartyBaseInfoStruct				NetCli_PartyChild::s_info;
vector<PartyMemberInfo>			NetCli_PartyChild::s_member;
vector<PartyAssignItem>			NetCli_PartyChild::s_assignItem;
vector<PartyRollItem>			NetCli_PartyChild::s_rollItem;
PartyStateInfo					NetCli_PartyChild::s_state;
string							NetCli_PartyChild::s_leaderName;
int								NetCli_PartyChild::s_leaderIndex;
map<int, PartyMemberInfo>		NetCli_PartyChild::s_tempMember;

//-----------------------------------------------------------------------------
bool NetCli_PartyChild::_Init()
{
	if (This)
		return false;

	This = new NetCli_PartyChild;

	ClearPartyInfo();

	return NetCli_Party::_Init();
}

//-----------------------------------------------------------------------------
bool NetCli_PartyChild::_Release()
{
	NetCli_Party::_Release();
	if (This)
	{
		delete This;
		This = NULL;
	}
	return true;
}
//-----------------------------------------------------------------------------
PartyMemberInfo* NetCli_PartyChild::GetPartyMember(int index)
{
	if ( (unsigned int)index < (unsigned int)s_member.size() )
		return &s_member[index];
	return NULL;
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::UpdateLeaderInfo()
{
	// 領隊名稱
	s_leaderName = s_info.LeaderName.Begin();

	// 取得隊長所在索引值
	s_leaderIndex = -1;

	int i = 0;
	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++, i++ )
	{
		if ( s_info.LeaderName.Compare( (*iter).name.c_str() ) == 0 )
		{
			s_leaderIndex = i;
			break;
		}
	}

	// 更新隊長資料
	g_pPartyFrame->RefreshPartyLeader();
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::SetPartyMemberHPMPSP(int DBID, int hp, int mp, int sp)
{	
	int i = 0;
	bool isHave = false;

	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++, i++ )
	{
		if ( (*iter).DBID == DBID )
		{
			if ( (*iter).hp != hp )
			{
				(*iter).hp = hp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitHealth, CUnitFrame::eUnit_Party, i + 1 );
			}
			if ( (*iter).mp != mp )
			{
				(*iter).mp = mp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitMana, CUnitFrame::eUnit_Party, i + 1 );
			}
			if ( (*iter).sp != sp )
			{
				(*iter).sp = sp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitSkill, CUnitFrame::eUnit_Party, i + 1 );
			}
			isHave = true;
			break;
		}
	}

	if ( !isHave )
	{
		map<int, PartyMemberInfo>::iterator iter = s_tempMember.find(DBID);
		if ( iter != s_tempMember.end() )
		{
			iter->second.hp = hp;
			iter->second.mp = mp;
			iter->second.sp = sp;
		}
		else
		{
			PartyMemberInfo member;
			member.hp = hp;
			member.mp = mp;
			member.sp = sp;
			s_tempMember.insert( make_pair(DBID, member) );
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::SetPartyMemberMaxHPMPSP(int DBID, int maxHp, int maxMp, int maxSp)
{
	int i = 0;
	bool isHave = false;

	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++, i++ )
	{
		if ( (*iter).DBID == DBID )
		{
			if ( (*iter).maxHp != maxHp )
			{
				(*iter).maxHp = maxHp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitHealth, CUnitFrame::eUnit_Party, i + 1 );
			}
			if ( (*iter).maxMp != maxMp )
			{
				(*iter).maxMp = maxMp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitMana, CUnitFrame::eUnit_Party, i + 1 );
			}
			if ( (*iter).maxSp != maxSp )
			{
				(*iter).maxSp = maxSp;
				g_pUnitFrame->UnitEvent( UiEvent_UnitSkill, CUnitFrame::eUnit_Party, i + 1 );
			}
			isHave = true;
			break;
		}
	}
	
	if ( !isHave )
	{
		map<int, PartyMemberInfo>::iterator iter = s_tempMember.find(DBID);
		if ( iter != s_tempMember.end() )
		{
			iter->second.maxHp = maxHp;
			iter->second.maxMp = maxMp;
			iter->second.maxSp = maxSp;
		}
		else
		{
			PartyMemberInfo member;
			member.maxHp = maxHp;
			member.maxMp = maxMp;
			member.maxSp = maxSp;
			s_tempMember.insert( make_pair(DBID, member) );
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::SetPartyMemberPosition(int DBID, int zoneId, float x, float y, float z)
{
	int i = 0;
	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++, i++ )
	{
		if ( (*iter).DBID == DBID )
		{
			if ( (*iter).ZoneID != zoneId )
			{
				(*iter).ZoneID = zoneId;
			}
			if ( (*iter).x != x || (*iter).y != y || (*iter).z != z )
			{
				(*iter).x = x;
				(*iter).y = y;
				(*iter).z = z;
			}
			break;
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::ClearPartyInfo()
{
	s_member.clear();
	s_leaderName.clear();
	s_tempMember.clear();
	s_leaderIndex	= -1;
	s_state			= ePartyState_Solo;

	ClearRollItem();
	ClearAssignItem();
}
//-----------------------------------------------------------------------------
int	NetCli_PartyChild::InviteToParty(const char* name)
{
	if ( name == NULL )
		return -1;

	switch ( s_state )
	{
	case ePartyState_Solo:
	case ePartyState_Receive:
	case ePartyState_Leader:
		S_Invite( (char*)name );
		break;

	case ePartyState_Member:
		return -2;					// 沒有權限
	}
	return 0;
}
//-----------------------------------------------------------------------------
int	NetCli_PartyChild::InviteAnswerState(bool isAccept)
{
	switch (s_state)
	{
	case ePartyState_Solo:			// 未受到邀請
		return -2;

	case ePartyState_Receive:		// 是否同意加入隊伍 
		s_state = ePartyState_Solo;
		if ( isAccept )
			S_Join( (char*)s_leaderName.c_str() );
		return 0;

	case ePartyState_Leader:		// 已在隊伍中
	case ePartyState_Member:
		return -3;					
	}
	return -1;
}

//-----------------------------------------------------------------------------
int	NetCli_PartyChild::PromoteToLeader(const char* name)
{
	if ( name == NULL )
		return -1;

	switch ( s_state )
	{
	case ePartyState_Leader:
		{
			PartyBaseInfoStruct info = s_info;
			info.LeaderName = name;

			NetCli_PartyChild::S_PartyRule( info );
		}
		break;

	default:
		return -1;
	}

	return 0;
}

//-----------------------------------------------------------------------------
int	NetCli_PartyChild::SetLootMethod(PartyItemShareENUM mode, const char* name)
{
	if ( s_state != ePartyState_Leader )
		return -1;

	if ( name == NULL )
		name = s_info.LeaderName.Begin();
	
	switch ( mode )
	{
	case EM_PartyItemShare_Roll:
		if ( s_info.ItemShareType != EM_PartyItemShare_Roll )
		{
			s_info.ItemShareType = EM_PartyItemShare_Roll;
			NetCli_PartyChild::S_PartyRule( s_info );
			return 0;
		}
		break;

	case EM_PartyItemShare_Assign:
		if ( s_info.ItemShareType != EM_PartyItemShare_Assign || s_info.ShareName.Compare( name ) != 0 )
		{
			s_info.ItemShareType = EM_PartyItemShare_Assign;
			s_info.ShareName = name;
			NetCli_PartyChild::S_PartyRule( s_info );
		}
		return 0;
	}

	return -1;
}

//-----------------------------------------------------------------------------
int	NetCli_PartyChild::SetLootThreshold(int quality)
{
	if ( s_state != ePartyState_Leader )
		return -1;

	if ( s_info.RollTypeLV != quality )
	{
		s_info.RollTypeLV = quality;
		if ( s_info.ItemShareType == EM_PartyItemShare_Roll )
			NetCli_PartyChild::S_PartyRule( s_info );
	}
	return 0;
}

//-----------------------------------------------------------------------------
int NetCli_PartyChild::KickMember(const char* name)
{
	if ( name == NULL )
		return -1;

	switch ( s_state )
	{
	case ePartyState_Leader:
		S_KickMember( (char*)name );
		break;

	default:
		return -1;
	}
	return 0;
}

//-----------------------------------------------------------------------------
const char* NetCli_PartyChild::FindMemberName(int DBID)
{
	if ( DBID == g_pGameMain->GetDBID() )
		return g_pGameMain->GetPlayerName();
	
	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++ )
	{
		if ( DBID == (*iter).DBID )
			return (*iter).name.c_str();
	}

	return NULL;
}

//-----------------------------------------------------------------------------
bool NetCli_PartyChild::InParty(const char* name)
{
	if ( name == NULL )
		return false;	

	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++ )
	{
		if ( strcmp( (*iter).name.c_str(), name ) == 0 )
			return true;
	}
	return false;
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::AddRollItem(PartyRollItem& rollItem)
{
	s_rollItem.push_back( rollItem );
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::DeleteRollItem(int DBID, int itemVersion)
{
	if ( DBID == g_pGameMain->GetDBID() )
	{
		for ( vector<PartyRollItem>::iterator iter = s_rollItem.begin(); iter != s_rollItem.end(); iter++ )
		{
			if ( (*iter).itemVersion == itemVersion )
			{
				// 刪除項目
				g_pLootFrame->DeleteLootItem( itemVersion );
				s_rollItem.erase(iter);
				break;
			}
		}
	}
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::ClearRollItem()
{
	for ( vector<PartyRollItem>::iterator iter = s_rollItem.begin(); iter != s_rollItem.end(); iter++ )
		g_pLootFrame->DeleteLootItem( (*iter).itemVersion );
	s_rollItem.clear();
}

//-----------------------------------------------------------------------------
PartyRollItem* NetCli_PartyChild::GetRollItem(int itemVersion)
{
	for ( vector<PartyRollItem>::iterator iter = s_rollItem.begin(); iter != s_rollItem.end(); iter++ )
	{
		if ( (*iter).itemVersion == itemVersion )
			return &(*iter);
	}
	return NULL;
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::AddAssignItem(PartyAssignItem& assignItem)
{
	s_assignItem.push_back(assignItem);
	g_pLootFrame->RefreshAssignItem();
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::DeleteAssignItem(int itemVersion)
{
	for ( vector<PartyAssignItem>::iterator iter = s_assignItem.begin(); iter != s_assignItem.end(); iter++ )
	{
		if ( (*iter).itemVersion == itemVersion )
		{
			s_assignItem.erase(iter);
			g_pLootFrame->RefreshAssignItem();
			break;
		}
	}
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::ClearAssignItem()
{
	s_assignItem.clear();
	g_pLootFrame->RefreshAssignItem();
}

//-----------------------------------------------------------------------------
PartyAssignItem* NetCli_PartyChild::GetAssignItem(int itemVersion)
{
	for ( vector<PartyAssignItem>::iterator iter = s_assignItem.begin(); iter != s_assignItem.end(); iter++ )
	{
		if ( (*iter).itemVersion == itemVersion )
			return &(*iter);
	}
	return NULL;
}

//-----------------------------------------------------------------------------
const char*	NetCli_PartyChild::GetAssignItemMember(int itemVersion, int index)
{
	PartyAssignItem* assign = GetAssignItem(itemVersion);
	if ( assign )
	{
		if ( (DWORD)index < (DWORD)assign->loot.size() )
		{
			return FindMemberName( assign->loot[index] );
		}
	}
	return NULL;
}

//-----------------------------------------------------------------------------
int NetCli_PartyChild::AssignTo(int itemVersion, int index)
{
	PartyAssignItem* assign = GetAssignItem(itemVersion);
	if ( assign )
	{
		if ( (DWORD)index < (DWORD)assign->loot.size() )
		{
			S_AssistItem(itemVersion, assign->loot[index]);
			return 0;
		}
	}
	return -1;
}

//-----------------------------------------------------------------------------
bool NetCli_PartyChild::IsAssigner()
{
	switch ( s_state )
	{
	case ePartyState_Leader:
	case ePartyState_Member:
		if ( s_info.ShareName.Compare( g_pGameMain->GetPlayerName() ) == 0 )
			return true;
		break;
	}
	return false;
}

//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_Invite( char* LeaderName )
{
	char Buf[1024];
	lua_State* L = g_pPartyFrame->GetLuaStateWorld();

	switch ( s_state )
	{
	//
	case ePartyState_Solo:
		sprintf( Buf , "[組隊要請] : LeaderName = %s" , LeaderName );
		g_pChatFrame->AddMessage( 5, Buf );
		s_state = ePartyState_Receive;
		s_leaderName = LeaderName;

		lua_pushstring(L, s_leaderName.c_str());
		lua_setglobal(L, "arg1");
		g_pPartyFrame->SendWorldEvent("PARTY_INVITE_REQUEST");		
		break;

	case ePartyState_Receive:
		sprintf( Buf , "[組隊要請][已受到其他人邀請] : LeaderName = %s" , LeaderName );
		g_pChatFrame->AddMessage( 5, Buf );
		break;

	case ePartyState_Leader:
	case ePartyState_Member:
		sprintf( Buf , "[組隊要請][已有隊伍] : LeaderName = %s" , LeaderName );
		g_pChatFrame->AddMessage( 5, Buf );
		break;	
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_PartyBaseInfo( PartyBaseInfoStruct& Info )
{
	char Buf[1024];
	sprintf( Buf , "[隊伍資訊] : PartyBase LeaderName = %s PartyID = %d" , Info.LeaderName.Begin( ) , Info.PartyID );
	g_pChatFrame->AddMessage( 5, Buf );
	sprintf( Buf , "[隊伍資訊] : PartyBase AttackName = %s ", Info.AttackName.Begin() );
	g_pChatFrame->AddMessage( 5, Buf );

	switch( Info.ItemShareType )
	{
	case EM_PartyItemShare_Roll:
		sprintf( Buf , "[隊伍資訊] : 分配方式 擲骰子");
		g_pChatFrame->AddMessage( 5, Buf );
		break;
	case EM_PartyItemShare_Assign:
		sprintf( Buf , "[隊伍資訊] : 分配方式 指定分配 分配者 = %s" , Info.ShareName.Begin() );
		g_pChatFrame->AddMessage( 5, Buf );
		g_pLootFrame->RefreshAssignItem();
		break;
	}

	bool isLeaderChanged = false;

	// 檢查隊長是否已更改
	if ( s_info.LeaderName.Compare(Info.LeaderName.Begin()) != 0 )
		isLeaderChanged = true;	

	s_info = Info;

	// 設定自己隊伍狀態
	if ( s_info.LeaderName.Compare(g_pGameMain->GetPlayerName()) == 0 )
		s_state = ePartyState_Leader;
	else
		s_state = ePartyState_Member;

	// 若隊長更改
	if ( isLeaderChanged )
		UpdateLeaderInfo();	
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_AddMember	( PartyMemberInfoStruct& Member )
{
	char Buf[1024];
	//sprintf( Buf , "[隊伍資訊] : 加入成員 ID =%d  Name = %s" , Member.MemberID , Member.Name.Begin() );
	//g_pChatFrame->AddMessage( 5, Buf );

	// 非玩家自己在加入清單內
	if ( Member.DBID != g_pGameMain->GetDBID() )
	{
		// 加入新隊友
		PartyMemberInfo info;
		memset( &info, sizeof(info), 0 );

		info.name			= Member.Name.Begin();
		info.DBID			= Member.DBID;
		info.memberId		= Member.MemberID;
		info.GItemID		= Member.GItemID;

		sprintf( Buf, "[%s]加入隊伍", Member.Name.Begin() );
		g_pChatFrame->AddMessage( 5, Buf );

		s_member.push_back( info );
		g_pPartyFrame->RefreshPartyMember();

		map<int, PartyMemberInfo>::iterator iter = s_tempMember.find(Member.DBID);
		if ( iter != s_tempMember.end() )
		{
			SetPartyMemberHPMPSP( iter->first, iter->second.hp, iter->second.mp, iter->second.sp );
			SetPartyMemberMaxHPMPSP( iter->first, iter->second.maxHp, iter->second.maxMp, iter->second.maxSp );
		}

		// 新加入隊員是否為隊長
		if ( s_info.LeaderName.Compare(Member.Name.Begin()) == 0 )
		{
			UpdateLeaderInfo();		// 更新隊長資料
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_DelMember	( PartyMemberInfoStruct& Member )
{
	char Buf[1024];
	//sprintf( Buf , "[隊伍資訊] : 刪除成員 ID =%d  Name = %s" , Member.MemberID , Member.Name.Begin() );
	//g_pChatFrame->AddMessage( 5, Buf );

	// 若自己脫離隊伍
	if ( Member.DBID == g_pGameMain->GetDBID() )
	{
		g_pChatFrame->AddMessage( 5, "你已經脫離隊伍" );

		ClearPartyInfo();
		g_pPartyFrame->RefreshPartyMember();
	}
	else
	{
		// 刪除隊友
		vector<PartyMemberInfo>::iterator iter = s_member.begin();
		for ( ; iter != s_member.end(); iter++ )
		{
			// 隊友脫離隊伍
			if ( (*iter).DBID == Member.DBID )
			{
				sprintf( Buf, "[%s]離開隊伍", Member.Name.Begin() );
				g_pChatFrame->AddMessage( 5, Buf );

				s_member.erase( iter );
				g_pPartyFrame->RefreshPartyMember();

				if ( s_member.empty() )
					g_pChatFrame->AddMessage( 5, "隊伍已解散");
				break;
			}
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_FixMember	( PartyMemberInfoStruct& Member )
{
	char Buf[1024];
	sprintf( Buf , "[隊伍資訊] : 修改成員 ID =%d  Name = %s" , Member.MemberID , Member.Name.Begin() );
	g_pChatFrame->AddMessage( 5, Buf );
	
	for ( vector<PartyMemberInfo>::iterator iter = s_member.begin(); iter != s_member.end(); iter++ )
	{
		PartyMemberInfo& info = (*iter);
		if ( info.DBID == Member.DBID )
		{
			info.name		= Member.Name.Begin();
			info.memberId	= Member.MemberID;
			info.GItemID	= Member.GItemID;
			break;
		}
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_PartyTreasure( int ItemVersion, PartyItemShareENUM LootType, ItemFieldStruct& Item, StaticVector< int , _MAX_PARTY_COUNT_ >& LootDBID )
{
	GameObjDbStruct* pObj = CNetGlobal::GetObj( Item.OrgObjID );
	if( pObj == NULL )
	{
		g_pChatFrame->AddMessage( 5, "[隊員物品] : R_PartyTreasure pObj == NULL" );
		return;
	}

	/*
	for ( int i = 0; i < LootDBID.Size(); i++ )
	{
		if ( LootDBID[i] == g_pGameMain->GetDBID() )
		{
			char msg[1024];
			char itemName[MAX_PATH];

			RoleDataEx::GetItemFieldName(&Item, itemName, MAX_PATH);
			sprintf( msg, "隊伍獲得[%s]", itemName );
			g_pChatFrame->AddMessage( eMessage_Channel_Party, msg );

			break;
		}
	}
	*/

	char msg[1024];
	char itemName[MAX_PATH];

	RoleDataEx::GetItemFieldName(&Item, itemName, MAX_PATH);
	sprintf( msg, "隊伍獲得[%s]", itemName );
	g_pChatFrame->AddMessage( 0, msg );

	// 隊伍護得物品
	// 判斷物品取得方式,投擲或分配或輪流取得
	switch ( LootType )
	{
	case EM_PartyItemShare_Roll:
		for ( int i = 0; i < LootDBID.Size(); i++ )
		{
			if ( LootDBID[i] == g_pGameMain->GetDBID() )
			{
				PartyRollItem roll;
				roll.itemVersion	= ItemVersion;
				roll.item			= Item;
				roll.status			= eLootItem_Wait;

				AddRollItem(roll);
				break;
			}
		}
		break;

	case EM_PartyItemShare_Assign:
		{			
			PartyAssignItem assign;
			assign.itemVersion	= ItemVersion;
			assign.item			= Item;
			for ( int i = 0; i < LootDBID.Size(); i++ )
				assign.loot.push_back(LootDBID[i]);

			AddAssignItem( assign );			
		}
		break;
	}
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_PartyTreasureLoot( int ItemVersion ,	int DBID , int LootValue )
{
	/*
	char Buf[1024];
	sprintf( Buf , "[隊員物品] : 執骰子  ItemVersion = %d DBID =%d LootValue = %d " , ItemVersion , DBID , LootValue );
	g_pChatFrame->AddMessage( 5, Buf );
	*/

	const char* name = FindMemberName(DBID);
	if ( name == NULL )
	{
		g_pChatFrame->AddMessage( 0, "[封包錯誤][R_PartyTreasureLoot] 該角色DBID不存在" );
	}
	else
	{
		PartyRollItem* rollItem = GetRollItem(ItemVersion);
		if ( rollItem == NULL )
		{
			// g_pChatFrame->AddMessage( eMessage_Channel_System, "[封包錯誤][R_PartyTreasureLoot] 該物品ItemVersion不存在" );
		}
		else
		{
			char msg[1024];
			char itemName[MAX_PATH];
			RoleDataEx::GetItemFieldName(&rollItem->item, itemName, MAX_PATH);

			if ( LootValue > 100 )
				sprintf( msg, "[%s]:需求[%s] %d", name, itemName, LootValue - 100 );
			else
				sprintf( msg, "[%s]:貪婪[%s] %d", name, itemName, LootValue );

			g_pChatFrame->AddMessage( 0, msg );
		}
	}

	DeleteRollItem( DBID, ItemVersion );
}
//-----------------------------------------------------------------------------
void NetCli_PartyChild::R_GiveItemInfo( int DBID , ItemFieldStruct& Item , int ItemVersion )
{
	const char* name = FindMemberName(DBID);
	if ( name == NULL )
	{
		g_pChatFrame->AddMessage( 0, "[封包錯誤][R_GiveItemInfo] 該角色DBID不存在" );
	}
	else
	{
		char msg[1024];
		char itemName[MAX_PATH];
		RoleDataEx::GetItemFieldName(&Item, itemName, MAX_PATH);
		sprintf( msg, "%s獲得[%s]", name, itemName );

		g_pChatFrame->AddMessage( 0, msg );
	}

	// 物品分配給某一位隊員
	// 將物品至隊伍暫存區移除	
	DeleteAssignItem( ItemVersion );
	DeleteRollItem( DBID, ItemVersion );
}

	