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



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class MeshCreationTest:Node3D
  {

    [Export]
    public MeshInstance3D meshInstance3D;
    
    [Export]
    public bool createQuad = false;

    [Export]
    public float size = 1;

    [Export]
    public bool createSpline = false;

    [Export]
    public Spline spline;

    [Export]
    public int splineResolution = 50;

    
    [Export]
    public bool createBoolOp = false;
    
    [Export]
    public bool createBoolOpAlways = false;

    [Export]
    public Spline splineA;
    [Export]
    public int splineAResolution = 50;

    [Export]
    public Spline splineB;
    [Export]
    public int splineBResolution = 50;

    [Export]
    public Geometry2D.PolyBooleanOperation booleanOperation;

    [Export]
    public bool createNavMesh = false;

    [Export]
    public Node3D[] countries = new Node3D[ 0 ];

    [Export]
    public float navMeshRadius = 100;
    

    public override void _Process( double delta )
    {
      CreateQuad();
      CreateSpline();
      CreateBoolOp();
      CreateNavMesh();
    }

    void CreateQuad()
    {
      if ( ! createQuad )
      {
        return;
      }

      createQuad = false;

      RJLog.Log( "CREATING QUAD" );

      var meshGeometry = new MeshGeometry();
      meshGeometry.Initialize();

      meshGeometry.AddQuad( new Vector3( 0, 0, 0 ), size );


      meshInstance3D.Mesh = meshGeometry.GenerateMesh();

    }

    void CreateSpline()
    {
      if ( ! createSpline )
      {
        return;
      }

      createSpline = false;

      RJLog.Log( "CREATING SPLINE" );

      var path = spline.GetCurve().SampleXZPath( splineResolution );
      var meshGeometry = path.CreateMeshGeometry();

      meshInstance3D.Mesh = meshGeometry.GenerateMesh();

    }

    void CreateBoolOp()
    {
      if ( ! ( createBoolOp || createBoolOpAlways ) )
      {
        return;
      }

      createBoolOp = false;

      

      var pathA = splineA.GetCurve().SampleXZPath( splineResolution );
      var pathB = splineB.GetCurve().SampleXZPath( splineResolution );

      // RJLog.Log( "CREATING SPLINE", pathA.isClockwise, pathB.isClockwise );

      pathA.SetWindingDirection( true );
      pathB.SetWindingDirection( true );

      var shape = Path2.Boolean( pathA, pathB, booleanOperation );

      var meshGeometry = shape.CreateFillMeshGeometry();

      meshInstance3D.Mesh = meshGeometry.GenerateMesh();

    }

    void CreateNavMesh()
    {
        if ( ! ( createNavMesh  ) )
      {
        return;
      }

      createNavMesh = false;


      var circleAreaShape = new Shape2();
      circleAreaShape.paths.Add( Path2.Circle( Vector2.Zero, navMeshRadius) );

      var islands = new Shape2();

      foreach ( var c in countries )
      {       
        var path = Nodes.GetAnyChild<Path3D>( c );       

        if ( path == null )
        {
          continue;
        }

        var islandPath = Path2.ToLinearXZPath( path );
        islands.paths.Add( islandPath );        
        RJLog.Log( "Getting path:", c.Name, islandPath.points.Count );
      }

      var shape = Shape2.Boolean( circleAreaShape, islands, Geometry2D.PolyBooleanOperation.Difference );

      var meshGeometry = shape.CreateFillMeshGeometry();

      meshInstance3D.Mesh = meshGeometry.GenerateMesh();

    }

  }
}