package nallar.leagueskin;

import nallar.leagueskin.models.Obj;
import nallar.leagueskin.models.Skn;
import nallar.leagueskin.util.Throw;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class SkinPack {
    final String match;

    private List<Replacement> replacements = new ArrayList<>();

    public SkinPack(Path folder) {
        this(folder, null);
    }

    public SkinPack(Path folder, String match) {
        this.match = match;
        recursiveSearch(folder);
    }

    private static String shortNameFromPath(Path p) {
        return p.getFileName().toString().toLowerCase().replace("\\", "/");
    }

    private void recursiveSearch(Path path) {
        Path workingDir = Paths.get("").toAbsolutePath();
        path = path.toAbsolutePath();
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
            for (Path entryFull : stream) {
                Path entry = workingDir.relativize(entryFull);
                String forwardSlashName = entry.toString().replace('\\', '/');
                String name = shortNameFromPath(entry);
                if (Files.isDirectory(entry)) {
                    recursiveSearch(entry);
                } else if (!name.startsWith("!") && !forwardSlashName.contains("/!")) {
                    if (match == null || name.contains(match)) {
                        boolean discardsPrevious = true;
                        ReplacementGenerator replacementGenerator = previous -> Files.readAllBytes(entry);
                        if (name.endsWith(".obj")) {
                            discardsPrevious = false;
                            name = name.replace(".obj", ".skn");
                            Obj replacement = new Obj();
                            replacement.load(entry);
                            final String finalName = name;
                            replacementGenerator = previous -> {
                                Skn skn = new Skn(finalName, ByteBuffer.wrap(previous));
                                if (replacement.getVertexes().length != skn.getVertexes().length) {
                                    System.out.println("Mismatched vertex counts replacing " + entry);
                                    return previous;
                                }
                                skn.setVertexes(replacement.getVertexes());
                                skn.setIndices(replacement.getIndices());
                                return skn.update();
                            };
                        }
                        replacements.add(new Replacement(name, replacementGenerator, discardsPrevious, entry));
                    }
                }
            }
        } catch (IOException e) {
            throw Throw.sneaky(e);
        }
    }

    public List<Replacement> getReplacements() {
        return replacements;
    }

    public static class Replacement {
        public final String name;
        public final ReplacementGenerator generator;
        public final boolean discardsPrevious;
        public final Path path;

        public Replacement(String name, ReplacementGenerator generator, boolean discardsPrevious, Path path) {
            this.name = name;
            this.generator = generator;
            this.discardsPrevious = discardsPrevious;
            this.path = path;
        }

        @Override
        public String toString() {
            return "Replacement{" +
                    "name='" + name + '\'' +
                    ", generator=" + generator +
                    ", discardsPrevious=" + discardsPrevious +
                    ", path=" + path +
                    '}';
        }
    }
}

@@ -1254,32 +1254,159 @@
 romPath(entry);%0A
+                if (name.startsWith(%22!%22) %7C%7C forwardSlashName.contains(%22/!%22)) %7B%0A                    continue;%0A                %7D%0A
                 
@@ -1501,84 +1501,40 @@
     
-%7D else if (!name.startsWith(%22!%22) && !forwardSlashName.
+    
 cont
-a
 in
-s(%22/!%22)) %7B%0A
+ue;%0A            
     
+%7D%0A
     
@@ -1610,20 +1610,16 @@
         
-    
 boolean 
@@ -1663,20 +1663,16 @@
         
-   
- 
 Replacem
@@ -1758,36 +1758,32 @@
                 
-    
 if (name.endsWit
@@ -1819,20 +1819,16 @@
         
-    
 discards
@@ -1869,20 +1869,16 @@
         
- 
-   
 name = n
@@ -1930,20 +1930,16 @@
         
-    
 Obj repl
@@ -1975,36 +1975,32 @@
                 
-  
-  
 replacement.load
@@ -2000,36 +2000,32 @@
 nt.load(entry);%0A
-    
                 
@@ -2055,36 +2055,32 @@
 nalName = name;%0A
-    
                 
@@ -2152,20 +2152,16 @@
         
-    
 Skn skn 
@@ -2205,28 +2205,24 @@
 previous));%0A
-    
             
@@ -2337,20 +2337,16 @@
         
- 
-   
 System.o
@@ -2432,28 +2432,24 @@
             
-    
 return previ
@@ -2477,34 +2477,26 @@
             
-   
- 
 %7D%0A
-    
             
@@ -2551,28 +2551,24 @@
 ertexes());%0A
-    
             
@@ -2649,28 +2649,24 @@
             
-    
 return skn.u
@@ -2670,28 +2670,24 @@
 n.update();%0A
-    
             
@@ -2717,34 +2717,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -2831,38 +2831,16 @@
 ntry));%0A
-                    %7D%0A
         

Improve SkinPack performance