package com.guigarage.photonia.folder;

import com.guigarage.photonia.MetadataUtils;
import com.guigarage.photonia.service.AsyncService;
import com.guigarage.photonia.service.PhotoniaService;
import com.guigarage.photonia.thumbnail.ThumbnailCache;
import com.guigarage.photonia.types.JpegImageFile;
import com.guigarage.photonia.types.RenderedImageFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

public class ImageFolder {

    private Path folderPath;

    private String name;

    private final List<JpegImageFile> images;

    private final String uuid;

    private final ThumbnailCache thumbnailCache;

    public ImageFolder(String folderPath, AsyncService asyncService, ThumbnailCache thumbnailCache) throws IOException {
        this(Paths.get(folderPath), asyncService, thumbnailCache);
    }

    public ImageFolder(Path folderPath, AsyncService asyncService, ThumbnailCache thumbnailCache) throws IOException {
        this.folderPath = folderPath;
        this.images = new ArrayList<>();
        this.uuid = UUID.randomUUID().toString();
        this.thumbnailCache = thumbnailCache;

        this.name = folderPath.toFile().getName();
        if (!getFolderPath().toFile().exists()) {
            getFolderPath().toFile().mkdirs();
        }

        synchWithFileSystem(asyncService);
    }

    public List<JpegImageFile> getImages() {
        return Collections.unmodifiableList(images);
    }

    public String getName() {
        return name;
    }

    public Path getFolderPath() {
        return folderPath;
    }

    public void synchWithFileSystem(AsyncService asyncService) throws IOException {
        for (RenderedImageFile imageFile : images) {
            thumbnailCache.remove(imageFile);
        }

        images.clear();

        for (File child : folderPath.toFile().listFiles()) {
            addInternal(child.getName(), asyncService);
        }
    }

    public void moveToTrash(JpegImageFile imageFile, AsyncService asyncService, PhotoniaService photoniaService) throws IOException {
        moveChildTo(imageFile, photoniaService.getTrashFolder(), asyncService);
    }

    public void moveChildTo(JpegImageFile imageFile, ImageFolder newFolder, AsyncService asyncService) throws IOException {
        if (!imageFile.getParentImageFolder().equals(this)) {
            throw new RuntimeException("Wrong Folder!");
        }
        newFolder.add(imageFile.toFile(), asyncService);
        delete(imageFile);
    }

    protected void delete(JpegImageFile imageFile) throws IOException {
        images.remove(imageFile);
        thumbnailCache.remove(imageFile);

        for (File child : folderPath.toFile().listFiles()) {
            if (FilenameUtils.getBaseName(child.getName()).equals(FilenameUtils.getBaseName(imageFile.getName()))) {
                FileUtils.forceDelete(child);
            }
        }
    }

    public void add(File externalFile, AsyncService asyncService) throws IOException {
        List<File> toCopyList = new ArrayList<>();
        for (File child : externalFile.getParentFile().listFiles()) {
            if (FilenameUtils.getBaseName(child.getName()).equals(FilenameUtils.getBaseName(externalFile.getName()))) {
                toCopyList.add(child);
            }
        }

        String baseName = FilenameUtils.getBaseName(externalFile.getName());
        int counter = 0;
        boolean canCopy = false;
        while (!canCopy) {
            canCopy = true;
            for (File child : getFolderPath().toFile().listFiles()) {
                if (FilenameUtils.getBaseName(child.getName()).equals(baseName)) {
                    canCopy = false;
                }
            }
            counter++;
            baseName = FilenameUtils.getBaseName(externalFile.getName()) + "-" + counter;
        }


        for (File toCopy : toCopyList) {
            File newFile = new File(getFolderPath().toFile(), baseName + FilenameUtils.getExtension(toCopy.getName()));
            FileUtils.copyFile(externalFile, newFile);
            addInternal(newFile.getName(), asyncService);
        }
    }

    private void addInternal(String childName, AsyncService asyncService) {
        File child = new File(getFolderPath().toFile(), childName);
        if (!child.exists()) {
            throw new RuntimeException("Image is not in the folder!");
        }
        if (MetadataUtils.JPEG_FILE_TYPE.isMatching(child.getName())) {
            JpegImageFile imageFile = new JpegImageFile(this, child.getName());
            images.add(imageFile);
            thumbnailCache.addOrUpdateAsync(imageFile, asyncService);
        }
    }

    public String getUuid() {
        return uuid;
    }

    public JpegImageFile findImageById(String id) {
        for (JpegImageFile imageFile : images) {
            if (imageFile.getUuid().equals(id)) {
                return imageFile;
            }
        }
        return null;
    }

    public JpegImageFile getNext(JpegImageFile file) {
        for (int i = 0; i < images.size(); i++) {
            if (images.get(i).getUuid().equals(file.getUuid())) {
                if (i < images.size() - 1) {
                    return images.get(i + 1);
                } else {
                    return images.get(0);
                }
            }
        }
        return null;
    }

    public JpegImageFile getPrev(JpegImageFile file) {
        for (int i = 0; i < images.size(); i++) {
            if (images.get(i).getUuid().equals(file.getUuid())) {
                if (i > 0) {
                    return images.get(i - 1);
                } else {
                    return images.get(images.size() - 1);
                }
            }
        }
        return null;
    }
}

@@ -33,16 +33,225 @@
 older;%0A%0A
+import java.io.File;%0Aimport java.io.IOException;%0Aimport java.nio.file.Path;%0Aimport java.nio.file.Paths;%0Aimport java.util.ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.UUID;%0A%0A
 import c
@@ -645,217 +645,8 @@
 s;%0A%0A
-import java.io.File;%0Aimport java.io.IOException;%0Aimport java.nio.file.Path;%0Aimport java.nio.file.Paths;%0Aimport java.util.ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.UUID;%0A%0A
 publ
@@ -5210,37 +5210,32 @@
 ) %7B%0A        
-for (
 int i = 
 0; i %3C image
@@ -5226,117 +5226,38 @@
 i = 
-0; i %3C images.size(); i++) %7B%0A            if (images.get(i).getUuid().equals(file.getUuid())) %7B%0A      
+images.indexOf(file);%0A
         
   if
@@ -5248,26 +5248,24 @@
 e);%0A        
-  
 if (i %3C imag
@@ -5277,23 +5277,12 @@
 ze()
- - 1) %7B%0A       
+) %7B%0A
     
@@ -5281,33 +5281,32 @@
 ) %7B%0A            
- 
 return images.ge
@@ -5319,107 +5319,8 @@
 1);%0A
-                %7D else %7B%0A                    return images.get(0);%0A                %7D%0A            %7D%0A
     
@@ -5420,21 +5420,16 @@
     
-for (
 int i = 
 0; i
@@ -5428,111 +5428,30 @@
 i = 
-0; i %3C images.size(); i++) %7B%0A            if (images.get(i).getUuid().equals(file.getUuid())) %7B%0A        
+images.indexOf(file);%0A
     
@@ -5475,32 +5475,24 @@
             
-    
-    
 return image
@@ -5509,123 +5509,8 @@
 1);%0A
-                %7D else %7B%0A                    return images.get(images.size() - 1);%0A                %7D%0A            %7D%0A
     

simplify getNext and getPrev Method