package bam.display.opengl;

import bam.display.DisplayParams;
import lombok.extern.slf4j.Slf4j;
import nativelibs.NativeLibsBinder;
import nativelibs.NativeLibsJarIntrospectSearch;
import nativelibs.NativeLibsSearch;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.ProviderNotFoundException;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
public class OpenGlDisplay {

    private AtomicBoolean displayEnable = new AtomicBoolean();

    private final OpenGlSetup openGlSetup;

    private final int fpsLimit;

    private final float width;

    private final float height;

    public OpenGlDisplay(DisplayParams displayParams) {
        fpsLimit = displayParams.getFpsLimit();
        width = displayParams.getWidth();
        height = displayParams.getHeight();
        openGlSetup = new OpenGlSetup(displayParams);
    }

    public void init() {
        if (!displayEnable.get()) {
            try {
                bindNativeLibs();
                Display.create();
                openGlSetup.setup();
                displayEnable.set(true);
            } catch (LWJGLException e) {
                log.info(e.getMessage(), e);
            }
        }
    }

    public void destroy() {
        if (displayEnable.get()) {
            Display.destroy();
        }
    }

    public void draw(Runnable redrawing) {
        if (displayEnable.get()) {
            // Clear The Screen And The Depth Buffer
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
            GL11.glPushMatrix();
            redrawing.run();
            GL11.glLoadIdentity();
            GL11.glPopMatrix();
            GL11.glFlush();
            Display.sync(fpsLimit);
            Display.update();
        }
    }

    public boolean isDisplayEnabled() {
        return displayEnable.get() && !Display.isCloseRequested();
    }

    public float getDisplayWidth() {
        return width;
    }

    public float getDisplayHeight() {
        return height;
    }

    private void bindNativeLibs() {
        Set<Path> pathStream;
        try {
            pathStream = new NativeLibsJarIntrospectSearch().getNativeLibraries();
        } catch (ProviderNotFoundException e) {
            log.error(e.getMessage());
            final NativeLibsSearch nativeLibsIDEItrospectorSearch = targetPath ->
                    Optional.of(new File("engine/src/main/resources/" + targetPath.toString()).toPath());
            pathStream = nativeLibsIDEItrospectorSearch.getNativeLibraries();
        }
        new NativeLibsBinder().bindLibs(pathStream);
    }
}

@@ -329,16 +329,37 @@
 o.File;%0A
+import java.net.URL;%0A
 import j
@@ -421,24 +421,50 @@
 dException;%0A
+import java.util.Objects;%0A
 import java.
@@ -2462,32 +2462,168 @@
     
-final NativeLibsSearch n
+pathStream = new NativeLibsIDEIntrospectSearch().getNativeLibraries();%0A        %7D%0A        new NativeLibsBinder().bindLibs(pathStream);%0A    %7D%0A%0A    private class N
 ativ
@@ -2627,32 +2627,33 @@
 tiveLibsIDEI
+n
 trospect
 orSearch = t
@@ -2644,52 +2644,73 @@
 pect
-or
 Search 
-= targetPath -%3E%0A           
+implements  NativeLibsSearch %7B%0A%0A        @Override%0A
         
  Opt
@@ -2705,16 +2705,22 @@
         
+public
  Optiona
@@ -2724,52 +2724,124 @@
 onal
-.of(new File(%22engine/src/main/r
+%3CPath%3E transform(Path targetPath) %7B%0A            final URL dirURL = OpenGlDisplay.class.getClassLoader().getR
 esource
-s/%22 + 
+(
 targ
@@ -2862,98 +2862,172 @@
 g())
-.toPath());%0A            pathStre
+;%0A            if (Objects.nonNull(dirURL)) %7B%0A                String dirN
 am
+e
  = 
-nativeLibsIDEItrospectorSearch.getNativeLibraries
+dirURL.getFile();%0A                return Optional.of(new File(dirName).toPath
 ()
+)
 ;%0A
+    
     
@@ -3044,52 +3044,46 @@
     
-new NativeLibsBinder().bindLibs(pathStream);
+    return Optional.empty();%0A        %7D
 %0A   

Make NativeLibsIDEIntrospectSearch more agile.