using System.Collections;
using System.Collections.Generic;
using Godot;
using System;



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class Baker:Node
  {

    [ExportToolButton( "Apply Camera Settings")]
    public Callable ApplyCamerySettingsButton => Callable.From( () => ApplyCameraSettings() );

    [Export]
    public bool updateAlways = false;

    [ExportGroup( "View") ]

    [Export]
    public BakingViewSettings viewSettings = new BakingViewSettings();

    [Export]
    public Viewport viewport;
    
    [Export]
    public Camera3D camera;


    [ExportGroup( "Target")]

    [Export]
    public Node3D target;

    [Export]
    public Vector3 targetPivot;

    [Export]
    public bool autoTargetPivot = true;


    [ExportGroup( "Output")]

    [Export]
    public Node3D outputTexture;

    [Export]
    public float outputScale = 1;

    [Export]
    public float outputTextureSize = 1;


    public static Baker Create( Node parent, Node3D target, Vector2I size, string name )
    {
      var bakingView = parent.CreateChild<SubViewport>( "Viewport " + name );
      bakingView.TransparentBg = true;
      bakingView.Size = size;
      
      var bakingCamera = bakingView.CreateChild<Camera3D>( "Camera View " + name );
      var baker = bakingView.CreateChild<Baker>( "Baker " + name );

      baker.camera   = bakingCamera;
      baker.target   = target;
      baker.viewport = bakingView;

      return baker;
    }

    public override void _Process( double delta )
    {
      if ( ! updateAlways )
      {
        return;
      }

      ApplyCameraSettings();
      
    } 

    public void ApplyCameraSettings()
    {
      if ( viewport == null || target == null || camera == null )
      {
        return;
      }
      
      if ( autoTargetPivot )
      { 
        Box3 box = target.GetWorldBounds();
        
        if ( box == null )
        {
          return;
        }

        targetPivot = new Vector3( 0, -box.center.Y, 0 );
      }

      viewSettings.ApplySettings( camera, target, targetPivot );
      
      var outputScale = Cameras.ComputeCameraFittingScale( camera.Fov, viewSettings._XX_ComputedDistance );

      if ( outputTexture != null )
      {
        outputTexture.Scale = Vector3.One * outputScale;
        outputTexture.GlobalPosition = target.GlobalPosition - targetPivot; 
      }
    }

  }
}
