using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;



namespace Rokojori
{
  /** <summary for="class FoliageRendererSettings">
      
      <title>
        Resource to define foliage data
      </title>
      
      <description>
        
      </description>

    </summary>  
  */

  [Tool]
  [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ]
  public partial class FoliageQualitySettings:Resource
  {
    [Export( PropertyHint.Range, "0,200")]
    public float qualityLevel = 100;

    [Export]
    public float cellSizeMultiply = 1f;

    [Export]
    public float visibilityRangeMultiply = 1f;


    public static float GetCellSize( float quality, FoliageQualitySettings[] all, FoliageQualitySettings[] own, float ownValue )
    {
      if ( own != null && own.Length > 0 )
      {
        return ComputeCellSize( quality, all, ownValue );
      }

      if ( all != null && all.Length > 0 )
      {
        return ComputeCellSize( quality, all, ownValue );
      }

      return ownValue;
    }

    public static float GetVisibilityRange( float quality, FoliageQualitySettings[] all, FoliageQualitySettings[] own, float ownValue )
    {
      if ( own != null && own.Length > 0 )
      {
        return ComputeVisibilityRange( quality, all, ownValue );
      }

      if ( all != null && all.Length > 0 )
      {
        return ComputeVisibilityRange( quality, all, ownValue );
      }

      return ownValue;
    }

    static Func<FoliageQualitySettings,float> getQualityyLevel = ( fqs ) => fqs.qualityLevel;

    protected static float ComputeCellSize( float quality, FoliageQualitySettings[] settings, float value )
    {
      if ( settings.Length == 1 )
      {
        return settings[ 0 ].cellSizeMultiply * value; 
      }

      var closest = settings.ClosestIndex( quality, getQualityyLevel );
      var second  = settings.SecondClosestIndex( closest, quality, getQualityyLevel );

      var a = settings[ closest ];
      var b = settings[ second ];
      
      return value * MathX.RemapClamped( quality, a.qualityLevel, b.qualityLevel, a.cellSizeMultiply, b.cellSizeMultiply );
    }

    protected static float ComputeVisibilityRange( float quality, FoliageQualitySettings[] settings, float value )
    {
      if ( settings.Length == 1 )
      {
        return settings[ 0 ].visibilityRangeMultiply * value; 
      }

      var closest = settings.ClosestIndex( quality, getQualityyLevel );
      var second  = settings.SecondClosestIndex( closest, quality, getQualityyLevel );

      var a = settings[ closest ];
      var b = settings[ second ];
      
      return value * MathX.RemapClamped( quality, a.qualityLevel, b.qualityLevel, a.visibilityRangeMultiply, b.visibilityRangeMultiply );
    }
  }
}