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

using Syncfusion.Maui.Buttons;

namespace DXLib.UI.Control.Checkbox;

/*
 * A checkbox control with label, default styling, and an optional tri-state.
 */ 
public class DXCheckbox : SfCheckBox
{
	/* Constants */
	public const double DefaultSize = 36;

	// Colors
	public static readonly Color DefaultSelectedColor = DXColors.Positive;
	public static readonly Color DefaultDisabledColor = DXColors.Light1;
	
	public static readonly Color IndeterminateColor = DXColors.Warn;
	
	/* Events */
	public Action<DXCheckbox> ValueChanged { get; set; }
	public bool SuppressEvent { get; set; }

	/* Properties */
	public LayoutOptions Horizontal { set => HorizontalOptions = value; }
	public LayoutOptions Vertical { set => VerticalOptions = value; }

	public bool IsBold { set => FontAttributes = value ? FontAttributes.Bold : FontAttributes.None; }
	
	// Colors
	public Color SelectedColor { get; set; }
	public Color DisabledColor { set => SetDisabledColor( value ); }

	// Use indeterminate state?
	public bool IsTriState { set => IsThreeState = value; }

	// Lookup key when used in lists
	public string Key { get; set; }

	// Optional associated data
	public object Data { get; set; }

	/* Methods */
	public DXCheckbox()
	{
		Margin = 0;
		Padding = new Thickness( 5, 0, 0, 0 );			// REQUIRED workaround

		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Fill;
		
		CornerRadius = 4;
		
		// Colors
		CheckedColor = DXColors.Positive;
		UncheckedColor = DXColors.Dark1;
		TextColor = DXColors.Dark1;
		
		// Font
		FontFamily = DXFonts.Roboto;
		FontAttributes = FontAttributes.None;
		FontSize = 17;
		FontAutoScalingEnabled = false;

		// Border
		StrokeThickness = 1;
		EnabledAnimation = false;
		
		HorizontalTextAlignment = TextAlignment.Start;
		LineBreakMode = LineBreakMode.TailTruncation;

		// Register for events
		StateChanged += OnStateChanged;

		// Default
		SelectedColor = CheckedColor;
	}

	// Sets checkbox states to specified color
	public void SetColor( Color color, bool all = true )
	{
		CheckedColor = color;
		SelectedColor = color;
		UncheckedColor = all ? color : UncheckedColor;
	}

	// (Un)checks checkbox with option to suppress event
	public void SetChecked( bool check, bool quiet = false )
	{
		SuppressEvent = quiet;

		IsChecked = check;
	}

	// Sets custom disabled color via visual states
	private void SetDisabledColor( Color color )
	{
        // Disabled state
        VisualState disabled = new VisualState { Name = "Disabled" };

        disabled.Setters.Add( new Setter { Property = CheckedColorProperty, Value = color } );
        disabled.Setters.Add( new Setter { Property = UncheckedColorProperty, Value = color } );
        disabled.Setters.Add( new Setter { Property = TextColorProperty, Value = color } );
        disabled.Setters.Add( new Setter { Property = TickColorProperty, Value = color } );
        
        // Disabled Null state
        VisualState disabledNull = new VisualState { Name = "DisabledNull" };

        disabledNull.Setters.Add( new Setter { Property = CheckedColorProperty, Value = color } );
        disabledNull.Setters.Add( new Setter { Property = UncheckedColorProperty, Value = color } );
        disabledNull.Setters.Add( new Setter { Property = TextColorProperty, Value = color } );
        disabledNull.Setters.Add( new Setter { Property = TickColorProperty, Value = color } );

        VisualStateGroupList groupList = [];
        VisualStateGroup stateGroup = new();

        // Add states to group
        stateGroup.States.Add( disabled );
        stateGroup.States.Add( disabledNull );
        
        // Add group to list
		groupList.Add( stateGroup );

		VisualStateManager.SetVisualStateGroups( this, groupList );
	}
	
	/* Event Callbacks */

	// Callback listener when check value changes
	private void OnStateChanged( object sender, StateChangedEventArgs args )
	{
		bool isChecked = (args.IsChecked == true);

		// Set custom indeterminate color for tri-state checkboxes
		CheckedColor = isChecked ? SelectedColor : IndeterminateColor;
		
		// Callback listener
		if ( !SuppressEvent )
		{
			ValueChanged?.Invoke( this );
		}

		SuppressEvent = false;
	}
}

//
