
using Godot;
using System.Collections.Generic;
using System;
namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class GlowEffect:PostProcessVolumeEffect
  {
    [Export]
    public GlowEffectLevels levels;

    [Export]
    public Float8Value intensity;
    
    [Export]
    public Float2Value strength;

    [Export]
    public NormalizedValue bloom;

    [Export]
    public Float4Value hdrTreshold;

    [Export]
    public Float4Value hdrScale;

    [Export]
    public Float256Value hdrLuminanceCap;

    [Export]
    public NormalizedValue mapStrength;


    BoxedFloatValue[] _values = new BoxedFloatValue[ 7 ];


    public override BoxedFloatValue[] GetFloatValues()
    {
      _values[ 0 ] = intensity;
      _values[ 1 ] = strength;
      _values[ 2 ] = bloom;
      _values[ 3 ] = hdrTreshold;
      _values[ 4 ] = hdrScale;
      _values[ 5 ] = hdrLuminanceCap;
      _values[ 6 ] = mapStrength;

      return _values;
    }

    public override void SetFloatValues( BoxedFloatValue[] values )
    {
      intensity = Float8Value.Create( _values[ 0 ] );
      strength = Float2Value.Create(_values[ 1 ] );
      bloom = NormalizedValue.Create( _values[ 2 ] );
      hdrTreshold = Float4Value.Create(_values[ 3 ] );
      hdrScale = Float4Value.Create(_values[ 4 ] );
      hdrLuminanceCap = Float256Value.Create(_values[ 5 ] );
      mapStrength = NormalizedValue.Create(_values[ 6 ] );
    }

    public override void Lerp( object glowEffects, List<PostProcessVolume> volumes )
    {
      LerpFrom( (List<GlowEffect>) glowEffects, volumes );
    }

    public void LerpFrom( List<GlowEffect> glowEffects, List<PostProcessVolume> volumes )
    {
      if ( levels == null && glowEffects.Find( g => g.levels != null ) != null  )
      { 
        levels = new GlowEffectLevels();
      }

      if ( levels != null )
      {
        levels.LerpFrom( glowEffects, volumes );
      }     

      LerpFloats( glowEffects, volumes );
      
    }

    public override void Apply( WorldEnvironment worldEnvironment ) 
    {
      if ( worldEnvironment == null || worldEnvironment.Environment == null )
      {
        return;
      }
      
      if ( levels != null )
      {
        var normalizer = levels.normalizer;

        worldEnvironment.Environment.SetGlowLevel( 0, levels.level1 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 1, levels.level2 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 2, levels.level3 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 3, levels.level4 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 4, levels.level5 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 5, levels.level6 * normalizer );
        worldEnvironment.Environment.SetGlowLevel( 6, levels.level7 * normalizer );

      } 

      if ( intensity != null )
      {
        worldEnvironment.Environment.GlowIntensity = intensity.GetFloatValue();
      }

      if ( strength != null )
      {
        worldEnvironment.Environment.GlowStrength = strength.GetFloatValue();
      }

      if ( bloom != null )
      {
        worldEnvironment.Environment.GlowBloom = bloom.GetFloatValue();
      }

      if ( hdrTreshold != null )
      {
        worldEnvironment.Environment.GlowHdrThreshold = hdrTreshold.GetFloatValue();
      }

      if ( hdrScale != null )
      {
        worldEnvironment.Environment.GlowHdrScale = hdrScale.GetFloatValue();
      }

      if ( mapStrength != null )
      {
        worldEnvironment.Environment.GlowMapStrength = mapStrength.GetFloatValue();
      }
          

    }
  }
}