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



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class GenerateFence:GeneratorScatterer
  {
    [Export]
    public Spline spline;

    [Export]
    public bool xzOnly = true;

    [Export]
    public float sampleDensity = 1;   

    [Export]
    public GeneratorEntry segment;
    [Export]
    public float segmentLength;

    [Export]
    public GeneratorEntry pole;
    [Export]
    public float poleLength;

    [Export]
    public GeneratorEntry startPole;    
    [Export]
    public float startPoleLength;

    [Export]
    public GeneratorEntry endPole;
    [Export]
    public float endPoleLength;

    SplineCurve last;
    LerpCurve3 equalSpacedCurve;

    protected override List<ScatterPoint> _Scatter( List<ScatterPoint> points, Scatterer root )
    {
      CreateWeights();
      var curve = spline.GetCurve();

      if ( last != curve )
      {
        last = curve;
        equalSpacedCurve = LerpCurve3.SampledEqually( curve, sampleDensity );
      }

      var curveLength = equalSpacedCurve.ComputeLength( 0 );
      var numPoints = Mathf.CeilToInt( curveLength * sampleDensity );


      var id = 0;

      for ( int i = 0; i < numPoints; i++ )
      {
        var t = i / (float) ( numPoints - 1 );

        var position = equalSpacedCurve.PositionAt( t );
        var rawDirection = equalSpacedCurve.TangentAt( t, 1f / 100f );
        var direction = rawDirection;
        var length = direction.Length();
        

        if ( length != 0 )
        {
          direction /= length;
        }

        /*RJLog.Log( "i:", i, "t:", t, 
          "P:", position, 
          "L:", length,
          "RD:", rawDirection,
          "D:", direction
        );*/

        var point = CreatePoint( points, id, position.X, position.Y, position.Z );

        point.rotation = Math3D.LookRotation( direction, Vector3.Up );
        id = point.creatorID + 1;

      } 


      return points;
    }

    ScatterPoint CreatePoint( List<ScatterPoint> points, int id, float x, float y, float z )
    {
      var p = new ScatterPoint( this, id );

      p.position = new Vector3( x, y, z );
      p.visible = ! setDiscarded;
      p.seed = Noise.CreateSeed( p.position );

      AssginSceneAndContainer( p );
    
      points.Add( p );

      return p;
    } 
  }
}