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

using DXLib.UI.Form;
using DXLib.UI.Form.Control;

namespace iStatVball3;

/*
 * Implements a small data form for entering configuration options for set video sync. The form is displayed in a modal
 * popup.
 */
public class SetVideoForm
{
	/* Constants */
	private static readonly Color DefaultColor = DXColors.Light4;

	/* Events */
	public Action<SetVideo> Completed { get; set; }
	public Action Cancelled { get; set; }

	/* Fields */

	// UI components
	private readonly DXVerticalLayout layout;
	private readonly DXButton okBtn;
	private readonly DXPopup popup;

	// Controls
	private DXFormControlList controls;

	// External refs
	private readonly Match match;
	private readonly SetVideo video;

	/* Methods */
	public SetVideoForm( Match match, SetVideo video )
	{
		this.match = match;
		this.video = video;
		
		// Controls are stacked
		layout = new DXVerticalLayout
		{
			BackgroundColor = DefaultColor,

			Padding = 0,
			Spacing = 10,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		// Controls
		CreateControls();

		// Button layout
		DXHorizontalLayout btnLayout = new()
		{
			BackgroundColor = DXColors.Light4,
			
			Padding = 0,
			Spacing = 10,
			
			Horizontal = LayoutOptions.Center,
			Vertical = LayoutOptions.Start
		};
		
		// Cancel
		DXButton cancelBtn = new()
		{
			Resource = "alert.cancel",
			Type = DXButton.ButtonType.Neutral,
			ButtonWd = 75,

			ButtonTapped = OnCancelTapped
		};

		cancelBtn.Init();
		btnLayout.Add( cancelBtn );
		
		// OK
		okBtn = new DXButton
		{
			Resource = "alert.ok",
			Type = DXButton.ButtonType.Action,

			ButtonTapped = OnOkTapped
		};

		okBtn.Init();
		btnLayout.Add( okBtn );
		
		layout.Add( btnLayout );

		// Modal popup
		popup = new DXPopup( "video.title", layout )
		{
			IsModal = true,
			Padding = 0,
			
			ViewWidth = 350,
			ViewHeight = 155
		};
	}

	// Creates all form control fields
	private void CreateControls()
	{
		// Video setting fields
		controls = new DXFormControlList( false )
		{
			Padding = new Thickness( 24, 5, 24, 0 ),
			Color = DefaultColor,
			Title = null
		};

		bool hasData = (video != null);
		
		// Offset
		AddControl( new DXPicker
		{
			Key = "offset",
			Title = "video.offset",
			Type = DXPicker.PickerType.Duration,
			Duration = hasData ? TimeSpan.FromMilliseconds( video.Offset ) : TimeSpan.Zero,
			Hint = DXFormControl.HintType.Duration,
			Help = "video.offset",

			ControlChanged = UpdateOk
		});

		controls.Init();

		layout.Add( controls.View );
	}

	// Adds control to list
	private void AddControl( DXFormControl control, bool required = true )
	{
		controls.Add( control, required, false );
	}

	// Determines if any control has pending changes
	public bool HasChanges()
	{
		return controls.HasChanges();
	}

	// Determines if all controls have valid values
	public bool IsValid()
	{
		return controls.IsValid();
	}

	// Shows video settings in modal popup
	public void Show( View view )
	{
		UpdateOk();

		popup.ShowFromView( view, 0, 20 );
	}

	/* Update */

	// OK button only enabled if all controls valid
	private void UpdateOk()
	{
		if ( okBtn != null )
		{
			okBtn.IsDisabled = !IsValid();
		}
	}

	/* Get */

	// Returns populated video settings object
	private SetVideo GetVideo()
	{
		// May not have UI yet
		TimeSpan? duration = GetOffset().Duration;

		return new SetVideo
		{
			Offset = duration.HasValue ? (int)((TimeSpan)duration).TotalMilliseconds : SetVideo.OffsetUnknown
		};
	}

	// Convenience methods for accessing individual controls
	private DXPicker GetOffset() { return controls.GetControl( "offset" ) as DXPicker; }

	/* Event Callbacks */

	// User tapped OK button
	private void OnOkTapped( object sender )
	{
		// Get current configuration
		SetVideo newVideo = GetVideo();

		popup.Hide();

		// Callback listener
		Completed?.Invoke( newVideo );
	}
	
	// User cancelled modal popup
	private void OnCancelTapped( object sender )
	{
		popup.Hide();
		
		// Callback listener
		Cancelled?.Invoke();
	}
}

//
