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



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public abstract partial class MeshGeneratorType:Resource
  {
    [Export]
    public bool cacheMeshes = true;

    public static readonly string cachePath = "res://.rokojori/cache/MeshGeneratorType";

    public static string GetProjectCachePath( string cacheName )
    {
      return  FilePath.Join( cachePath, cacheName + ".tres" );
    }

    public static ArrayMesh FromCache( string cacheName )
    {
      var path = GetProjectCachePath( cacheName );
      var globalPath = Paths.ToGlobal( path );

      RJLog.Log( path, globalPath );

      if ( ! FilesSync.FileExists( globalPath ) )
      {
        return null;
      }

      return GD.Load<ArrayMesh>( path );
    }

    public static void ToCache( string cacheName, ArrayMesh arrayMesh )
    {
      
      var path = GetProjectCachePath( cacheName );
      var globalPath = Paths.ToGlobal( path );

      RJLog.Log( path, globalPath );

      FilesSync.EnsureParentDirectoryExists( globalPath );
      ResourceSaver.Save( arrayMesh, path, ResourceSaver.SaverFlags.Compress );
    }

    

    public ArrayMesh Generate()
    {
      var cachePath = GetCachePath();
      
      if ( cachePath != null && Engine.IsEditorHint() )
      {
        this.LogInfo( "Checking cache for:", cachePath );
        var cached = FromCache( cachePath );

        if ( cached != null )
        {
          this.LogInfo( "Found cache for:", cachePath, cached.SurfaceGetArrayLen( 0 ) );
          return cached;
        }

        this.LogInfo( "Not cached:", cachePath );
      }

      var mg = _GenerateMeshGeometry();

      var arrayMesh = mg.GenerateMesh();

      if ( cachePath != null && Engine.IsEditorHint() )
      {
        this.LogInfo( "To cache:", cachePath, arrayMesh.SurfaceGetArrayLen( 0 ) );


        ToCache( cachePath, arrayMesh );

        return FromCache( cachePath );
      }

      return arrayMesh;
    }

    protected abstract string GetCachePath();
    protected abstract MeshGeometry _GenerateMeshGeometry();
  }
}