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

using Microsoft.Maui.Layouts;

using DXLib.Utils;

namespace DXLib.UI.Gestures;

/*
 * Equivalent to DXAbsoluteLayout with the addition of support for up, down, and tap gestures.
 */ 
public class DXAbsoluteGestures : MR.Gestures.AbsoluteLayout
{
	/* Properties */
	public LayoutOptions Horizontal { set => HorizontalOptions = value; }
	public LayoutOptions Vertical { set => VerticalOptions = value; }

	// Programmatically set bounds, can be used BEFORE layout
	public Rect LayoutBounds { get; private set; }
	
	public double LayoutWidth => LayoutBounds.Width;
	public double LayoutHeight => LayoutBounds.Height;

	/* Methods */

	// Sets bounds for this layout within specified parent layout, saves bounds internally
	public void SetLayoutBounds( DXAbsoluteGestures parent, double x, double y, double wd, double ht )
	{
		SetLayoutBounds( parent, new Rect( x, y, wd, ht ) );
	}
	
	// Sets bounds for this layout within specified parent layout, saves bounds internally
	private void SetLayoutBounds( DXAbsoluteGestures parent, Rect bounds )
	{
		LayoutBounds = bounds;
		
		parent.SetBounds( this, bounds );
	}
	
	// Shorthand for setting layout bounds for specified view
	public void SetBounds( IView view, Rect bounds )
	{
		SetLayoutBounds( view, bounds );
	}

	// Expanded shorthand for setting layout bounds for specified view
	public void SetBounds( IView view, double x, double y, double wd, double ht )
	{
		SetLayoutBounds( view, new Rect( x, y, wd, ht ) );
	}

	// Adds child with same width as parent but with dynamic position and height
	public void SetWidthBounds( IView view, double y, double ht )
	{
		SetLayoutFlags( view, AbsoluteLayoutFlags.WidthProportional );
		SetLayoutBounds( view, new Rect( 0, y, 1.00, ht ) );
	}

	// Adds child with same height as parent but with dynamic position and width
	public void SetHeightBounds( IView view, double x, double wd )
	{
		SetLayoutFlags( view, AbsoluteLayoutFlags.HeightProportional );
		SetLayoutBounds( view, new Rect( x, 0, wd, 1.00 ) );
	}

	// Adds child with specified proportional width and height centered in parent
	public void SetSizeBounds( IView view, double wd, double ht )
	{
		SetLayoutFlags( view, AbsoluteLayoutFlags.All );
		SetLayoutBounds( view, new Rect( 0.5, 0.5, wd, ht ) );
	}

	// Adds child with same full size bounds as parent
	public void SetFullBounds( IView view )
	{
		SetLayoutFlags( view, AbsoluteLayoutFlags.SizeProportional );
		SetLayoutBounds( view, new Rect( 0, 0, 1.00, 1.00 ) );
	}
	
	// Determines if specified x,y point within layout bounds
	public bool Contains( Point point )
	{
		return Bounds.Contains( point );
	}

	/* Layout Utils */

	// Shorthand for setting dimensions
	public virtual void SetSize( double wd, double ht )
	{
		WidthRequest = wd;
		HeightRequest = ht;
	}

	// Shorthand for setting margin
	public void SetMargin( double left, double top, double right, double bottom )
	{
		Margin = new Thickness( left, top, right, bottom );
	}

	// Shorthand for setting layout options
	public void SetPosition( LayoutOptions horizontal, LayoutOptions vertical )
	{
        Horizontal = horizontal;
        Vertical = vertical;
	}

	/* Layout */

	// Allows special handling for device rotation
	public virtual void Rotate()
	{} 

	// Forces layout for current device type/orientation
	public virtual void UpdateLayout()
	{
		UpdateLayout( DXDevice.GetLayoutType() );
	}

	// Gives subclasses opportunity to make type/orientation specific changes
	public virtual void UpdateLayout( LayoutType type )
	{
		switch ( type )
		{
			case LayoutType.Landscape: Landscape(); break;
			case LayoutType.Portrait: Portrait(); break;

			case LayoutType.WideLandscape: WideLandscape(); break;
			case LayoutType.WidePortrait: WidePortrait(); break;

			case LayoutType.MobileLandscape: MobileLandscape(); break;
			case LayoutType.MobilePortrait: MobilePortrait(); break;
			
			default: break;
		}
	}

	// Layout changes specific to each possible size
	protected virtual void Landscape() {}
	protected virtual void Portrait() {}

	protected virtual void WideLandscape() {}
	protected virtual void WidePortrait() {}

	protected virtual void MobileLandscape() {}
	protected virtual void MobilePortrait() {}
}

//
