// Blake Shaw
// metablake.com
//
// edited from ran tao's code

int w = 800;
int h = 800;


int D = 100;
int cellsize = 5;
int N = h/cellsize;
int[][] x, newx;

void setup(){
  size(w, h);
  
  fill(0, 0, 0);
  smooth();

  x = new int[N][N];
  newx = new int[N][N];

  for(int i=1; i<N; i++){
    for(int j=1; j<N; j++){
      if(random(1.0) > 0.4){
        x[i][j] = 1;
      } 
      else {
        x[i][j] = 0;
      }
      //print(x[i][j]);
    }
  }

  //ploti();
  background(0);
  frameRate(20);
}

void simulate(){
  //int[][] neighbors = getneighbors();

  newx = new int[N][N];
  int c = 0;

  for(int i=1; i<N; i++){
    for(int j=1; j<N; j++){
      //int ne = neighbors[i][j];
      
    
    int ne = 0;
    
    
    if (x[(i+N-1) % N ][(j+N-1) % N ] == 1) { ne++; }
    if (x[ i                ][(j+N-1) % N ] == 1) { ne++; }
    if (x[(i+1)      % N ][(j+N-1) % N ] == 1) { ne++; }
      //middle row
    if (x[(i+N-1) % N ][ j                ] == 1) { ne++; }
    if (x[(i+1)      % N ][ j                ] == 1) { ne++; }
      //bottom row
    if (x[(i+N-1) % N ][(j+1)      % N ] == 1) { ne++; }
    if (x[ i                ][(j+1)      % N ] == 1) { ne++; }
    if (x[(i+1)      % N ][(j+1)      % N ] == 1) { ne++; }
      
      if(c++ < 100){
        //print(i + ", " + j + ", ne = " + ne + ", i = " + x[i][j] + "\n");
      }
      
      if( (x[i][j] == 1) && (ne < 2) ) {
        newx[i][j] = 0;
      } else if( (x[i][j] == 1) && (ne > 3) ) {
        newx[i][j] = 0;
      } else if( (x[i][j] == 0) && (ne == 3) ) {
        newx[i][j] = 1;
      } else {
        newx[i][j] = x[i][j];
      }
    }
  }

  int[][] tmp = x;
  x = newx;
  newx = tmp;
}

void draw(){
  
  simulate();
  fill(255, 100); 
  rect(0,0,width-1,height-1);
  
  
  plotx();
  
  
  
  //noLoop();
}

void plotx(){
  int s = cellsize;
  int N = x.length;
  for(int i=1; i<N; i++){
    for(int j=1; j<N; j++){
      if(x[i][j] == 1){
        fill(0, 0, 0);
        rect(s*i, s*j, s-2, s-2);
        fill(50,50, 50);
        rect(s*i, s*j, s-1, s-1);
      } 
    }
  }
}



int[][] getneighbors(int[][] x){
  int N = x.length;
  int[][] neighbors = new int[N][N];


  for(int i=1; i<N; i++){
    for(int j=1; j<N; j++){
      neighbors[i][j] = 0;
      int c = 0;
      for(int a=-1; a<=1; a++){
        for(int b=-1; b<=1; b++){
          if(a != 0 && b != 0){
            c += x[((i+a+N) % N)][((j+b+N) % N)];
            //println(c);
          }
        }   
      }
      neighbors[i][j] = c;
    }
  }
  return neighbors;
}

void mouseDragged() {
  if (mouseX<w && mouseX >0 && mouseY <h && mouseY > 0) {
  int new_x;
  int new_y;
  
  new_x = mouseX/cellsize;
  new_y = mouseY/cellsize;
  x[new_x][new_y] = 1;
  plotx();
  }
}

