class ArmsCWInSlotPrereqState extends PrereqState
{
	var m_listener : ArmsCWInSlotCallback;
	var m_owner : weak< GameObject >;

	public function AreaChanged( itemID : ItemID )
	{
		const var prereq : ArmsCWInSlotPrereq;
		var checkPassed : Bool;
		prereq = ( ( ArmsCWInSlotPrereq )( GetPrereq() ) );
		if( prereq )
		{
			checkPassed = prereq.EvaluateAll( m_owner );
			OnChanged( checkPassed );
		}
	}

}

class ArmsCWInSlotPrereq extends IScriptablePrereq
{
	var m_equipmentArea : gamedataEquipmentArea;
	default m_equipmentArea = gamedataEquipmentArea.ArmsCW;
	var m_slotCheckType : gamedataCheckType;
	var m_itemType : gamedataItemType;
	var m_itemTag : CName;
	var m_invert : Bool;

	protected export const override function OnRegister( state : PrereqState, game : GameInstance, context : IScriptable ) : Bool
	{
		var owner : GameObject;
		var castedState : ArmsCWInSlotPrereqState;
		owner = ( ( GameObject )( context ) );
		castedState = ( ( ArmsCWInSlotPrereqState )( state ) );
		castedState.m_listener = new ArmsCWInSlotCallback;
		castedState.m_owner = owner;
		castedState.m_listener.RegisterState( castedState );
		GameInstance.GetTransactionSystem( game ).RegisterAttachmentSlotListener( owner, castedState.m_listener );
		return false;
	}

	protected export const override function OnUnregister( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var castedState : ArmsCWInSlotPrereqState;
		castedState = ( ( ArmsCWInSlotPrereqState )( state ) );
		if( castedState )
		{
			castedState.m_listener = NULL;
		}
	}

	protected export const override function OnApplied( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var castedState : ArmsCWInSlotPrereqState;
		castedState = ( ( ArmsCWInSlotPrereqState )( state ) );
		castedState.OnChanged( IsFulfilled( game, context ) );
	}

	public export const override function IsFulfilled( game : GameInstance, context : IScriptable ) : Bool
	{
		return EvaluateAll( ( ( GameObject )( context ) ) );
	}

	public const function EvaluateAll( owner : weak< GameObject > ) : Bool
	{
		var eqSystem : weak< EquipmentSystem >;
		var playerData : EquipmentSystemPlayerData;
		var slots : Int32;
		var i : Int32;
		var item : ItemID;
		var result : Bool;
		eqSystem = ( ( EquipmentSystem )( GameInstance.GetScriptableSystemsContainer( owner.GetGame() ).Get( 'EquipmentSystem' ) ) );
		playerData = eqSystem.GetPlayerData( owner );
		slots = playerData.GetNumberOfSlots( m_equipmentArea );
		for( i = 0; i < slots; i += 1 )
		{
			item = playerData.GetItemInEquipSlot( m_equipmentArea, i );
			if( ItemID.IsValid( item ) )
			{
				result = Evaluate( item );
				if( result )
				{
					break;
				}
			}
		}
		return ( ( m_invert ) ? ( !( result ) ) : ( result ) );
	}

	public const function Evaluate( itemID : ItemID ) : Bool
	{
		var result : Bool;
		switch( m_slotCheckType )
		{
			case gamedataCheckType.Tag:
				result = EvaluateTag( itemID, m_itemTag );
			break;
			case gamedataCheckType.Type:
				result = EvaluateType( RPGManager.GetItemType( itemID ) );
			break;
			default:
				result = false;
			break;
		}
		return result;
	}

	public const function EvaluateTag( itemID : ItemID, tag : CName ) : Bool
	{
		var tags : array< CName >;
		tags = RPGManager.GetItemRecord( itemID ).Tags();
		return tags.Contains( tag );
	}

	public const function EvaluateType( itemType : gamedataItemType ) : Bool
	{
		return itemType == m_itemType;
	}

	protected export override function Initialize( recordID : TweakDBID )
	{
		m_slotCheckType = TweakDBInterface.GetCheckTypeRecord( TweakDBInterface.GetForeignKeyDefault( recordID + T".checkType" ) ).Type();
		m_itemType = TweakDBInterface.GetItemTypeRecord( TweakDBInterface.GetForeignKeyDefault( recordID + T".itemType" ) ).Type();
		m_itemTag = TweakDBInterface.GetCName( recordID + T".itemTag", '' );
		m_invert = TweakDBInterface.GetBool( recordID + T".inverted", false );
	}

}

class ArmsCWInSlotCallback extends AttachmentSlotsScriptCallback
{
	protected var m_state : weak< ArmsCWInSlotPrereqState >;

	public export override function OnItemEquipped( slot : TweakDBID, item : ItemID )
	{
		if( EquipmentSystem.GetEquipAreaType( item ) == gamedataEquipmentArea.RightArm )
		{
			m_state.AreaChanged( item );
		}
	}

	public export override function OnItemUnequipped( slot : TweakDBID, item : ItemID )
	{
		if( EquipmentSystem.GetEquipAreaType( item ) == gamedataEquipmentArea.RightArm )
		{
			m_state.AreaChanged( item );
		}
	}

	public export override function OnAttachmentRefreshed( slot : TweakDBID, item : ItemID )
	{
		if( EquipmentSystem.GetEquipAreaType( item ) == gamedataEquipmentArea.RightArm )
		{
			m_state.AreaChanged( item );
		}
	}

	public function RegisterState( state : PrereqState )
	{
		m_state = ( ( ArmsCWInSlotPrereqState )( state ) );
	}

}

