import com.shigeodayo.pframe.*;
import g4p_controls.*;

//gestione mouse e rotazione assi
float spostX, spostY, spostZ; //spostamento degli oggeto nel sistema di assi
int mousePressedX, mousePressedY;
float vRot; //velocità di rotazione al pixel

float rotX, rotY; //variabili rotazione assi
float tempRotX, tempRotY; //variabili temporanee per la somma della rotazione con il drag del mouse
float vSpost; // spostamento negli assi

float tempSpostX, tempSpostY; //spostamento temporaneo nel sistema
float zoom; //variabile per la gesione della quantità di zoom

float scalatura; //indica la grandezza di scale()
float scaleIndex; //indica di quanto diminuire scalatura es: 0.1 --> ogni pressione dei tasti su/giu scalatura cambia di 0.1

float explode;
int opacita;

int ogniTot;

int loneliness;
int overcrowding;
int minNeight, maxNeight;
thVita thv;;

//istanzio l'array tridimensionale di cellule
Cellula[][][] brodo;

//lato cubo
int L = 300;
//num Cellule per lato
int numCell = 50;

public void setup(){
  size(800, 600, P3D);
  
  //istanzio le alter finestre
  createGUI();
  
  zoom = 2;
  spostX = 0;
  spostY = 0;
  spostZ = 0;
  vSpost = 1;
  
  explode = 0;
  opacita = 51;
  
  brodo = new Cellula[numCell][numCell][numCell];
  
  ogniTot = 2;
  
  istanziaBrodo();
  
  loneliness = 3;
  overcrowding = 20;
  minNeight = 4;
  maxNeight = 15;
  
  thv = new thVita();
}

public void draw(){
  background(255);//cancella tutto
  
  pushMatrix();
  translate(width/2 + spostX + tempSpostX - (explode/2)*brodo.length, height/2 + spostY + tempSpostY - (explode/2)*brodo.length, -L/2 - (explode/2)*brodo.length);//mi sposto al centro dello schermo
  //ruoto il disegno
  rotateY(rotX + tempRotX);
  rotateX(rotY + tempRotY);
  scale(zoom); //imposto la proporzione di disegno
  noFill();
  noStroke();
  
  
  for (int i = 0; i< brodo.length; i++){
    for (int j = 0; j< brodo[0].length; j++){
      for (int k = 0; k< brodo[0][0].length; k++){
        pushMatrix();
        
        translate(-L/2 + (L/numCell + explode/2) * i, -L/2 + (L/numCell + explode/2) * j, -L/2 + (L/numCell + explode/2) * k);//mi sposto al centro dello schermo
        
        if(brodo[i][j][k].isLiving()) {
          if(brodo[i][j][k].getWilllive()) fill(0,100,255, opacita); //blu trasparente
          else fill(200,100,0, opacita); //blu trasparente
        }
        else {
          noFill();
        }
        
        box((L/numCell));
        //sphere((L/numCell)/2);
        
        popMatrix();
      }
    }
  }
  fill(255);
  
  scalatura = 1;
  popMatrix();
  vRot = radians(0.3); //spostamento di 1 px per ogni pixel del mouse
}

void mouseDragged() {
  if (mouseButton == 39) {
    tempRotX = (mouseX - mousePressedX) * vRot;
    tempRotY = -(mouseY - mousePressedY) * vRot;
  }

  if (mouseButton == 37) {
    tempSpostX = (mouseX - mousePressedX) * vSpost;
    tempSpostY = (mouseY - mousePressedY) * vSpost;
    //println(spostX + " " + spostY + " " + tempSpostX + " " + tempSpostY);
  }
}

void mouseReleased() {
  //salvo la nuova posizione e resetto le varibili temporanee
  rotX += tempRotX;
  rotY += tempRotY;
  spostX += tempSpostX;
  spostY += tempSpostY;
  tempSpostX = 0;
  tempSpostY = 0;
  tempRotX = 0;
  tempRotY = 0;
}

void mouseWheel(MouseEvent event) {
  if(zoom - event.getAmount() / 10 > 1) zoom -= (event.getAmount() / 10);
  else if(zoom - event.getAmount() / 30 <= 1 && zoom - event.getAmount() / 30 >= 0.1) zoom -= (event.getAmount() / 30);
  else zoom = 0.1;
}

void mousePressed() {
  mousePressedX = mouseX;
  mousePressedY = mouseY;
}

public void istanziaBrodo(){
  for (int i = 0; i< brodo.length; i++){
    for (int j = 0; j< brodo[0].length; j++){
      for (int k = 0; k< brodo[0][0].length; k++){
        brodo[i][j][k] = new Cellula(i, j, k);
        //1 cellula su boh la faccio vivere in modo random
        brodo[i][j][k].setLiving((Math.round(random(ogniTot)) == 0)?true:false);
      }
    }
  }
}

