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

using DXLib.UI.Control;
using DXLib.UI.Control.Image;
using DXLib.UI.Control.Badge;
using DXLib.UI.Control.Button;

using DXLib.Data;
using DXLib.Utils;

namespace iStatVball3;

/*
 * Represents either the OUT or IN row in a lineup replace panel. Allows the user to select the player subbing/swapping
 * out or in.
 */
public class LineupReplaceRow : DXGridGestures
{
	/* Constants */

	// Player coming OUT or IN?
	public enum RowType
	{
		Out,
		In
	};

	// Colors
	private static readonly Color EmptyColor = DXColors.Light1;
	private static readonly Color NormalColor = DXColors.Light4;

	/* Events */
	public Action<LineupReplaceRow> RowTapped { get; set; }
	public Action Changed { get; set; }

	/* Properties */
	public bool IsEmpty => Player == null;
	public bool HasPosition => !string.IsNullOrEmpty( Position );

	// OUT or IN row?
	public bool IsOut => rowType == RowType.Out;
	public bool IsIn => rowType == RowType.In;

	// Player represented by this entry
	public Player Player { get; private set; }

	private string Position { get; set; }
	private bool IsAltNumber { get; set; }

	// Sub or swap?
	private bool IsSub => parent.IsSub;
	private bool IsSwap => parent.IsSwap;

	/* Fields */
	private readonly LineupReplace parent;

	// Out/In
	private readonly RowType rowType;

    // UI
    private readonly DXTextBadge typeBadge;

    private readonly DXButton positionBtn;
    private readonly DXLabel positionLbl;

    private readonly DXImageArea imageArea;
    private readonly DXNumberButton numberBtn;

    private readonly DXLabel firstLbl;
    private readonly DXLabel lastLbl;

	/* Methods */

	// NO UI in constructor
	public LineupReplaceRow( LineupReplace parent, RowType type )
    {
        this.parent = parent;
        rowType = type;

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

        BackgroundColor = EmptyColor;

        bool tablet = DXDevice.IsTablet;

        // Out/In
        typeBadge = new DXTextBadge
        {
            Text = DXString.GetUpper( IsOut ? "replace.out" : "replace.in" ),

            TextColor = DXColors.Light4,
            Color = IsOut ? DXColors.Negative : DXColors.Positive,
            Font = DXFonts.RobotoBold,
        };

        // Image
        imageArea = new DXImageArea()
        {
            DefaultIcon = "player",
            IconColor = DXColors.Light4
        };

        imageArea.SetImage( (ImageSource)null );

        // Number 
        numberBtn = new DXNumberButton
        {
            TextColor = DXColors.Light4,
            DisabledOpacity = 1.0,
			
            HasShadow = false,
            IsSticky = true,

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

        numberBtn.Init();
        
        LineBreakMode mode = tablet ? LineBreakMode.TailTruncation : LineBreakMode.NoWrap;

        // First Name
        firstLbl = new DXLabel
        {
            TextColor = DXColors.Dark1,
            FontResource = DXFonts.RobotoBold,

            LineBreakMode = mode,
            Vertical = LayoutOptions.End
        };

        // Last Name
        lastLbl = new DXLabel
        {
            TextColor = DXColors.Dark1,
            FontResource = DXFonts.RobotoBold,

            LineBreakMode = mode,
            Vertical = LayoutOptions.Start
        };

        // Position
        if ( IsIn )
        {
            // Sub uses button
            if ( IsSub )
            {
                positionBtn = new DXButton
                {
                    Type = DXButton.ButtonType.Action,
                    Font = DXFonts.Roboto,

                    Horizontal = LayoutOptions.Center,
                    Vertical = LayoutOptions.Center,

                    IsSticky = true,
                    ButtonTapped = OnPositionTapped,
                };
                
                positionBtn.Init();
            }
            // Swap always shows LIB label
            else
            {
                positionLbl = new DXLabel
                {
                    Text = DXString.GetUpper( "lineup.lib" ),

                    TextColor = DXColors.Dark3,
                    Font = DXFonts.RobotoBold,
                    LineBreakMode = LineBreakMode.NoWrap,

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

        // Register for events
        Tapped += OnTapped;
    }

    // Post construction initialization (components MUST be created in constructor)
    public void Init( Color color )
	{
		imageArea.Color = color;
		numberBtn.Color = color;
	}

    /* Entry */

    // Returns lineup entry represented by this row (DEEP COPY)
    public LineupEntry GetEntry()
    {
        return IsEmpty ? null : new LineupEntry
        {
            Position = Position,
            IsAltNumber = IsAltNumber,

            Player = Player,
            PlayerId = Player.RootId
        };
    }

    // Populates values for this row
    public void SetEntry( LineupEntry entry )
    {
        Player = entry.Player;
        Position = entry.Position;
        IsAltNumber = entry.IsAltNumber;
    }

    // Updates player displayed in this row
    public void SetPlayer( Player player )
    {
        Player = player;
        Position = IsOut ? null : (IsSub ? player?.FirstPosition( false ) : Lineup.LiberoKey);
        IsAltNumber = false;

		Update();
    }

    /* Update */

    // Updates display with current player entry
    public void Update()
	{
		BackgroundColor = IsEmpty? EmptyColor : NormalColor;
		imageArea.SetImage( Player?.ImageUrl );

		firstLbl.Text = Player?.FirstName!;
		lastLbl.Text = Player?.LastName!;

		numberBtn.Text = Player?.GetNumber( IsAltNumber );
		numberBtn.IsDisabled = !IsAltNumber;

		// Position NA for player coming out, fixed for swap
		if ( IsSub && IsIn )
		{
			positionBtn.Text = (Position == null) ? DXString.Get( "lineup.empty" ) : Position.ToUpper();
		}

		UpdateVisible();
	}

	// Updates visible state for all controls
	private void UpdateVisible()
	{
		bool visible = !IsEmpty;

		imageArea.IsVisible = visible;
		numberBtn.IsVisible = visible;
		firstLbl.IsVisible = visible;
		lastLbl.IsVisible = visible;

		// Position only on IN row
		if ( IsIn )
		{
			// Sub uses button
			if ( IsSub )
			{
				positionBtn.IsVisible = visible;
			}
			// Swap always shows LIB
			else
			{
				positionLbl.IsVisible = visible;
			}
		}
	}

	/* Validation */

	// Determines if this row contains specified player
	public bool HasPlayer( Player player )
	{
		return !IsEmpty && Player.Equals( player );
	}

	// IN row requires position
	public bool IsValid()
	{
		return IsOut || !string.IsNullOrEmpty( Position );
	}

	/* Event Callbacks */

	// User tapped anywhere within row
	private void OnTapped( object sender, MR.Gestures.TapEventArgs args )
	{
		if ( IsOut || IsSwap || !positionBtn.Bounds.Contains( args.Center ) )
		{
			RowTapped?.Invoke( this );
		}
	}

	// POSITION

	// User tapped to change IN position
	private void OnPositionTapped( object sender )
	{
		// Show menu (highlight current value)
		DXMenu menu = new()
		{
			Title = "lineup.position",
			MenuWd = 225,

			ItemSelected = OnPositionSelected,
			Cancelled = OnPositionCancelled
		};

		menu.SetItems( Lineup.GetPositions(), Position );
		menu.ShowFromView( positionBtn );
	}

	// User selected position from popup menu
	private void OnPositionSelected( DXItem item )
	{
		// User may have cancelled
		if ( item != null )
		{
			Position = item.Key;

			positionBtn.Text = item.Key.ToUpper();
		}

		positionBtn.Reset();

		// Notify change
		Changed?.Invoke();
	}

	// User cancelled position selection
	private void OnPositionCancelled()
	{
		positionBtn.Reset();
	}

	/* Layout */

	// Redraws entire player row
	public override void UpdateLayout( LayoutType type )
	{
		ClearAll();

		bool ios = DXDevice.IsIOS;
		bool tablet = DXDevice.IsTablet;
		bool narrow = DXDevice.IsMobilePortrait();
		bool wide = DXDevice.IsWideLandscape();

		double dim = DXDevice.GetScreenDim();

		Padding = 0;
		RowSpacing = 0;
		ColumnSpacing = (dim * (tablet ? 0.003 : 0.004));

		// Component sizes
		double imageSize = (dim * (tablet ? 0.040 : 0.038));
		double numberSize = (dim * (narrow ? 0.021 : (wide ? 0.024 : 0.027)));

		// Font sizes
		double badgeSize = (dim * (wide ? 0.011 : 0.012));
		double numSize = (dim * (narrow ? 0.011 : (wide ? 0.015 : 0.017)));
		double nameSize = (dim * (wide ? 0.011 : (narrow ? (ios ? 0.015 : 0.016) : 0.015)));

		double posWd = (dim * (tablet ? (wide ? 0.030 : 0.035) : 0.030));
		double postHt = (dim * 0.028);
		double posSize = (dim * 0.012);

		// 3 rows
		AddStarRow( 22 );								// 0: badge
		AddStarRow( 39 );								// 1: first
		AddStarRow( 39 );								// 2: last

		// 4 columns
		AddStarColumn( 25 );							// 0: image
		AddStarColumn( 13 );							// 1: number
		AddStarColumn( 38 );							// 2: first/last
		AddStarColumn( 24 );							// 3: position

		// Out/In
		typeBadge.FontSize = badgeSize;
		typeBadge.Adjust( 0, (ios ? -2 : (wide ? -6 : -4)) );
		Add( typeBadge, 0, 0, 4, 1 );

		// Image
		imageArea.SetSize( imageSize, imageSize, 0.80 );
		Add( imageArea, 0, 1, 1, 2 );

		// Number
		numberBtn.Margin = 0;
		numberBtn.Size = numberSize;
		numberBtn.FontSize = numSize;
		numberBtn.TextAdjustY = (ios ? 0 : -6);

		Add( numberBtn, 1, 1, 1, 2 );

		// First
		firstLbl.FontSize = nameSize;
		Add( firstLbl, 2, 1 );

		// Last
		lastLbl.FontSize = nameSize;
		Add( lastLbl, 2, 2 );

		// Position
		if ( IsIn )
		{
			// Button
			if ( IsSub )
			{
				positionBtn.Margin = 0;
				positionBtn.FontSize = posSize;
				positionBtn.SetSize( posWd, postHt );

				Add( positionBtn, 3, 1, 1, 2 );
			}
			// LIB
			else
			{
				positionLbl.FontSize = posSize;

				Add( positionLbl, 3, 1, 1, 2 );
			}
		}
	}
}

//
