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

using System.Threading.Tasks;

namespace Rokojori.PointClouds
{
  public class PointCloud
  { 
    public List<Point> points = new List<Point>();

    public Vector3 center;

    public void ComputeCenter()
    {
      center = Math3D.ComputeAverage( points, p => p.position );
    }

    public Box3 boundingBox;

    public void ComputeBoundingBox()
    {
      boundingBox = Box3.Create( points, p => p.position );
    }

    public void SortByDistanceToCenter()
    {
      ComputeCenter();

      points.Sort(
        ( a, b ) =>
        {
          var dA = ( a.position - center ).LengthSquared();
          var dB = ( b.position - center ).LengthSquared();

          return Mathf.Sign( dB - dA );
        }
      );
    }

    public ArrayMesh GenerateMesh( float normalOffset = 0f )
    {
      var mg = GenerateMeshGeometry( normalOffset );
      return mg.GenerateMesh( Mesh.PrimitiveType.Points, null, false );
    }

    public MeshGeometry GenerateMeshGeometry( float normalOffset = 0f )
    {
      var mg = new MeshGeometry( false, false, false, false );
      mg.customMeshAttributes.Add( new MeshAttributeVector4List( 0 ) );
      mg.customMeshAttributes.Add( new MeshAttributeVector4List( 1 ) );

      points.ForEach(
        ( p ) =>
        {
          mg.AddPoint( p.position + p.normal * normalOffset, p.normal, 0, p.uv, 1 );
        }
      );

      return mg;
    }

  }
}