using Godot;

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class StarFlareType:FlareType
  {
    public override Shader GetShader( FlareLayer.Data data )
    {
      var bm = data.GetBlendMode();

      if ( FlareBlendMode.BlendModeType.Add == bm )
      {
        return StarTypeFlareAddShader.shader.Get();
      }

      if ( FlareBlendMode.BlendModeType.Mix == bm )
      {
        return StarTypeFlareMixShader.shader.Get();
      }

      if ( FlareBlendMode.BlendModeType.Subtract == bm )
      {
        return StarTypeFlareSubtractShader.shader.Get();
      }

      if ( FlareBlendMode.BlendModeType.Multiply == bm )
      {
        return StarTypeFlareMultiplyShader.shader.Get();
      }

      return null;
      
    }

    public override ShaderMaterial CreateMaterial( FlareLayer.Data data )
    {
      var bm = data.GetBlendMode();

      if ( FlareBlendMode.BlendModeType.Add == bm )
      {
        return new StarTypeFlareAddMaterial();
      }

      if ( FlareBlendMode.BlendModeType.Mix == bm )
      {
        return new StarTypeFlareMixMaterial();
      }

      if ( FlareBlendMode.BlendModeType.Subtract == bm )
      {
        return new StarTypeFlareSubtractMaterial();
      }

      if ( FlareBlendMode.BlendModeType.Multiply == bm )
      {
        return new StarTypeFlareMultiplyMaterial();
      }

      return null;
    }

    
    [Export( PropertyHint.Range, "0,1")]
    float speedMultiply = 1f;  

    [Export]
    Vector4 innerHsl = Vector4.Zero;  

    [Export]
    Vector4 outerHsl = Vector4.Zero;  

    [Export( PropertyHint.Range, "0,5")]
    float colorFillRange = 0.5f;  

    [Export( PropertyHint.Range, "0.01,5")]
    float colorFillDistributionPower = 1f;  

    [ExportGroup( "Streaks")]
    [Export( PropertyHint.Range, "0,8")]
    float streaksFrequency = 1f;  
    [Export( PropertyHint.Range, "0,16")]
    float streaksRotation = 0f;  
    [Export( PropertyHint.Range, "0,1")]
    float streaksRotationSpeed = 0f;  
    [Export( PropertyHint.Range, "0,2")]
    float streaksNoise = 0f;  
    [Export( PropertyHint.Range, "-2,2")]
    float streaksNoiseOffset = 0f;  
    [Export( PropertyHint.Range, "-1,1")]
    float streaksNoiseScroll = 0f;  

    [ExportGroup( "Streaks 2")]
    [Export]
    bool streaks2Enabled = false;  
    [Export( PropertyHint.Range, "0,1")]
    float streaksAddVsMult = 0f;  
    [Export( PropertyHint.Range, "0,5")]
    float streaks2Multiply = 0f;  

    [Export( PropertyHint.Range, "0,8")]
    float streaksFrequency2 = 1f;  
    [Export( PropertyHint.Range, "0,16")]
    float streaksRotation2 = 0f;  
    [Export( PropertyHint.Range, "0,1")]
    float streaksRotationSpeed2 = 0f;  
    [Export( PropertyHint.Range, "0,2")]
    float streaksNoise2 = 0f;  
    [Export( PropertyHint.Range, "-2,2")]
    float streaksNoiseOffset2 = 0f;  
    [Export( PropertyHint.Range, "-1,1")]
    float streaksNoiseScroll2 = 0f;  

    [ExportGroup( "Mask")]
    [Export( PropertyHint.Range, "0,1")]
    float maskScale = 0.5f;  
    [Export( PropertyHint.Range, "0,2")]
    float maskRange = 0.1f;  
    [Export( PropertyHint.Range, "0,1")]
    float maskRangeOscillation = 0.1f;  
    [Export( PropertyHint.Range, "0,1")]
    float maskRangeOscillationSpeed = 0.1f;  
    [Export( PropertyHint.Range, "0,2")]
    float maskInnerSize = 1f;  
    [Export( PropertyHint.Range, "0,2")]
    float maskFrequency = 1f;  
    [Export( PropertyHint.Range, "0,1")]
    float maskRotation = 0f;  
    [Export( PropertyHint.Range, "-1,1")]
    float maskRotationSpeed = 0f;  


    [ExportGroup( "Noise Blend")]
    [Export( PropertyHint.Range, "0,0.5")]
    float blendingRange = 0.1f;  


    [ExportGroup( "Noise","noise")]
    [Export( PropertyHint.Range, "0,1" ) ]
    public float noiseAmount = 0;

    [Export( PropertyHint.Range, "0.1,100" ) ]
    public float noiseScale = 0;

    public override void ApplyShape( FlareLayer.Data data )
    {
      var material = data.material;
      
      StarTypeFlareAddShader.speedMultiply.Set( material, speedMultiply );
      StarTypeFlareAddShader.innerHsl.Set( material, innerHsl );
      StarTypeFlareAddShader.outerHsl.Set( material, outerHsl );
      StarTypeFlareAddShader.colorFillRange.Set( material, colorFillRange );
      StarTypeFlareAddShader.colorFillDistributionPower.Set( material, colorFillDistributionPower );
      StarTypeFlareAddShader.streaksFrequency.Set( material, streaksFrequency );
      StarTypeFlareAddShader.streaksRotation.Set( material, streaksRotation );
      StarTypeFlareAddShader.streaksRotationSpeed.Set( material, streaksRotationSpeed );
      StarTypeFlareAddShader.streaksNoise.Set( material, streaksNoise );
      StarTypeFlareAddShader.streaksNoiseOffset.Set( material, streaksNoiseOffset );
      StarTypeFlareAddShader.streaksNoiseScroll.Set( material, streaksNoiseScroll );
      StarTypeFlareAddShader.streaks2Enabled.Set( material, streaks2Enabled );
      StarTypeFlareAddShader.streaksAddVsMult.Set( material, streaksAddVsMult );
      StarTypeFlareAddShader.streaks2Multiply.Set( material, streaks2Multiply );
      StarTypeFlareAddShader.streaksFrequency2.Set( material, streaksFrequency2 );
      StarTypeFlareAddShader.streaksRotation2.Set( material, streaksRotation2 );
      StarTypeFlareAddShader.streaksRotationSpeed2.Set( material, streaksRotationSpeed2 );
      StarTypeFlareAddShader.streaksNoise2.Set( material, streaksNoise2 );
      StarTypeFlareAddShader.streaksNoiseOffset2.Set( material, streaksNoiseOffset2 );
      StarTypeFlareAddShader.streaksNoiseScroll2.Set( material, streaksNoiseScroll2 );
      StarTypeFlareAddShader.maskScale.Set( material, maskScale );
      StarTypeFlareAddShader.maskRange.Set( material, maskRange );
      StarTypeFlareAddShader.maskRangeOscillation.Set( material, maskRangeOscillation );
      StarTypeFlareAddShader.maskRangeOscillationSpeed.Set( material, maskRangeOscillationSpeed );
      StarTypeFlareAddShader.maskInnerSize.Set( material, maskInnerSize );
      StarTypeFlareAddShader.maskFrequency.Set( material, maskFrequency );
      StarTypeFlareAddShader.maskRotation.Set( material, maskRotation );
      StarTypeFlareAddShader.maskRotationSpeed.Set( material, maskRotationSpeed );
      StarTypeFlareAddShader.blendingRange.Set( material, blendingRange );

      BaseFlareShader.shapeNoiseAmount.Set( material, noiseAmount );
      BaseFlareShader.shapeNoiseScale.Set( material, noiseScale );

    }
  }
}
