/* 
 * 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.Alert;
using DXLib.UI.Layout;
using DXLib.UI.Control;

using DXLib.Utils;

namespace iStatVball3;

/*
 * UI control used to encapsulate the Starters, Subs, and Swaps control panels. A segment control is used to switch
 * between panels.
 */
public class LineupControl : DXGridLayout
{
	/* Constants */

	// Panel keys
	private const string StartersKey = "starters";
	private const string SubsKey = "subs";
	private const string SwapsKey = "swaps";

	/* Events */
	public Action Changed { get; set; }

	/* Properties */
	public bool IsEditEnabled { get; set; }

	// Full player list
	public IList<Player> Roster { get; set; }

	// Access to current panel data
	public IList<LineupEntry> Starters => starters.GetEntries();
	public IList<LineupEntryReplace> Subs => subs?.GetEntries();
	public IList<LineupEntryReplace> Swaps => swaps?.GetEntries();

	// Custom color
	public Color Color { get; set; }

	/* Fields */
	private DXSegmentBar segmentBar;
	private LineupPanel activeLayout;

	// Panels
	private readonly LineupStarter starters;
	private readonly LineupReplace subs;
	private readonly LineupReplace swaps;

	/* Methods */

	// NO UI in constructor
	public LineupControl()
	{
		// Starters
        starters = new LineupStarter
        {
            Changed = OnChanged
        };

		// Subs
        subs = new LineupReplace( starters, LineupEntryReplace.SubKey )
        {
            Changed = OnChanged
        };

        // Swaps
        swaps = new LineupReplace( starters, LineupEntryReplace.SwapKey )
        {
            Changed = OnChanged
        };
    }

    // Post construction initialization
    public void Init()
	{
		BackgroundColor = Color;

		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Fill;
		
		// Starters/Subs/Swaps
		segmentBar = new DXSegmentBar()
		{
			FillColor = Color,
			TextColor = DXColors.Light4,
			SelectColor = DXColors.Light4,

			SegmentWd = 120,
			SegmentHt = 35,
			SegmentFontSize = 15,

			Mode = DXSegmentBar.SegmentMode.Text,
			
			Horizontal = LayoutOptions.Center,
			Vertical = LayoutOptions.Fill,

			Selected = OnSelected
		};

		segmentBar.Init();

		// Add segments
		segmentBar.AddSegment( StartersKey, "lineup.starter" );
		segmentBar.AddSegment( SubsKey, "lineup.sub" );
		segmentBar.AddSegment( SwapsKey, "lineup.swap" );

		// 1 column
		AddStarColumn();

		// 2 rows
		AddFixedRow( 47 );		// 0: segment
		AddStarRow();			// 1: grid

		// Add components
		Add( segmentBar, 0, 0 );
		
		// Start with starters selected
		segmentBar.SelectedKey = StartersKey;
	}

	/* Lineup */

	// Sets all underlying lineup data
	public void SetLineup( Lineup lineup )
	{
		starters.SetEntries( lineup?.Entries );
		subs.SetEntries( lineup?.Subs );
		swaps.SetEntries( lineup?.Swaps );
	}

	/* Update */

	// Forces data update for all panel components
	public void Update()
	{
		starters.Update();
		subs.Update();
		swaps.Update();
	}

	/* Validate */

	// Performs full validation for starting lineup, subs, and swaps
	public bool Validate()
	{
		List<LineupEntry> entries = starters.GetEntries();

		// Starting lineup
		if ( !RecordLineup.Validate( entries, false ) )
		{
			return false;
		}

		// Subs
		if ( subs.IsInitialized )
		{
			int zone = subs.Validate();

			// Invalid player/position in sub chart
			if ( zone > 0 )
			{
				DXAlert.ShowError( "replace.sub", "replace.sub.invalid", zone.ToString() );
				return false;
			}

			Player player = subs.FindDuplicate( false );

			// Player subbed in/out more than once
			if ( player != null )
			{
				string playerStr = player.GetNumberName( true );

				DXAlert.ShowError( "replace.sub", "replace.sub.dup", playerStr );
				return false;
			}
		}

		// Swaps
		if ( swaps.IsInitialized )
		{
			int zone = swaps.Validate();

			// Invalid player in swap chart
			if ( zone > 0 )
			{
				DXAlert.ShowError( "replace.swapin", "replace.swapin.invalid", zone.ToString() );
				return false;
			}

			Player player = swaps.FindDuplicate( true );

			// Player swapped out more than once
			if ( player != null )
			{
				string playerStr = player.GetNumberName( true );

				DXAlert.ShowError( "replace.swapin", "replace.swapin.dup", playerStr );
				return false;
			}
		}

		// All valid
		return true;
	}

	// Determines if any panel has pending changes
	public bool HasChanges()
	{
		return starters.HasChanges || (subs is { HasChanges: true }) || (swaps is { HasChanges: true });
	}

	/* Select */

	// Changes focus to Starters panel
	public void SelectStarters()
	{
		// Layout if necessary
		if ( !starters.IsInitialized )
		{
			starters.Init( Roster, Color, IsEditEnabled );

			Add( starters, 0, 1 );
		}

		activeLayout = starters;

		Update();
		UpdateLayout();

		// Hide other panels
		ShowPanel( starters, true );
		ShowPanel( subs, false );
		ShowPanel( swaps, false );
	}

	// Changes focus to Subs panel
	private void SelectSubs()
	{
		// Layout if necessary
		if ( !subs.IsInitialized )
		{
			subs.Init( Roster, Color, IsEditEnabled );

			Add( subs, 0, 1 );
		}

		activeLayout = subs;

		Update();
        UpdateLayout();

        // Hide other panels
        ShowPanel( starters, false );
		ShowPanel( subs, true );
		ShowPanel( swaps, false );
	}

	// Changes focus to Swaps panel
	private void SelectSwaps()
	{
		// Create if necessary
		if ( !swaps.IsInitialized )
		{
			swaps.Init( Roster, Color, IsEditEnabled );

			Add( swaps, 0, 1 );
		}

		activeLayout = swaps;

		Update();
        UpdateLayout();

        // Hide other panels
        ShowPanel( starters, false );
		ShowPanel( subs, false );
		ShowPanel( swaps, true );
	}

	// Shows/hides specified control panel
	private void ShowPanel( LineupPanel panel, bool show )
	{
		if ( panel != null )
		{
			panel.IsVisible = show;
		}
	}

	/* Event Callbacks */

	// Used selected panel from segment control
	private void OnSelected( string key )
	{
		switch ( key )
		{
			case StartersKey: SelectStarters(); break;
			case SubsKey: SelectSubs(); break;
			case SwapsKey: SelectSwaps(); break;
		}
	}

	// Change was made in underlying panel, notify listener
	private void OnChanged()
	{
		Changed?.Invoke();
	}

	/* Layout */

	// Updates display of currently visible lineup control
	public override void UpdateLayout( LayoutType type )
	{
		bool tablet = DXDevice.IsTablet;

		bool portrait = DXDevice.IsPortrait();
		bool wide = DXDevice.IsTabletWide;
		bool portraitWide = (portrait && wide);

		double pad = tablet ? (wide ? 12 : 24) : 8;

		// Spacing
		RowSpacing = 0;
		ColumnSpacing = 0;

		// Dynamic padding
		Padding = new Thickness( pad, (pad / 5), pad, (portraitWide ? (pad * 3) : pad) );

		// Update children
		activeLayout?.UpdateLayout();
	}
}

//
