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

using DXLib.Video;
using DXLib.Video.Source;

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

using DXLib.Utils;

namespace iStatVball3;

/*
 * Wrapper for the native video player that allows video content to be played within any layout of the app. Video can be
 * played from multiple sources.
 */
public class VideoPlayer : DXAbsoluteGestures
{
	/* Constants */

	// Background color
	public static readonly Color DefaultColor = Colors.Black;
	
	// Clock update interval (ms)
	public const int ClockUpdate = 100;

	// 16:9 aspect ratio
	public const double RatioHt = 0.563;

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

	/* Properties */
	public bool Muted { set => player.Muted = value; }

	public bool IsLoading => player.IsLoading;
	public bool IsPlaying => player.IsPlaying;
	public bool IsStopped => player.IsStopped;

	// Native settings
	public DXVideoSource Source { set => player.Source = value; }
	public DXVideo.VideoStatus Status => player.Status;

	public TimeSpan Position { get => player.Position; set => player.Position = value; }
	public float Speed { set => player.Speed = value; }
	
	/* Fields */
	private readonly DXVideo player;
	private readonly VideoControls controls;

	private readonly DXContent loadingView;

	/* Methods */
	public VideoPlayer()
	{
		BackgroundColor = DefaultColor;

		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Fill;
		
		// Native player
		player = new DXVideo
		{
			AutoPlay = false,
			ShowControls = false,

			Ready = OnReady,
			Ended = OnEnded
		};

		Add( player );
		SetFullBounds( player );

		// Controls
		controls = new VideoControls( this );
		Add( controls );

		// Loading placeholder
		loadingView = new DXContent
		{
			Color = Colors.Black
		};

		DXLabel loadingLbl = new()
		{
			Resource = "alert.load",
			TextColor = DXColors.Dark4,

			Font = DXFonts.RobotoBoldItalic,
			FontSize = 24,

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

		loadingView.Content = loadingLbl;

		Add( loadingView );
		SetFullBounds( loadingView );
	}

	// Returns current playback offset (ms) from start of video
	public int GetOffset()
	{
		return (int) player.Position.TotalMilliseconds;
	}

	// Advances video to specified offset (ms) from start
	public void SeekTo( int offset )
	{
		player.Position = TimeSpan.FromMilliseconds( offset );

		UpdateTime();
	}

	// Forces update of elapsed time display in controls
	public void UpdateTime()
	{
		controls.Time = player.Position;
	}

	// Shows/hides 'Loading...' message
	private void ShowLoading( bool loading )
	{
		loadingView.IsVisible = loading;
	}

	/* Life Cycle */

	// Begins video playback
	public void Play()
	{
		player.Play();
	}

	// Pauses video playback
	public void Pause()
	{
		player.Pause();
	}

	// Stops video playback
	public void Stop()
	{
		player.Stop();

		UpdateTime();
	}

	/* Event Callbacks */

	// Video player done loading
	private void OnReady()
	{
		// Stop on first frame if not autoplaying
		if ( !player.AutoPlay )
		{
			Pause();
		}

		// Show video
		ShowLoading( false );

		// Callback listener
		Ready?.Invoke();
	}

	// Video played to completion
	private static void OnEnded()
	{}

	/* Layout */

	// Redraws entire video view
	public override void UpdateLayout( LayoutType type )
	{
		// Update children
		controls.UpdateLayout( LayoutBounds.Width );

		// Controls centered at bottom of video
		const double pad = 10;

		double controlsWd = controls.GetWidth();
		double controlsHt = controls.GetHeight();

		double controlsX = (LayoutBounds.Width - controlsWd) / 2;
		double controlsY = (LayoutBounds.Height - controlsHt - pad);

		SetBounds( controls, controlsX, controlsY, controlsWd, controlsHt );
	}
}

//
