/* 
 * 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;

namespace iStatVball3;

/*
 * Manages display of an undo history stack with one text line for each stat in the undo stack. Each line fades in color
 * as it gets older. Stats are references into the database, they are NOT maintained separately here.
 */
public class ScoreUndo : DXGridLayout
{
	/* Constants */

	// Change stack depth here (max 6)
	private const int StackSize = 4;

	// Colors fade down history stack
	private readonly double[] AlphaScale = [ 1.00, 0.65, 0.40, 0.20 ];

	/* Properties */
	public RecordDb StateData { get; set; }

	// Generates undo lines
	public RecordHistory History { get; private set; }

	// Size of all labels in undo stack
	public double FontSize { set => UpdateFontSize( value ); }

	// Spacing between stack rows
	public double Spacing { set => RowSpacing = value; }

	// Special embedded sync mode?
	public bool IsSyncMode { get; set; }

	/* Fields */
	private readonly List<DXLabel> labels;

	// External refs
	private readonly RecordScore parent;

	/* Methods */
	public ScoreUndo( RecordScore parent )
	{
		this.parent = parent;

		BackgroundColor = DXColors.Dark2;

		// Layout
		Padding = 0;
		RowSpacing = 0;

		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Fill;

		// Grid rows (hold empty space)
		AddAutoRows( 4 );
		
		// Labels
		labels = new List<DXLabel>( StackSize );

		for ( int row = 0; row < StackSize; row++ )
		{
			DXLabel label = new()
			{
				Padding = 0,

				TextColor = DXColors.ColorWithAlpha( DXColors.Light2, AlphaScale[ row ] ),
				Font = DXFonts.Roboto,
				LineBreakMode = LineBreakMode.TailTruncation,

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

			labels.Add( label );
			Add( label, 0, row );
		}

		// Prep line creator
		History = new RecordHistory();
	}

	// Post construction initialization
	public void Init( Set set )
	{
		History.Init( set.Match );
	}

	// Re-displays undo stack with top N stats from state machine
	public void Update()
	{
		int count = StateData.StatCount;

		// Get top X stats for display
		for ( int i = 0; i < StackSize; i++ )
		{
			int index = (count - i - 1);
			Stat stat = StateData.GetStat( index );

			labels[i].Text = (i < count) ? History.CreateLine( stat ) : string.Empty;
		}

		bool empty = (count == 0);
		bool limit = empty || StateData.GetStat( count - 1 ).Persisted;
		
		// Undo invalid if stack empty or at undo limit
		parent.IsUndoDisabled = (empty || limit);
	}

	/* Layout */

	// Widescreen Portrait (10:16)
	protected override void WidePortrait()
	{
		UpdateLabels( 10, 7 );
	}

	// Mobile Landscape
	protected override void MobileLandscape()
	{
		UpdateLabels( 10, (Shell.IsLegacy ? 2 : 4) );
	}

	// Mobile Portrait
	protected override void MobilePortrait()
	{
		UpdateLabels( 11, (Shell.IsLegacy ? 5 : 3) );
	}

	// Updates all line labels to specified size and row spacing
	private void UpdateLabels( double size, double spacing )
	{
		ClearAll();

		// Rebuild grid to adjust row height
		for ( int row = 0; row < labels.Count; row++ )
		{
			DXLabel lineLbl = labels[ row ];

			lineLbl.FontSize = size;

			AddFixedRow( size + spacing );
			Add( lineLbl, 0, row );
		}
	}

	// Updates font size of all labels in stack
	private void UpdateFontSize( double size )
	{
		foreach ( DXLabel label in labels )
		{
			label.FontSize = size;
		}
	}
}

//
