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


namespace Rokojori
{  
  [Tool]
   [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/EditorCamera.svg") ]
  public partial class EditorCamera:VirtualCamera
  {
    [Export]
    public Vector3 target;
    
    [Export]
    public float yaw = 0;

    [Export]
    public float pitch = 0; 

    [Export]
    public float distance = 10; 
    float _smoothDistance = 10;
    public float smoothDistance => _smoothDistance;
    
    [Export] 
    public float minPitch = -89;

    [Export] 
    public float maxPitch = 89;

    [Export]
    public float minDistance = 0.001f;

    [Export]
    public float maxDistance = 200f;


    [Export( PropertyHint.Range, "0,600")]
    public Smoothing zoomSmoothing;

    public Vector3 moveDirection = Vector3.Zero;

    [Export]
    public EditorCameraInputSettings keyboardMouseInputs;

    [Export]
    public EditorCameraInputSettings controllerInputs;

    float _cachedDistance = -1;

    public void CacheDistance()
    {
      if ( _cachedDistance < 0 )
      {
        return;
      }

      _cachedDistance = distance;

      GlobalPosition = target;
      distance = minDistance;

      this.LogInfo( "Cached Distance", _cachedDistance );
    }

    public void RestoreDistance()
    {
      if ( _cachedDistance < 0 )
      {
        return;
      }

      this.LogInfo( "Restored Distance", _cachedDistance );

      target = GlobalPosition + GlobalBasis.Z * _cachedDistance;
      distance = _cachedDistance;

      

      _cachedDistance = -1;

    }

    [Export]
    public float running = 0;

    public override void _Process( double delta )
    {
      keyboardMouseInputs?.Orbit( this );
      controllerInputs?.Orbit( this );
      
      keyboardMouseInputs?.Pan( this );
      controllerInputs?.Pan( this );
      
      keyboardMouseInputs?.Zoom( this );
      controllerInputs?.Zoom( this );

      moveDirection = Vector3.Zero;

      keyboardMouseInputs?.Move( this );
      controllerInputs?.Move( this );

      Apply( (float) delta );

      if ( ! hasMotionDelta )
      {
        _motionDelta.X = 0;
        _motionDelta.Y = 0;
      }

      hasMotionDelta = false;   
    }

    bool hasMotionDelta = false;
    Vector2 _motionDelta = Vector2.Zero;
    public Vector2 motionDelta => _motionDelta;

    public override void _Input( InputEvent inputEvent )
    {     
      var mouseMotionEvent = inputEvent as InputEventMouseMotion;

      if ( mouseMotionEvent == null )
      {
        return;
      }

      _motionDelta = mouseMotionEvent.ScreenRelative;
      hasMotionDelta = true;      
      
    }

    void Apply( float delta )
    {
      _smoothDistance = Smoothing.Apply( zoomSmoothing, distance, delta );
      GlobalRotation = new Vector3( Mathf.DegToRad( pitch ), Mathf.DegToRad( yaw ), 0 );

      var forward = this.GlobalForward() * _smoothDistance;
      target -= moveDirection * delta;
      GlobalPosition = target + forward;
    }
    
  }
}