class RadialMenuHubLogicController extends inkLogicController
{
	private editable var m_menuObject : inkWidgetRef;
	private editable var m_btnCrafting : inkWidgetRef;
	private editable var m_btnPerks : inkWidgetRef;
	private editable var m_btnStats : inkWidgetRef;
	private editable var m_btnInventory : inkWidgetRef;
	private editable var m_btnBackpack : inkWidgetRef;
	private editable var m_btnCyberware : inkWidgetRef;
	private editable var m_btnMap : inkWidgetRef;
	private editable var m_btnJournal : inkWidgetRef;
	private editable var m_btnPhone : inkWidgetRef;
	private editable var m_btnTarot : inkWidgetRef;
	private editable var m_btnShard : inkWidgetRef;
	private editable var m_btnCodex : inkWidgetRef;
	private editable var m_panelInventory : inkWidgetRef;
	private editable var m_panelMap : inkWidgetRef;
	private editable var m_panelJournal : inkWidgetRef;
	private editable var m_panelCharacter : inkWidgetRef;
	private editable var m_mouseCollider : inkWidgetRef;
	private editable var m_debugText : inkTextRef;
	private var m_menusData : MenuDataBuilder;
	private var m_tooltipsManager : weak< gameuiTooltipsManager >;
	private editable var m_tooltipsManagerRef : inkWidgetRef;
	private var m_windowSize : Vector2;
	private var m_previousMenuElement : RadialHubMenuElement;
	private var m_hoveredButtons : array< Int32 >;
	private var m_isActive : Bool;
	private var m_timeSkipOpened : Bool;

	protected event OnInitialize()
	{
		m_tooltipsManager = ( ( gameuiTooltipsManager )( inkWidgetRef.GetControllerByType( m_tooltipsManagerRef, 'gameuiTooltipsManager' ) ) );
		m_tooltipsManager.Setup( ETooltipsStyle.Menus );
		SetHoverPanel( m_panelInventory );
		SetHoverPanel( m_panelJournal );
		SetHoverPanel( m_panelCharacter );
		SetHoverPanel( m_panelMap );
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnGlobalRelease' );
		SetActive( true );
	}

	protected event OnGlobalRelease( e : inkPointerEvent )
	{
		if( ( ( e.IsAction( 'click' ) && !( m_timeSkipOpened ) ) && m_isActive ) && ( m_hoveredButtons.Size() == 0 ) )
		{
			OpenElement( m_previousMenuElement );
		}
	}

	public function SetWindowSize( size : Vector2 )
	{
		m_windowSize = size;
	}

	public function SetTimeSkipOpened( value : Bool )
	{
		m_timeSkipOpened = value;
	}

	public function SetButtonHoverOver( buttonId : Int32 )
	{
		m_hoveredButtons.PushBack( buttonId );
	}

	public function SetButtonHoverOut( buttonId : Int32 )
	{
		m_hoveredButtons.Remove( buttonId );
	}

	public function SetUnhover()
	{
		SetElementState( m_previousMenuElement, 'Default' );
		PlayHoverAnimation( m_panelHoverOutAnimProxy, m_previousMenuElement, true );
		m_previousMenuElement = RadialHubMenuElement.None;
	}

	public function SetHover( currentMenuElement : RadialHubMenuElement )
	{
		if( m_timeSkipOpened )
		{
			return;
		}
		if( m_previousMenuElement != currentMenuElement )
		{
			SetElementState( m_previousMenuElement, 'Default' );
			SetElementState( currentMenuElement, 'CellHover' );
			PlayHoverAnimation( m_panelHoverOutAnimProxy, m_previousMenuElement, true );
			PlayHoverAnimation( m_panelHoverOverAnimProxy, currentMenuElement );
			m_previousMenuElement = currentMenuElement;
		}
	}


	private var m_panelHoverOverAnimProxy : inkAnimProxy;
	private var m_panelHoverOutAnimProxy : inkAnimProxy;

	private function PlayHoverAnimation( animProxy : inkAnimProxy, menuTarget : RadialHubMenuElement, optional playReverse : Bool )
	{
		var playbackOptions : inkAnimOptions;
		if( animProxy )
		{
			animProxy.Stop();
			animProxy = NULL;
		}
		playbackOptions.playReversed = playReverse;
		if( menuTarget == RadialHubMenuElement.Inventory )
		{
			animProxy = PlayLibraryAnimation( 'inventory_hover', playbackOptions );
		}
		else if( menuTarget == RadialHubMenuElement.Map )
		{
			animProxy = PlayLibraryAnimation( 'map_hover', playbackOptions );
		}
		else if( menuTarget == RadialHubMenuElement.Character )
		{
			animProxy = PlayLibraryAnimation( 'character_hover', playbackOptions );
		}
		else if( menuTarget == RadialHubMenuElement.Journal )
		{
			animProxy = PlayLibraryAnimation( 'journal_hover', playbackOptions );
		}
	}

	public function OpenElement( hubMenuElement : RadialHubMenuElement )
	{
		var widget : inkWidgetRef;
		if( hubMenuElement != RadialHubMenuElement.None )
		{
			widget = RadialHubMenuElementToWidget( hubMenuElement );
			( ( RadialMenuItemController )( inkWidgetRef.GetController( widget ) ) ).RequestMenuSelect();
		}
	}

	private function SetElementState( hubMenuElement : RadialHubMenuElement, state : CName )
	{
		var widget : inkWidgetRef;
		if( hubMenuElement != RadialHubMenuElement.None )
		{
			widget = RadialHubMenuElementToWidget( hubMenuElement );
			inkWidgetRef.SetState( widget, state );
		}
	}

	private function GetRadialHubMenuElementFromAngle( angle : Float ) : RadialHubMenuElement
	{
		if( ( angle < 45.0 ) || ( angle >= 315.0 ) )
		{
			return RadialHubMenuElement.Journal;
		}
		else if( ( angle >= 45.0 ) && ( angle < 135.0 ) )
		{
			return RadialHubMenuElement.Character;
		}
		else if( ( angle >= 135.0 ) && ( angle < 225.0 ) )
		{
			return RadialHubMenuElement.Inventory;
		}
		return RadialHubMenuElement.Map;
	}

	private function RadialHubMenuElementToWidget( hubMenuElement : RadialHubMenuElement ) : inkWidgetRef
	{
		if( hubMenuElement == RadialHubMenuElement.Journal )
		{
			return m_panelJournal;
		}
		else if( hubMenuElement == RadialHubMenuElement.Map )
		{
			return m_panelMap;
		}
		else if( hubMenuElement == RadialHubMenuElement.Inventory )
		{
			return m_panelInventory;
		}
		return m_panelCharacter;
	}

	private function WidgetToRadialHubElement( hubMenuElement : weak< inkWidget > ) : RadialHubMenuElement
	{
		if( hubMenuElement == inkWidgetRef.Get( m_panelJournal ) )
		{
			return RadialHubMenuElement.Journal;
		}
		else if( hubMenuElement == inkWidgetRef.Get( m_panelMap ) )
		{
			return RadialHubMenuElement.Map;
		}
		else if( hubMenuElement == inkWidgetRef.Get( m_panelInventory ) )
		{
			return RadialHubMenuElement.Inventory;
		}
		else if( hubMenuElement == inkWidgetRef.Get( m_panelCharacter ) )
		{
			return RadialHubMenuElement.Character;
		}
		return RadialHubMenuElement.None;
	}

	public function SetHoverPanel( hoverPanel : inkWidgetRef )
	{
		if( inkWidgetRef.IsValid( hoverPanel ) )
		{
			inkWidgetRef.RegisterToCallback( hoverPanel, 'OnEnter', this, 'OnHoverPanelOver' );
			inkWidgetRef.RegisterToCallback( hoverPanel, 'OnLeave', this, 'OnHoverPanelOut' );
		}
	}

	protected event OnHoverPanelOver( evt : inkPointerEvent )
	{
		SetHover( WidgetToRadialHubElement( evt.GetCurrentTarget() ) );
	}

	protected event OnHoverPanelOut( evt : inkPointerEvent )
	{
		SetUnhover();
	}

	protected event OnUninitialize()
	{
		SetActive( false );
	}

	protected event OnOldSelectByCursor( evt : SelectMenuRequest )
	{
		var currentMenuItem : MenuItemController;
		var openMenuEvt : OpenMenuRequest;
		currentMenuItem = evt.m_eventData;
		if( currentMenuItem )
		{
			openMenuEvt = new OpenMenuRequest;
			openMenuEvt.m_eventData = currentMenuItem.m_menuData;
			openMenuEvt.m_isMainMenu = true;
			openMenuEvt.m_jumpBack = currentMenuItem.IsHyperlink();
			QueueEvent( openMenuEvt );
		}
	}

	protected event OnSelectByCursor( evt : RadialSelectMenuRequest )
	{
		var currentMenuItem : RadialMenuItemController;
		var openMenuEvt : OpenMenuRequest;
		currentMenuItem = evt.m_eventData;
		if( currentMenuItem )
		{
			openMenuEvt = new OpenMenuRequest;
			openMenuEvt.m_eventData = currentMenuItem.m_menuData;
			openMenuEvt.m_isMainMenu = true;
			openMenuEvt.m_jumpBack = currentMenuItem.IsHyperlink();
			QueueEvent( openMenuEvt );
		}
	}

	public function SetMenusData( menuData : MenuDataBuilder, tarotIsBlocked : Bool, mapIsBlocked : Bool, perkPoints, attrPoints : Int32 )
	{
		var dataCharacter, dataTarot, dataMap : MenuData;
		m_menusData = menuData;
		HubMenuUtils.SetRadialMenuData( m_btnCrafting, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Crafting ) ) ) );
		dataCharacter = m_menusData.GetData( ( ( Int32 )( HubMenuItems.Character ) ) );
		dataCharacter.attrFlag = attrPoints > 0;
		dataCharacter.perkFlag = perkPoints > 0;
		dataCharacter.attrText = ( ( Int32 )( attrPoints ) );
		dataCharacter.perkText = ( ( Int32 )( perkPoints ) );
		dataTarot = m_menusData.GetData( ( ( Int32 )( HubMenuItems.Tarot ) ) );
		if( tarotIsBlocked )
		{
			dataTarot.disabled = true;
		}
		dataMap = m_menusData.GetData( ( ( Int32 )( HubMenuItems.Map ) ) );
		if( mapIsBlocked )
		{
			dataMap.disabled = true;
		}
		HubMenuUtils.SetRadialMenuData( m_panelInventory, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Inventory ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_panelMap, dataMap );
		HubMenuUtils.SetRadialMenuData( m_panelJournal, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Journal ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_panelCharacter, dataCharacter );
		HubMenuUtils.SetRadialMenuData( m_btnPerks, dataCharacter );
		HubMenuUtils.SetRadialMenuData( m_btnStats, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Stats ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnInventory, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Inventory ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnBackpack, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Backpack ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnCyberware, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Cyberware ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnMap, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Map ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnJournal, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Journal ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnPhone, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Phone ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnTarot, dataTarot );
		HubMenuUtils.SetRadialMenuData( m_btnCodex, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Codex ) ) ) );
		HubMenuUtils.SetRadialMenuData( m_btnShard, m_menusData.GetData( ( ( Int32 )( HubMenuItems.Shards ) ) ) );
	}

	public function SetActive( isActive : Bool )
	{
		m_isActive = isActive;
		inkWidgetRef.SetVisible( m_menuObject, isActive );
		if( isActive )
		{
			RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnSelectByButton' );
		}
		else
		{
			UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnSelectByButton' );
		}
	}

	public function SelectMenuExternally( menuName : CName, optional submenuName : CName, optional userData : IScriptable )
	{
		var evt : OpenMenuRequest;
		var subMenuData : array< MenuData >;
		var evtMenuData : MenuData;
		evt = new OpenMenuRequest;
		evt.m_menuName = menuName;
		if( userData )
		{
			evt.m_eventData.userData = userData;
			evt.m_eventData.m_overrideDefaultUserData = true;
			if( IsNameValid( submenuName ) )
			{
				evtMenuData.userData = userData;
				subMenuData.PushBack( evtMenuData );
				evt.m_eventData.subMenus = subMenuData;
				evt.m_eventData.m_overrideSubMenuUserData = true;
			}
		}
		evt.m_submenuName = submenuName;
		evt.m_isMainMenu = true;
		QueueEvent( evt );
	}

}

enum RadialHubMenuElement
{
	None = 0,
	Inventory = 1,
	Map = 2,
	Character = 3,
	Journal = 4,
}

