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

using DXLib.UI.Alert;
using DXLib.UI.Layout;
using DXLib.UI.Container;
using DXLib.UI.Control.Button;

using DXLib.Utils;

namespace DXLib.UI.Control.Image;

/*
 * Presents a popup control allowing the user to choose an existing image from the native photo gallery, take a new
 * photo using the camera, or clear the existing image. 
 */ 
public class DXImageSelector
{
	/* Events */
	public Action<ImageSource> ImageSelected { get; set; }

	/* Fields */
	private readonly DXPopup popup;

	private readonly DXButton chooseBtn;
	private readonly DXButton takeBtn;
	private readonly DXButton clearBtn;

	/* Methods */
	public DXImageSelector()
	{
		const double width = 180;
		const double height = 158;
		
		// Button stack
		DXVerticalLayout layout = new()
		{
			BackgroundColor = DXColors.Light4,

			Padding = new Thickness( 8, 15, 10, 10 ),
			Spacing = 10,

			WidthRequest = width,
			HeightRequest = height,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		const double buttonWd = 150;

		// Choose Photo
		chooseBtn = new DXButton
		{
			Resource = "form.image.choose",
			Type = DXButton.ButtonType.Positive,
			ButtonWd = buttonWd,

			IsSticky = true,
			ButtonTapped = OnChooseTapped,
		};

		layout.Add( chooseBtn );

		// Take Photo
		takeBtn = new DXButton
		{
			Resource = "form.image.take",
			Type = DXButton.ButtonType.Action,
			ButtonWd = buttonWd,

			IsSticky = true,
			ButtonTapped = OnTakeTapped,
		};

		layout.Add( takeBtn );

		// Clear Photo
		clearBtn = new DXButton
		{
			Resource = "form.image.clear",
			Type = DXButton.ButtonType.Negative,
			ButtonWd = buttonWd,

			IsSticky = true,
			ButtonTapped = OnClearTapped,
		};

		layout.Add( clearBtn );

		// Init popup
		popup = new DXPopup( "form.image.edit", layout )
		{
			ViewWidth = width,
			ViewHeight = height
		};
	}

	// Shows selector popup anchored to specified view
	public void Show( View anchor, bool hasImage )
	{
		clearBtn.IsDisabled = !hasImage;
		
		popup.ShowFromView( anchor );
	}

	// Dismisses selector popup
	public void Hide()
	{
		Reset();

		// Dismiss
		popup.Hide();
	}

	// Reset button sticky states
	private void Reset()
	{
		chooseBtn.Reset();
		takeBtn.Reset();
		clearBtn.Reset();
	}

	/* Event Callbacks */
	
	// Uses native chooser control to select photo from gallery
	private async void OnChooseTapped( object sender )
	{
		try
		{
			// Config
			MediaPickerOptions options = new()
			{
				Title = DXString.Get( "form.image.choose" ),
			};
	
			// Show native chooser control
			FileResult file = await MediaPicker.Default.PickPhotoAsync( options );

			if ( file == null )
			{
				throw new NullReferenceException();
			}

			// Read from stream to ImageSource
			Stream stream = await file.OpenReadAsync();
			ImageSource image = ImageSource.FromStream( () => stream );

			// Callback handler
			ImageSelected?.Invoke( image );
		}
		catch ( Exception )
		{
			DXAlert.ShowError( "form.image.choose", "form.image.err.choose", Reset );
		}
	}

	// Uses native camera control to take new photo
	private async void OnTakeTapped( object sender )
	{
		IMediaPicker media = MediaPicker.Default;

		// Make sure camera accessible
		if ( media.IsCaptureSupported )
		{
			// Config
			MediaPickerOptions options = new()
			{
				Title = DXString.Get( "form.image.take" ),
			};

			// Show native camera control
			FileResult file = await media.CapturePhotoAsync( options );

			if ( file == null )
			{
				throw new NullReferenceException();
			}
			
			// Read from stream to ImageSource
			Stream stream = await file.OpenReadAsync();
			ImageSource source = ImageSource.FromStream( () => stream );

			// Callback handler
			ImageSelected?.Invoke( source );
		}
		else
		{
			DXAlert.ShowError( "form.image.take", "form.image.err.take", Reset );
		}
	}

	// Clears currently selected photo
	private void OnClearTapped( object sender )
	{
		ImageSelected?.Invoke( null );
	}
}

//
