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



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class RandomizeTransform:Scatterer
  {  
    [ExportGroup( "All" )]
    [Export]
    public float noiseScale = 1;
    [Export]
    public ScattererOwnPositionMode ownPositionMode = ScattererOwnPositionMode.Ignore;

    [ExportGroup( "Position" )]
    [Export]
    public Vector3 positionOffset = Vector3.Zero;
    [Export]
    public float positionOffsetScale = 1;
    [Export]
    public float positionNoiseScale = 1;
    [Export]
    public Vector3 positionNoiseOffset = Vector3.Zero;

    [Export]
    public Vector3 staticOffset = Vector3.Zero;


    [ExportGroup( "Rotation" )]
    [Export]
    public Vector3 rotationOffset = Vector3.Zero;
    [Export]
    public float rotationOffsetScale = 1;
    [Export]
    public float rotationNoiseScale = 1;
    [Export]
    public Vector3 rotationNoiseOffset = Vector3.Zero;

    [ExportGroup( "Scale" )]

    [Export]
    public float uniformScaleMultiplyMin = 1;
    [Export]
    public float uniformScaleMultiplyMax = 1;

    
    [Export]
    public Vector3 componentScaleMinMultiply = Vector3.One;
    [Export]
    public Vector3 componentScaleMaxMultiply = Vector3.One;
    [Export]
    public float scaleNoiseScale = 1;
    [Export]
    public Vector3 scaleNoiseOffset = Vector3.Zero;

    
    protected override List<ScatterPoint> _Scatter( List<ScatterPoint> points, Scatterer root )
    { 
      var output = points;
      var ownOffset = ScattererOwnPosition.ComputeOffset( ownPositionMode, this );

      points.ForEach(
        p => 
        {         
          
          var point = p.position;

          var positionPerlin = ( point + positionNoiseOffset + ownOffset ) * ( noiseScale * positionNoiseScale );
          var rotationPerlin = ( point + rotationNoiseOffset + ownOffset ) * ( noiseScale * rotationNoiseScale );
          var scalePerlin    = ( point + scaleNoiseOffset    + ownOffset ) * ( noiseScale * scaleNoiseScale );

          var positionRandom =  Noise.PerlinPolar3( positionPerlin );
          var rotationRandom =  Noise.PerlinPolar3( rotationPerlin );
          var scaleRandom    =  Noise.Perlin3( scalePerlin );
          var uniformScaleRandom = Noise.Perlin( scalePerlin + new Vector3( 100002, -10002, 1000 ) );

          p.position += positionOffset * positionRandom * positionOffsetScale + staticOffset;
          p.rotation *= Quaternion.FromEuler( rotationOffset * MathX.DegreesToRadians * rotationRandom * rotationOffsetScale );

          

          p.scale *= Math3D.LerpComponents( componentScaleMinMultiply, componentScaleMaxMultiply, scaleRandom );
          p.scale *= Mathf.Lerp( uniformScaleMultiplyMin, uniformScaleMultiplyMax, uniformScaleRandom );

 
        }
      );



      return output;
    } 
  }
}