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

namespace Rokojori
{
  [System.Serializable]
	public class RangeDouble
	{
    public double min;
    public double max;
    
    public RangeDouble( double min, double max )
    {
      this.min = min;
      this.max = max;
    }

    public void EnsureCorrectness()
    {
      if ( max < min )
      {
        var b = max; max = min; min = b;
      }
    } 

    public bool Contains( double value )
    {
      return min <= value && value <= max;
    }

    public bool Overlaps( RangeDouble other )
    {
      if ( other.max < min ) { return false; }
      if ( other.min > max ) { return false; }
      
      if ( other.Contains( min ) || other.Contains( max ) ) 
      {
        return true;
      }

      if ( Contains( min ) || Contains( max ) ) 
      {
        return true;
      }

      return false;
    }

    public bool IsSmaller( RangeDouble other )
    {
      if ( Overlaps( other ) )
      {
        return false;
      }

      return max < other.min;
    }

    public bool IsBigger( RangeDouble other )
    {
      if ( Overlaps( other ) )
      {
        return false;
      }

      return min > other.max;
    }

    public double center { get { return 0.5f * ( max + min ); } }
    public double range { get { return max - min; } }
    public double length { get { return max - min; } }

    public double DistanceTo( RangeDouble other )
    {
      var center = this.center;
      var otherCenter = other.center;

      var RangeDouble = this.range;
      var otherRangeDouble = other.range;

      var distance = Mathf.Abs( center - otherCenter );

      return Mathf.Max( 0, distance - 0.5f * ( RangeDouble + otherRangeDouble ) );
 
    }

    public RangeDouble Copy()
    {
      return new RangeDouble( min, max );
    }

    public double SampleAt( double normalized )
    {
      return min + ( max - min ) * normalized;
    }

    public static RangeDouble Of_01
    {
      get { return new RangeDouble( 0, 1 ); }
    }

    public static RangeDouble Of_Zero
    {
      get { return new RangeDouble( 0, 0 ); }
    }

    public static RangeDouble Of_One
    {
      get { return new RangeDouble( 1, 1 ); }
    }


    public static bool Contains( double min, double max, double value )
    {
      return min <= value && value <= max;
    }

    public static bool ContainsExclusive( double min, double max, double value )
    {
      return min < value && value < max;
    }

    public static bool ContainsExclusiveMax( double min, double max, double value )
    {
      return min <= value && value < max;
    }

    public static bool ContainsExclusiveMin( double min, double max, double value )
    {
      return min < value && value <= max;
    }
    
	}
  
}

