/* 
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information 
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC. 
 */

using DXLib.UI;

using DXLib.UI.Layout;
using DXLib.UI.Control;
using DXLib.UI.Gestures;
using DXLib.UI.Container;

using DXLib.Data;
using DXLib.Utils;

namespace iStatVball3;

/*
 * A popup menu used to choose a single item from a list of text items. The menu has a title and shows current
 * selection state. 
 */ 
public class DXMenu
{
	/* Constants */
	private const double DefaultMenuWd = 240;
	private const int TapDelay = 250;
	
	// Colors
	private readonly Color Color = DXColors.Light4;
	private readonly Color SelectedColor = DXColors.Accent1;
	private readonly Color TapColor = DXColors.Light2;

	/* Events */
	public Action<DXItem> ItemSelected { get; set; }
	public Action Cancelled { get; set; }

	/* Properties */
	public string Title { get; set; }

	// Icon support
	public bool HasIcons { get; set; }
	public string DefaultIcon { get; set; }

	public Color IconColor { get; set; }
	public double IconAdjustY { get; set; }

	// Allows custom sizing
	public double MenuWd { get; set; }
	public double MenuHt { get; set; }

	/* Fields */
	private readonly DXGridLayout layout;
	
	private DXPopup popup;
	private DXItem selectedItem;
	
	/* Methods */
	public DXMenu()
	{
		// Underlying view
		layout = new DXGridLayout
		{
			BackgroundColor = DXColors.Light4,

			Padding = new Thickness( 0, 10 ),
			RowSpacing = 0,
			ColumnSpacing = 0,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};
		
		// Defaults
		MenuWd = DefaultMenuWd;
	}

	// Populates menu with specified items and text color for each item
	public void SetItems( List<DXItem> items, List<Color> colors )
	{
		SetItems( items, colors, null );
	}

	// Populates menu with specified items and optional initial selection
	public void SetItems( List<DXItem> items, string selected = null )
	{
		SetItems( items, null, selected );
	}

	// Populates menu
	private void SetItems( List<DXItem> items, List<Color> colors, string selected )
	{
		const double iconSize = 26;

		// Sizing
		const double rowPad = 7;
		const double rowHt = (iconSize + (rowPad * 2));

		// Add each item
		for ( int i = 0; i < items.Count; i++ )
		{
			DXItem item = items[i];

			// Row has solid background
			DXContentGestures row = new()
			{
				Data = item,

				Padding = new Thickness( 10, rowPad, 10, rowPad ),
				BackgroundColor = (item.Key == selected) ? SelectedColor : Color
			};

			row.Tapped += OnRowTapped;

			// Inner layout to support icon/text
			DXGridLayout rowLayout = new()
			{
				Padding = 0,
				RowSpacing = 0,
				ColumnSpacing = 8,

				Horizontal = LayoutOptions.Fill,
				Vertical = LayoutOptions.Fill
			};

			// Icon (optional)
			if ( HasIcons )
			{
				DXIcon itemIcon = new()
				{
					Resource = DefaultIcon ?? $"{item.Key}.png",
					Size = iconSize,

					Horizontal = LayoutOptions.Center,
					Vertical = LayoutOptions.Center
				};

				rowLayout.AddFixedColumn( iconSize );
				rowLayout.Add( itemIcon, 0, 0 );
			}

			// Label
			DXLabel itemLbl = new()
			{
				Text = item.Value,

				TextColor = DXColors.Dark1,
				Font = DXFonts.Roboto,
				FontSize = 17,

				VAlign = TextAlignment.Center,
				Vertical = LayoutOptions.Center
			};

			// Optional custom text color
			if ( colors != null )
			{
				itemLbl.TextColor = colors[i];
			}

			rowLayout.AddStarColumn();
			rowLayout.Add( itemLbl, (HasIcons ? 1 : 0), 0 );

			row.Content = rowLayout;

			// Append to list
			layout.AddFixedRow( rowHt );
			layout.Add( row, 0, (layout.RowCount - 1) );
		}

		int count = items.Count;

		// Dynamic sizing
		MenuHt = (count * rowHt) + ((count - 1) * layout.RowSpacing) + layout.Padding.VerticalThickness;
	}

	// Display menu in popup
	public void ShowFromView( View view, double adjustX = 0, double adjustY = 0 )
	{
		selectedItem = null;

		// Update size
		layout.WidthRequest = MenuWd;
		layout.HeightRequest = MenuHt;
		
		// Create popup
		popup = new DXPopup( Title, layout )
		{
			ViewWidth = MenuWd,
			ViewHeight = MenuHt,
			
			PopupClosed = OnPopupClosed
		};

		popup.ShowFromView( view, adjustX, adjustY );
	}

	/* Event Callbacks */

	// Individual row from menu was tapped
	private void OnRowTapped( object sender, MR.Gestures.TapEventArgs args )
	{
		if ( sender is DXContentGestures row )
		{
			Color prevColor = row.BackgroundColor;

			// Show tap as color change
			row.BackgroundColor = TapColor;

			// Return to normal after brief delay
			DXTimer.Delay( TapDelay, () =>
			{
				row.BackgroundColor = prevColor;

				// Remember selection
				selectedItem = row.Data as DXItem;

				// Callback listener
				ItemSelected?.Invoke( selectedItem );

				popup.Hide();
			});
		}
	}

	// Callback listener when menu cancelled
	private void OnPopupClosed()
	{
		if ( selectedItem == null )
		{
			Cancelled?.Invoke();
		}
	}
}

//
