package com.gmail.stefvanschiedev.buildinggame.utils.region;

import com.gmail.stefvanschiedev.buildinggame.Main;
import com.gmail.stefvanschiedev.buildinggame.utils.worldedit.WorldBackedClipboard;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.util.io.Closer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.function.Supplier;

/**
 * The same as {@link Region}, but this one is used when WorldEdit is present, so we can do WorldEdit dependent method
 * calls.
 *
 * @since 7.0.0
 */
public class WorldEditRegion extends Region {

    /**
     * {@inheritDoc}
     */
    WorldEditRegion(Supplier<World> worldSupplier, int highX, int highY, int highZ, int lowX, int lowY, int lowZ) {
        super(worldSupplier, highX, highY, highZ, lowX, lowY, lowZ);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveSchematic(@NotNull File file, @Nullable Runnable runAfter) {
        World world = getWorld().get();

        if (world == null) {
            return;
        }

        Runnable runnable = () -> {
            try (var closer = Closer.create()) {
                var fileOutputStream = closer.register(new FileOutputStream(file));
                var bufferedOutputStream = closer.register(new BufferedOutputStream(fileOutputStream));
                var builtInClipboardFormat = BuiltInClipboardFormat.SPONGE_SCHEMATIC;
                var clipboardWriter = builtInClipboardFormat.getWriter(bufferedOutputStream);

                var lowVector = BlockVector3.at(getLowX(), getLowY(), getLowZ());
                var highVector = BlockVector3.at(getHighX(), getHighY(), getHighZ());
                var bukkitWorld = new BukkitWorld(world);

                var cuboidRegion = new CuboidRegion(bukkitWorld, lowVector, highVector);
                var blockArrayClipboard = new WorldBackedClipboard(cuboidRegion);

                closer.register(clipboardWriter).write(blockArrayClipboard);
            } catch (IOException exception) {
                exception.printStackTrace();
                return;
            }

            if (runAfter != null) {
                runAfter.run();
            }
        };

        if (Bukkit.isPrimaryThread()) {
            Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), runnable);
        } else {
            runnable.run();
        }
    }
}

@@ -122,48 +122,91 @@
 com.
-gmail.stefvanschiedev.buildinggame.utils
+sk89q.worldedit.EditSession;%0Aimport com.sk89q.worldedit.WorldEdit;%0Aimport com.sk89q
 .wor
@@ -217,31 +217,29 @@
 it.World
-BackedClipboard
+EditException
 ;%0Aimport
@@ -327,33 +327,285 @@
 ard.
-io.BuiltInClipboardFormat
+BlockArrayClipboard;%0Aimport com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;%0Aimport com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;%0Aimport com.sk89q.worldedit.function.operation.ForwardExtentCopy;%0Aimport com.sk89q.worldedit.function.operation.Operations
 ;%0Aim
@@ -701,51 +701,8 @@
 on;%0A
-import com.sk89q.worldedit.util.io.Closer;%0A
 impo
@@ -838,45 +838,8 @@
 e;%0A%0A
-import java.io.BufferedOutputStream;%0A
 impo
@@ -1630,100 +1630,160 @@
     
-Runnable runnable = () -%3E %7B%0A            try (var close
+var lowVector = BlockVector3.at(getLowX(), getLowY(), getLowZ());%0A        var highVecto
 r = 
-Closer.create()) %7B%0A       
+BlockVector3.at(getHighX(), getHighY(), getHighZ());%0A
         
  var
@@ -1782,538 +1782,519 @@
     
- 
 var 
-fileOutputStream = closer.register(new FileOutputStream(file));%0A                var bufferedOutputStream = closer.register(new BufferedOutputStream(fileOutputStream));%0A                var builtInClipboardFormat = BuiltInClipboardFormat.SPONGE_SCHEMATIC;%0A                var clipboardWriter = builtInClipboardFormat.getWriter(bufferedOutputStream);%0A%0A          
+bukkitWorld = new BukkitWorld(world);%0A%0A        var cuboidRegion = new CuboidRegion(bukkitWorld, lowVector, highVector);%0A        var clipboard = new BlockArrayClipboard(cuboidRegion);%0A%0A        EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder()%0A            .world(bukkitWorld)%0A            .build();%0A%0A
       
+  
 var 
-lowVector = BlockVector3.at(getLowX(), getLowY(), getLowZ());%0A                var highVector = BlockVector3.at(getHighX(), getHighY(), getHighZ()
+forwardExtentCopy = new ForwardExtentCopy(editSession, cuboidRegion, clipboard, cuboidRegion.getMinimumPoint());%0A        forwardExtentCopy.setCopyingEntities(true
 );%0A
+%0A
         
     
@@ -2285,32 +2285,38 @@
 );%0A%0A        
+try %7B%0A
         
 var bukkitWo
@@ -2307,289 +2307,362 @@
     
-var bukkitWorld = new BukkitWorld(world);%0A%0A                var cuboidRegion = new CuboidRegion(bukkitWorld, lowVector, highVector);%0A                var blockArrayClipboard = new WorldBackedClipboard(cuboidRegion);%0A%0A                closer.register(clipboardWriter).write(blockArrayC
+    Operations.complete(forwardExtentCopy);%0A        %7D catch (WorldEditException exception) %7B%0A            exception.printStackTrace();%0A            return;%0A        %7D%0A%0A        Runnable runnable = () -%3E %7B%0A            try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) %7B%0A                writer.write(c
 lipb
@@ -2845,24 +2845,74 @@
             
+ Bukkit.getScheduler().runTask(Main.getInstance(),
  runAfter.ru
@@ -2908,21 +2908,16 @@
 runAfter
-.run(
 );%0A     

Update schematic saving