class RipperdocInventoryController extends inkLogicController
{
	private editable var m_virtualGridContainer : inkVirtualCompoundRef;
	private editable var m_scrollBarContainer : inkWidgetRef;
	private editable var m_labelPrefix : inkTextRef;
	private editable var m_labelSuffix : inkTextRef;
	private var m_virtualGrid : weak< inkVirtualGridController >;
	private var m_backpackItemsClassifier : RipperdocInventoryTemplateClassifier;
	private var m_backpackItemsDataSource : ScriptableDataSource;
	private var m_backpackItemsDataView : ScriptableDataView;
	private var m_scrollBar : weak< inkScrollController >;
	private var m_root : weak< inkWidget >;
	private var m_opacityAnimation : inkAnimProxy;
	private var m_labelPulse : PulseAnimation;
	private var m_cachedPlayerItems : array< RipperdocWrappedUIInventoryItem >;
	private var m_cachedVendorItems : array< RipperdocWrappedUIInventoryItem >;
	private var m_cachedArea : gamedataEquipmentArea;
	private var m_openArea : gamedataEquipmentArea;
	private var m_cachedAttribute : gamedataStatType;
	private var m_openAttribute : gamedataStatType;
	private var m_hasCache : Bool;
	private var m_isAreaCache : Bool;

	protected event OnUninitialize()
	{
		ReleaseVirtualGrid();
	}

	public function Configure( scripting : weak< UIScriptableSystem > )
	{
		m_root = GetRootWidget();
		m_root.SetVisible( true );
		m_root.SetOpacity( 0.0 );
		m_scrollBar = ( ( inkScrollController )( inkWidgetRef.GetController( m_scrollBarContainer ) ) );
		m_labelPulse = new PulseAnimation;
		m_labelPulse.Configure( inkTextRef.Get( m_labelSuffix ), 1.0, 0.05, 1.0 );
		m_openArea = gamedataEquipmentArea.Invalid;
		m_openAttribute = gamedataStatType.Invalid;
		SetupVirtualGrid();
	}

	protected function SetupVirtualGrid()
	{
		m_virtualGrid = ( ( inkVirtualGridController )( inkVirtualCompoundRef.GetControllerByType( m_virtualGridContainer, 'inkVirtualGridController' ) ) );
		m_backpackItemsClassifier = new RipperdocInventoryTemplateClassifier;
		m_backpackItemsDataSource = new ScriptableDataSource;
		m_backpackItemsDataView = new ScriptableDataView;
		m_backpackItemsDataView.SetSource( m_backpackItemsDataSource );
		m_virtualGrid.SetClassifier( m_backpackItemsClassifier );
		m_virtualGrid.SetSource( m_backpackItemsDataView );
	}

	public function ReleaseVirtualGrid()
	{
		m_virtualGrid.SetClassifier( NULL );
		m_virtualGrid.SetSource( NULL );
		m_backpackItemsDataView.SetSource( NULL );
		m_backpackItemsClassifier = NULL;
		m_backpackItemsDataSource = NULL;
		m_backpackItemsDataView = NULL;
	}

	private function PopulateInventory()
	{
		var list : array< IScriptable >;
		var i, limit : Int32;
		var count : Float;
		for( i = 0, limit = m_cachedPlayerItems.Size(); i < limit; i += 1 )
		{
			if( count < 20.0 )
			{
				m_cachedPlayerItems[ i ].Delay = count / 30.0;
				count += 1.0;
			}
			list.PushBack( m_cachedPlayerItems[ i ] );
		}
		for( i = 0, limit = m_cachedVendorItems.Size(); i < limit; i += 1 )
		{
			if( count < 20.0 )
			{
				m_cachedVendorItems[ i ].Delay = count / 30.0;
				count += 1.0;
			}
			list.PushBack( m_cachedVendorItems[ i ] );
		}
		m_backpackItemsDataSource.Reset( list );
	}

	public function ShowArea( playerItems, vendorItems : array< RipperdocWrappedUIInventoryItem >, area : gamedataEquipmentArea )
	{
		m_cachedPlayerItems = playerItems;
		m_cachedVendorItems = vendorItems;
		m_cachedArea = area;
		m_isAreaCache = true;
		OnShow( NULL );
	}

	protected event OnShow( anim : inkAnimProxy )
	{
		AnimateOpacity( false );
		if( m_isAreaCache )
		{
			if( m_cachedArea == gamedataEquipmentArea.Invalid )
			{
				inkTextRef.SetText( m_labelPrefix, "No Filter Applied" );
				inkTextRef.SetText( m_labelSuffix, "" );
				m_labelPulse.Stop();
			}
			else
			{
				inkTextRef.SetText( m_labelPrefix, "Filtering By: " );
				inkTextRef.SetText( m_labelSuffix, TweakDBInterface.GetEquipmentAreaRecord( TDBID.Create( "EquipmentArea." + EnumValueToString( "gamedataEquipmentArea", ( ( Int32 )( m_cachedArea ) ) ) ) ).LocalizedName() );
				m_labelPulse.Start();
			}
		}
		else
		{
			if( m_cachedAttribute == gamedataStatType.Invalid )
			{
				inkTextRef.SetText( m_labelPrefix, "No Filter Applied" );
				inkTextRef.SetText( m_labelSuffix, "" );
				m_labelPulse.Stop();
			}
			else
			{
				inkTextRef.SetText( m_labelPrefix, "Filtering By: " );
				inkTextRef.SetText( m_labelSuffix, TweakDBInterface.GetStatRecord( TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( m_cachedAttribute ) ) - ( ( m_cachedAttribute == gamedataStatType.Armor ) ? ( 0 ) : ( 2 ) ) ) ) ).LocalizedName() );
				m_labelPulse.Start();
			}
		}
		PopulateInventory();
		if( ( m_isAreaCache && m_openArea != m_cachedArea ) || ( !( m_isAreaCache ) && m_openAttribute != m_cachedAttribute ) )
		{
			m_scrollBar.SetScrollPosition( 0.0 );
		}
		m_scrollBar.SetScrollPosition( 0.0 );
		m_openArea = m_cachedArea;
		m_openAttribute = m_cachedAttribute;
	}

	public function Hide()
	{
		AnimateOpacity( true );
	}

	private function AnimateOpacity( toHidden : Bool )
	{
		var time : Float;
		var barProgress : inkAnimDef;
		var opacityInterpolator : inkAnimTransparency;
		var animDuration : Float;
		animDuration = 0.42500001;
		if( m_opacityAnimation != NULL )
		{
			m_opacityAnimation.Stop();
		}
		time = m_root.GetOpacity();
		time = ( ( toHidden ) ? ( time ) : ( ( 1.0 - time ) ) ) * animDuration;
		opacityInterpolator = new inkAnimTransparency;
		opacityInterpolator.SetDuration( time );
		opacityInterpolator.SetStartTransparency( m_root.GetOpacity() );
		opacityInterpolator.SetEndTransparency( ( ( toHidden ) ? ( 0.0 ) : ( 1.0 ) ) );
		opacityInterpolator.SetType( inkanimInterpolationType.Quintic );
		opacityInterpolator.SetMode( inkanimInterpolationMode.EasyInOut );
		barProgress = new inkAnimDef;
		barProgress.AddInterpolator( opacityInterpolator );
		m_opacityAnimation = m_root.PlayAnimation( barProgress );
	}

}

class RipperdocInventoryItemData extends IScriptable
{
	var InventoryItem : InventoryItemData;
	var IsVendor : Bool;
	var IsBuyback : Bool;
	var IsUpgraded : Bool;
	var IsEnoughMoney : Bool;
	var Delay : Float;
}

class RipperdocWrappedUIInventoryItem extends IScriptable
{
	var InventoryItem : weak< UIInventoryItem >;
	var Delay : Float;
	var DisplayContext : ItemDisplayContextData;
	var IsEnoughMoney : Bool;
	default IsEnoughMoney = true;
	var IsNew : Bool;
	var IsEquippable : Bool;
	var ItemPrice : Float;
	var IsBuybackStack : Bool;
	var AdditionalData : IScriptable;

	public static function Make( item : weak< UIInventoryItem >, displayContext : ItemDisplayContextData, optional additionalData : IScriptable ) : RipperdocWrappedUIInventoryItem
	{
		var instance : RipperdocWrappedUIInventoryItem;
		instance = new RipperdocWrappedUIInventoryItem;
		instance.InventoryItem = item;
		instance.DisplayContext = displayContext;
		instance.IsEnoughMoney = true;
		instance.AdditionalData = additionalData;
		return instance;
	}

}

class RipperdocInventoryItem extends inkVirtualCompoundItemController
{
	protected editable var m_root : inkWidgetRef;
	protected var m_data : RipperdocWrappedUIInventoryItem;
	protected var m_widget : weak< InventoryItemDisplayController >;

	protected event OnInitialize()
	{
		GetRootWidget().SetVAlign( inkEVerticalAlign.Top );
		GetRootWidget().SetHAlign( inkEHorizontalAlign.Left );
		ItemDisplayUtils.SpawnCommonSlotAsync( this, m_root, 'itemDisplay', 'OnWidgetSpawned' );
		RegisterToCallback( 'OnSelected', this, 'OnSelected' );
	}

	protected event OnWidgetSpawned( widget : inkWidget, userData : IScriptable )
	{
		m_widget = ( ( InventoryItemDisplayController )( widget.GetController() ) );
		SetupData();
	}

	private function AnimateOpacity()
	{
		var barProgress : inkAnimDef;
		var opacityInterpolator : inkAnimTransparency;
		var options : inkAnimOptions;
		var animDuration : Float;
		animDuration = 0.34999999;
		if( m_data.Delay > 0.0 )
		{
			inkWidgetRef.SetOpacity( m_root, 0.0 );
			opacityInterpolator = new inkAnimTransparency;
			opacityInterpolator.SetDuration( animDuration );
			opacityInterpolator.SetStartTransparency( inkWidgetRef.GetOpacity( m_root ) );
			opacityInterpolator.SetEndTransparency( 1.0 );
			opacityInterpolator.SetType( inkanimInterpolationType.Quintic );
			opacityInterpolator.SetMode( inkanimInterpolationMode.EasyInOut );
			barProgress = new inkAnimDef;
			barProgress.AddInterpolator( opacityInterpolator );
			options.executionDelay = m_data.Delay;
			inkWidgetRef.PlayAnimationWithOptions( m_root, barProgress, options );
			m_data.Delay = 0.0;
		}
	}

	protected event OnDataChanged( value : Variant )
	{
		m_data = ( ( RipperdocWrappedUIInventoryItem )( ( ( IScriptable )value ) ) );
		SetupData();
	}

	private function SetupData()
	{
		if( !( m_data ) || !( m_widget ) )
		{
			return;
		}
		m_widget.Setup( m_data.InventoryItem, m_data.DisplayContext, m_data.IsEnoughMoney, !( m_data.DisplayContext.IsVendorItem() ) );
		m_widget.SetBuybackStack( m_data.IsBuybackStack );
		m_widget.SetIsNewOverride( m_data.IsNew );
		m_widget.SetAdditionalData( m_data.AdditionalData );
		AnimateOpacity();
	}

	public function Update()
	{
		if( m_data )
		{
			m_widget.Setup( m_data.InventoryItem, m_data.DisplayContext, m_data.IsEnoughMoney, !( m_data.DisplayContext.IsVendorItem() ) );
			m_widget.SetBuybackStack( m_data.IsBuybackStack );
			m_widget.SetIsNewOverride( m_data.IsNew );
			m_widget.SetAdditionalData( m_data.AdditionalData );
			AnimateOpacity();
		}
	}

}

class RipperdocInventoryTemplateClassifier extends inkVirtualItemTemplateClassifier
{

	public export virtual function ClassifyItem( data : Variant ) : Uint32
	{
		return 0;
	}

}

