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

using DXLib.UI.Layout;
using DXLib.UI.Control;
using DXLib.UI.Control.Checkbox;

using DXLib.Utils;

namespace DXLib.UI.Form.Control;

/*
 * A form control containing a simple 2-state checkbox. The normal control title is not used. Other control elements
 * remain the same. 
 */
public class DXCheckboxField : DXFormControl
{
	/* Constants */
	private new const double DisabledOpacity = 0.2;

	/* Events */

	// Only used outside of form
	public Action CheckboxToggled { get; set; }

	/* Properties */
	public bool Checked { get => isChecked; set => SetChecked( value ); }
	public bool HasLine { set => line.IsVisible = value; }

	public string Text { set => checkboxLbl.Text = DXString.Get( value ); }

	/* Fields */
	private readonly DXGridLayout layout;

	private readonly DXLabel checkboxLbl;
	private readonly DXCheckbox checkbox;

	private bool internalChange;
	private bool isChecked;

	/* Methods */
	public DXCheckboxField()
	{
		// Normal title not used
		Title = "form.empty";

		Padding = 0;
        Margin = 0;

        // Account for no title
        HeightRequest -= 20;

		// Layout
		layout = new DXGridLayout()
		{ 
			Padding = 0,
			Margin = 0,
			
			ColumnSpacing = 5,
			HeightRequest = DefaultControlHt,

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

		// Label
		checkboxLbl = new DXLabel
		{
			Padding = 0,
			Margin = new Thickness( 0, 8, 0, 0 ),

			TextColor = DXColors.Dark1,
			FontResource = DXFonts.Roboto,
			FontSize = 17,

			Horizontal = LayoutOptions.Start,
			Vertical = LayoutOptions.Fill
		};
		
		// Checkbox (do NOT set disabled color or margin/padding here)
		checkbox = new DXCheckbox
		{
			Horizontal = LayoutOptions.Center,
			Vertical = LayoutOptions.Center,
			
			ValueChanged = OnValueChanged
		};

		// 2 columns, 1 row
		layout.AddStarColumn();									// 0: label
		layout.AddFixedColumn( DXCheckbox.DefaultSize );		// 1: checkbox

		layout.Add( checkboxLbl, 0, 0 );
		layout.Add( checkbox, 1, 0 );
	}

	// Disables extended controls
	public override void SetDisabled( bool disabled )
	{
		base.SetDisabled( disabled );

		double opacity = disabled ? DisabledOpacity: 1.0;

		// Disable checkbox specific controls
		checkboxLbl.Opacity = opacity;
		checkbox.Opacity = opacity;
	}

	// Used internally to toggle checked state
	private void SetChecked( bool value )
	{
		// Only update if value changed by user
		if ( value != isChecked )
		{
			isChecked = value;
			internalChange = true;

			checkbox.IsChecked = value;
		}
	}

	/* Abstracts */

	// Insert in parent layout
	public override void Init()
	{
		AddControl( layout );
	}

	// Returns current checkbox value as boolean
	public override object GetObject()
	{
		return checkbox.IsChecked;
	}

	// Nothing to do here
	public override void SetPlaceholder( bool focused )
	{}

	// Always has value
	public override bool HasValue()
	{
		return true;
	}

	// Should always be valid
	public override bool IsValid()
	{
		return true;
	}

	/* Event Callbacks */

	// Only available event callback for underlying control
	private void OnValueChanged( DXCheckbox control )
	{
		// Only trigger events if value changed by user
		if ( !internalChange && (control.IsChecked != isChecked) )
		{
			if ( control.IsChecked != null )
			{
				isChecked = (bool)control.IsChecked;

				OnFocus();
				OnChange();

				// Might not be within form
				CheckboxToggled?.Invoke();
			}
		}

		internalChange = false;
	}
}

//
