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



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class BakingViewSettings:Resource
  {
    /*public enum CameraDistanceDetectionType
    {
      Automatic_Distance_Detection,
      Custom_Distance
    }
    
    public enum CameraFOVMode
    {
      Keep_Fov,
      Compute_Fov_With_Distance,
      Custom_Fov
    }*/

    [Export]
    public _XX_BakingFDSettings fovDistance;

    /*
    [Export]
    public float originalFOV = 75;

    [Export]
    public bool assignFOV = false;

    [Export]
    public float placingDistance = 500;

    

    [Export]
    public float zoom = 1;

    */


    /*

    [ExportGroup( "Custom FOV" )]

    [Export]
    public bool useCustomFOV = false;

    [Export]
    public float customFOV = 75;

    [ExportGroup( "Custom Distance" )]

    [Export]
    public bool useCustomDistance = false;

    [Export]
    public float customDistance = 50;
    */
    
    public enum RotationMode
    {
      Yaw_Pitch,
      Quaternion
    }

    

    [ExportGroup("Rotation")]

    [Export]
    public RotationMode rotationMode = RotationMode.Yaw_Pitch;

    [Export( PropertyHint.Range, "-180,180")]
    public float yaw = 0;

    [Export( PropertyHint.Range, "-180,180")]
    public float pitch = 0;

    [Export]
    public Quaternion rotationQuaternion = Quaternion.Identity;


    public Quaternion bakingRotation => RotationMode.Yaw_Pitch == rotationMode ? 
                                          Math3D.YawPitchRotation( yaw, pitch ) :
                                          rotationQuaternion;
    

    
    [ExportGroup( "Debug Readonly" )]

    [Export]
    public float _XX_ComputedFOV = 75;

    [Export]
    public float _XX_ComputedDistance = 1;

    [Export]
    public float _XX_ComputedOutputScale = 1;


    public void ApplySettings( Camera3D camera, Node3D target, Vector3 pivot )
    {
      var box = target.GetWorldBounds();

      if ( box == null )
      {
        RJLog.Log( "No target" );
        return;
      }

      Box3 box3 = box;
      box3.IncludePoint( target.ToGlobal( pivot ) );

      var sphere = Sphere.ContainingBox( box3 );

      var size = sphere.radius;
      
      if ( fovDistance is AutoDistance_BakingFDSettings ad )
      {
        size = ad.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ? 
                sphere.radius : ( box3.size.Y / 2f );
      } 

      if ( fovDistance is AutoFOVDistance_BakingFDSettings afd )
      {
        size = afd.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ? 
                sphere.radius : ( box3.size.Y / 2f );
      } 
      
      var fd = fovDistance.ComputeFOVDistance( size / 2f );
      _XX_ComputedDistance = fd.Y;
      _XX_ComputedFOV = fd.X;

      camera.Fov = fd.X;
      
      var cameraRotation = bakingRotation; 
      var offset = ( Vector3.Back * _XX_ComputedDistance ) * cameraRotation ;
      camera.GlobalPosition = target.GlobalPosition + offset - pivot;


      var inverse = cameraRotation.Normalized().Inverse();
      camera.SetGlobalQuaternion( inverse );

      _XX_ComputedOutputScale = Cameras.ComputeCameraFittingScale( camera.Fov, _XX_ComputedDistance );


    }
  }
}
