
using System.Linq;
using Godot;
using Rokojori;
 
namespace Rokojori
{ 
  public class UILayouting
  {  
    public static Vector2 GetContentSize( Control control )
    {
      if ( control is UIRegion )
      {
        return ( (UIRegion) control ).contentSize;
      }

      return control.Size;
    }

    public static Vector2 GetContentOffset( Control control )
    {
      if ( control is UIRegion )
      {
        return ( (UIRegion) control ).contentOffset;
      }

      return control.Size;
    }

    public static void UpdateChild( Control control )
    {
      if ( ! control.Visible )
      {
        return;
      }
      
      if ( control is UIRegion region )
      {
        region.Layout();
      }
      else if ( control is UIImage uiImage )
      {
        uiImage.Update();
        uiImage.CommitUpdateInfo();
      } 
      else if ( control is UIText uiText )
      {
        uiText.Update();
        uiText.CommitUpdateInfo();
      }
      else if ( control is UIBreak uiBreak )
      {
        uiBreak.Update();
      }
      else if ( control is UISpace uiSpace )
      {
        uiSpace.Update();
      }
      else
      {

      }

      UpdatePivot( control );
    }
    
    public static void SetPositionInParentAnchor( UIStylePropertyContainer container )
    {
      var control = (Control) container;
      var p = NodesWalker.Get().Parent( control ) as Control;
      
      var pWidth  = p == null ? UI.GetWindowWidth( control ) : UILayouting.GetWidth( p );
      var pHeight = p == null ? UI.GetWindowHeight( control ) : UILayouting.GetHeight( p );   
      
      var x = p.Position.X;
      var y = p.Position.Y;


      if ( ! UINumber.IsNullOrNone( container, UIStyleNumberProperty.Left ) )
      {
        var left  = UINumber.Compute( control, UIStyleNumberProperty.Left, 0 );
        x = left;
      }
      else if ( ! UINumber.IsNullOrNone( container, UIStyleNumberProperty.Right ) )
      {
        var right  = UINumber.Compute( control, UIStyleNumberProperty.Right, 0 );
        x = ( pWidth - UILayouting.GetWidth( control ) ) - right;
      }

      if ( ! UINumber.IsNullOrNone( container, UIStyleNumberProperty.Top ))
      {
        var top  = UINumber.Compute( control, UIStyleNumberProperty.Top, 0 );
        y = top;
      }
      else if ( ! UINumber.IsNullOrNone( container, UIStyleNumberProperty.Bottom ) )
      {
        var bottom  = UINumber.Compute( control, UIStyleNumberProperty.Bottom, 0 );
        y = ( pHeight - UILayouting.GetHeight( control ) ) - bottom;
      }

      // var margin       = UINumber.Compute( control, UIStyle.Margin( container ), 0 );
      // var marginLeft   = margin + UINumber.Compute( control, UIStyle.MarginLeft( container ), 0 );
      // var marginTop    = margin + UINumber.Compute( control, UIStyle.MarginRight( container ), 0 );
      // var marginRight   = margin + UINumber.Compute( control, UIStyle.MarginRight( container ), 0 );
      // var marginBottom   = margin + UINumber.Compute( control, UIStyle.MarginBottom( container ), 0 );
      
      // UILayouting.SetPosition( control, new Vector2( x - ( marginLeft + marginRight ), y - ( marginTop + marginBottom ) ) );

      UILayouting.SetPosition( control, new Vector2( x, y ) );
    }

    public static void UpdatePivot( Control c )
    {
      if ( ! ( c is UIImage || c is UIRegion || c is UIText ) )
      {
        return;
      }

      var container = c as UIStylePropertyContainer;

      var pivotX  = UINumber.Compute( c, UIStyleNumberProperty.PivotX, 0.5f * c.Size.X, c.Size.X );
      var pivotY  = UINumber.Compute( c, UIStyleNumberProperty.PivotY, 0.5f * c.Size.Y, c.Size.Y );

      if ( c is UIText text && ! text.alwaysMinimumSize )
      {
        pivotX = 0;
        pivotY = 0;        
      }

      c.PivotOffset = new Vector2( pivotX, pivotY );
      
      

      c.Rotation = MathX.DegreesToRadians * UINumber.Compute( c, UIStyleNumberProperty.Rotation, 0 ); 

      var scale = UINumber.Compute( c, UIStyleNumberProperty.Scale, 1, 1 );

      c.Scale = new Vector2( 
        UINumber.Compute( c, UIStyleNumberProperty.ScaleX, 1, 1 ) ,
        UINumber.Compute( c, UIStyleNumberProperty.ScaleY, 1, 1 )
      ) * scale; 

    }

    public static void SetPosition( Control c, Vector2 position )
    {
      if ( UIStyling.HasInnerMargins( c ) )
      {
        var container = c as UIStylePropertyContainer;

        var margin       = UINumber.Compute( c, UIStyleNumberProperty.Margin, 0 );
        var marginLeft   = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginLeft, 0 );
        var marginTop    = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginTop, 0 );

        position.X += marginLeft;
        position.Y += marginTop;
 
      }

      c.Position = position;
    }

    public static float GetWidth( Control c )
    {
      if ( UIStyling.HasInnerMargins( c ) )
      {
        var container = c as UIStylePropertyContainer;

        var margin       = UINumber.Compute( c, UIStyleNumberProperty.Margin, 0 );
        var marginLeft   = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginLeft, 0 );
        var marginRight   = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginRight, 0 );

        return c.Size.X + marginLeft + marginRight;
 
      }

      if ( c is UIBreak br )
      {
        return 0;
      }

      if ( c is UISpace sp )
      {
        return UINumber.em( c ) * 0.29f;
      }

      return c.Size.X;
    } 
    
    public static float GetHeight( Control c )
    {
      if ( UIStyling.HasInnerMargins( c ) )
      {
        var container = c as UIStylePropertyContainer;

        var margin       = UINumber.Compute( c, UIStyleNumberProperty.Margin, 0 );
        var marginTop     = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginTop, 0 );
        var marginBottom  = margin + UINumber.Compute( c, UIStyleNumberProperty.MarginBottom, 0 );

        return c.Size.Y + marginTop + marginBottom;
 
      }

      return c.Size.Y;
    }

  }
}