import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.io.File; 
import java.awt.FileDialog; 
import java.awt.Frame; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class merge_pictures extends PApplet {






ArrayList<String> toScan = new ArrayList();

String[] logs = new String[10000];
int logsIndex=0;
int generation=0;

int maxRecurs = 7;

public void setup() {
  try {
    String[] params = loadStrings("params.txt");
    maxRecurs = Integer.parseInt(params[0]);
  }
  catch(Exception e) {
    println(e);
  }
  String[] checkThisFirst = getDialogAllFilesUrl("OPEN");
  for (int i=0;i<checkThisFirst.length;i++) checkFolder(checkThisFirst[i], maxRecurs);
}

public void checkFolder(String thisFolder, int limit) {
  println(thisFolder);
  saveLogs("scanning" + thisFolder);
  toScan.add(thisFolder);
  String[] subfolders = getAllFoldersFrom(thisFolder);
  if (limit!=-1) for (int i=0;i<min(subfolders.length,limit);i++) checkFolder(subfolders[i], limit-1);
  else for (int i=0;i<subfolders.length;i++) checkFolder(subfolders[i], -1);
}

public void mergePicturesFrom(String url) {
  String[] files = getAllFilesFrom(url);
  int sX = 1600;
  int sY = 900;
  colorMode(RGB);
  long[][] r = new long[sX][sY];
  long[][] g = new long[sX][sY];
  long[][] b = new long[sX][sY]; 
  for (int x=0;x<sX;x++) {
    for (int y=0;y<sY;y++) {
      r[x][y]=0;
      g[x][y]=0;
      b[x][y]=0;
    }
  }
  int nbFiles = files.length;
  for (int i=0;i<files.length;i++) {
    println(i+" / "+files.length);
    try {
      PImage im = loadImage(files[i]);
      for (int x=0;x<sX;x++) {
        for (int y=0;y<sY;y++) {
          r[x][y]+=red(im.get(floor((float)x*im.width/sX), floor((float)y*im.height/sY)));
          g[x][y]+=green(im.get(floor((float)x*im.width/sX), floor((float)y*im.height/sY)));
          b[x][y]+=blue(im.get(floor((float)x*im.width/sX), floor((float)y*im.height/sY)));
        }
      }
    } 
    catch(Exception e) {
      println(e);
      nbFiles--;
    }
  }
  if (nbFiles>1) {
    PImage result = createImage(sX, sY, RGB);
    for (int x=0;x<sX;x++) {
      for (int y=0;y<sY;y++) {
        r[x][y]/=nbFiles;
        g[x][y]/=nbFiles;
        b[x][y]/=nbFiles;
        result.set(x, y, color((int)r[x][y], (int)g[x][y], (int)b[x][y]));
      }
    }
    result.save("result"+nf(generation++, 7)+".png");
  }
}

int currentScan=0;
public void draw() {
  if (currentScan<toScan.size()) mergePicturesFrom(toScan.get(currentScan));
  currentScan++;
}

public String[] getAllFoldersFrom(String folderUrl) {
  try {
    File folder = new File(folderUrl);
    File[] fileNames = folder.listFiles();
    ArrayList<String> result = new ArrayList(); 
    for (int i = 0; i < fileNames.length; i++) { 
      if (fileNames[i].isDirectory()) {
        result.add(fileNames[i].toString());
      }
    }
    String[] result2 = new String[result.size()];
    for (int i = 0; i < result2.length; i++) {
      result2[i] = result.get(i);
    }
    return result2;
  }
  catch(Exception e) {
    String[] empty = new String[0];
    return empty;
  }
}

public void saveLogs(String e) {
  logs[(logsIndex++)%logs.length]=e;
  saveStrings("logs.txt", logs);
}

public String[] getDialogAllFilesUrl(String label) {
  Frame frame = new Frame();
  FileDialog fileDialog = new FileDialog(frame, label, FileDialog.LOAD);
  fileDialog.setVisible(true);
  return getAllFilesFrom(fileDialog.getDirectory());
}

public String[] getAllFilesFrom(String folderUrl) {
  try {  
    File folder = new File(folderUrl);
    File[] filesPath = folder.listFiles();
    String[] result = new String[filesPath.length];
    for (int i=0;i<filesPath.length;i++) {
      result[i]=filesPath[i].toString();
    }
    return result;
  }
  catch(Exception e) {
    saveLogs(e.toString());
    String[] empty = new String[0];
    return empty;
  }
}

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "merge_pictures" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
