import processing.core.*; import gifAnimation.*; import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; public class maeda4 extends PApplet {

Grid grid;
Serpiente S;
Logo L[];
Tv tv;
PImage esq[];
int numL;
int winX, winY;
int fc, fcambio;
float incr;
float borde;
Fondo f;
Puntos puntos;
int cf;
int numVistos, numVistos0;

public void setup() {
  size(600,400,P3D);
  background(255);
  frameRate(30);
  cursor();
  tv = new Tv();
  esq = new PImage[4];
  for (int n = 0; n < 4; n++) {
    String nombre = "esq"+(n+1)+".png";
    esq[n] = loadImage(nombre);
  }  
  winX = width;
  borde = 95.f;
  winY = height-floor(2*borde);
  grid = new Grid();
  S = new Serpiente();
  f = new Fondo(this);
  puntos = new Puntos();
  numL = 26;
  L = new Logo[numL+1];
  for (int n = 0; n < numL+1; n++) {
    L[n] = new Logo(n);
  }
  fc = 0;
  fcambio = 30;
  incr = 0.04f;
  cf = numL;
  numVistos = 0;
  numVistos0 = 0;
  mouseX = floor(width*.5f);
  mouseY = floor(height*.5f);
}

public void draw() {
  mouseX = constrain(mouseX, 66, width-66);
  mouseY = constrain(mouseY, 49, height-49);
//  if (frameCount % 50 == 0) println(frameRate);
  grid.clear();
  f.draw(L[cf].col);  
  pushMatrix();  
  translate(0,borde);
  S.draw();     
  grid.draw();    
  popMatrix();  
  if (mouseY == constrain(mouseY, borde, height-borde-1)) {
  if (grid.getOcupacion(mouseX, mouseY-borde)) {
    int cf0 = cf;
    cf = grid.getColor(mouseX, mouseY-borde);
    if (cf != cf0 && cf != numL) numVistos++;
    incr = 0.04f+(numVistos-numVistos0)*0.001f;
    for (int i = 0; i < grid.nX; i++) {
      for (int j = 0; j < grid.nY; j++) {
        grid.celdas[i][j].t = incr;      
      }
    }
  }
  else {
    numVistos0 = numVistos;
    cf = numL;
    for (int i = 0; i < grid.nX; i++) {
      for (int j = 0; j < grid.nY; j++) {
        grid.celdas[i][j].t = max(grid.celdas[i][j].t-0.005f,0);
      }
    }
    fc = frameCount;
  }
  }  
  else {
    numVistos0 = numVistos;
    cf = numL;
    for (int i = 0; i < grid.nX; i++) {
      for (int j = 0; j < grid.nY; j++) {
        grid.celdas[i][j].t = max(grid.celdas[i][j].t-0.002f,0);
      }
    }
    fc = frameCount;
  }  
  tv.idle();
  tv.draw(cf);
  puntos.draw(numVistos-numVistos0);
  for (int n = 0; n < 4; n++) {
    switch(n) {
      case 0:image(esq[n], 0, 0); break;
      case 1:image(esq[n], width-50,0);break;
      case 2:image(esq[n], width-50,height-50);break;
      case 3:image(esq[n], 0,height-50);break;
    }
  } 
  
}   



class Celda {
  
  float x, y;
  float gX, gY;
  boolean ocupada;
  int c;
  float t;
  int id;
  
  Celda (int iIn, int jIn, float gXIn, float gYIn) {
    x = iIn-1;
    y = jIn;
    id = iIn;
    gX = gXIn;
    gY = gYIn;
    ocupada = false;
    t = 0;
    c = floor(random(0,numL));
  }
  
  public void draw() {
    x -= t;
    if ( x <= -2 ) { 
      x += grid.nX;
      if (y == 0) S.nueva(id);
    }
    noStroke();
    if (ocupada) {
      noTint();
      image(L[c].img, (x)*gX, y*gY, gX, gY);
    }
    else {
      noFill();
      noStroke();
      rect((x)*gX, y*gY, gX, gY);      
    }
//    rect((x)*gX, y*gY, gX, gY);
  }
  
}

class Logo {
  
  PImage img;
  int id;
  int col;
  
  Logo(int idIn) {
    id = idIn;
    String nombre = id+".png";
    if (id < numL) img = loadImage(nombre);
    switch (id) {
      case 0: col = color(255,255,0); break;
      case 1: col = color(255,180,0); break;
      case 2: col = color(195,175,210); break;
      case 3: col = color(234,94,130); break;
      case 4: col = color(114,201,226); break;
      case 5: col = color(0,255,48); break;
      case 6: col = color(0,99,46); break;
      case 7: col = color(255,30,23); break;
      case 8: col = color(0,135,73); break;
      case 9: col = color(255,0,3); break;
      case 10: col = color(102,130,170); break;
      case 11: col = color(219,69,38); break;
      case 12: col = color(244,130,30); break;
      case 13: col = color(100,100,100); break;
      case 14: col = color(194,189,214); break;
      case 15: col = color(0,155,229); break;
      case 16: col = color(254,220,0); break;
      case 17: col = color(196,27,30); break;
      case 18: col = color(250,220,134); break;
      case 19: col = color(236,134,132); break;
      case 20: col = color(0,0,90); break;
      case 21: col = color(50,228,176); break;
      case 22: col = color(255,213,38); break;      
      case 23: col = color(255,101,1); break;      
      case 24: col = color(255,142,240); break;      
      case 25: col = color(123,235,246); break;            
      default: col = color(255,255,255); break;
    }  
  }
  
}

/*
      case 0: col = color(99,100,0); break;
      case 1: col = color(100,52,0); break;
      case 2: col = color(63,66,73); break;
      case 3: col = color(92,37,51); break;
      case 4: col = color(45,79,89); break;
      case 5: col = color(0,100,19); break;
      case 6: col = color(0,39,18); break;
      case 7: col = color(100,12,9); break;
      case 8: col = color(0,53,29); break;
      case 9: col = color(100,0,1); break;
      case 10: col = color(40,51,67); break;
      case 11: col = color(86,27,15); break;
      case 12: col = color(96,51,12); break;
      case 13: col = color(0,0,0); break;
      case 14: col = color(76,78,84); break;
      case 15: col = color(0,61,90); break;
      default: col = color(255,0,0); break;
      */

class Puntos {
 
  PImage numero[];
  int w[];
 
  Puntos() {
    numero = new PImage[10];
    w = new int[10];
    for (int n = 0; n < 10; n++) {
      String nombre = "n"+n+".png";
      numero[n] = loadImage(nombre);
      w[n] = numero[n].width*2;
    }
  } 
  
  public void draw(int n) {
    int n1, n2, n3, n4;
    if (n < 10) {
      image(numero[n],width-50, 50, w[n], 40);  
    }
    else if (n < 100) {
       n1 = floor(n/10);
       n2 = n%10;
       image(numero[n2],width-50, 50, w[n2], 40);         
       image(numero[n1],width-80, 50, w[n1], 40);         
    }
    else if (n < 1000) {
       n1 = floor(n/100);
       n2 = n%100;
       n3 = floor(n2/10);
       n4 = n2%10;
       image(numero[n4],width-50, 50, w[n4], 40);         
       image(numero[n3],width-80, 50, w[n3], 40);         
       image(numero[n1],width-110, 50, w[n1], 40);                
    }    
    
  }
  
}
class Serpiente {

  int serpiente[];
  int numS;
  int dx, dy;
  int cuenta;
  int c[];

  Serpiente() {  
    numS = grid.nX;  
    serpiente = new int[numS];
    c = new int[numS];
    dx = 1; dy = 3;
    cuenta = 0;
    for (int n = 0; n < numS; n++) {
      c[n] = floor(random(0,numL));
      if (n == 0) {
        serpiente[n] = floor(random(1,6));
        cuenta = 0;
      }
      else {
        if (cuenta > dx && random(0,1) > .1f) {
          serpiente[n] = (serpiente[n-1] + floor(random(0,dy)))%6;
          cuenta = 0;
        }
        else {
          serpiente[n] = serpiente[n-1];
          cuenta++;
        }
      }
    }
  }
  
  public void nueva(int i) {
    int i2 = i-1;
    c[i] = floor(random(0,numL));
    if (i == 0) i2 = numS-1;
    if (cuenta > dx && random(0,1) > .1f) {
      serpiente[i] = (serpiente[i2] + floor(random(0,dy)))%6;
      cuenta = 0;
    }
    else {
      serpiente[i] = serpiente[i2];
      cuenta++;
    }    
  }  
  
  public void draw() {
    for (int n = 0; n < numS; n++) {
      for (int m = 0; m < 6; m++) 
        grid.setOcupacion(n,m,c[n],false);
      int n2 = n - 1;
      if (n == 0) n2 = grid.nX - 1;
        if (serpiente[n] > serpiente[n2]) 
          for (int m = serpiente[n2]; m < serpiente[n]; m++) 
            grid.setOcupacion(n,m,c[n],true);
        if (serpiente[n] <= serpiente[n2]) 
          for (int m = serpiente[n]; m <= serpiente[n2]; m++) 
            grid.setOcupacion(n,m,c[n],true);        
          
      grid.setOcupacion(n,serpiente[n],c[n],true);
    }
  }
  
}

class Fondo {
  
  int fX, fY;
  float gfX, gfY;
  Gif gifFondo;

  Fondo(PApplet mom) {
    fX = 150; fY = 60;
    gfX = width/fX; gfY = height/fY;
    gifFondo = new Gif(mom,"noise150.gif");
    gifFondo.loop();
  }

  public void draw(int c) {
    tint(c);
    image(gifFondo,0,0,width,height);
/*    if (frameCount % 4 == 1) {
      noStroke();
      for (int i = 0; i < fX; i++) {
        for (int j = 0; j < fY; j++) {
          if (random(1) > .7) {
            fill(random(255));
            rect(i*gfX,j*gfY,gfX,gfY);
          }
        }
      }
    }
    */
  }
}

class Grid {

  int nX, nY;
  float gX, gY;
  Celda[][] celdas;  
  float t;
  
  Grid () { 
    nX = 17;
    nY = 6; 
    gX = (float)winX/(nX-2);
    gY = (float)winY/(float)nY;
    celdas = new Celda[nX][nY];
    for (int i = 0; i < nX; i++) {
      for (int j = 0; j < nY; j++) {
        celdas[i][j] = new Celda(i,j, gX, gY);
      }
    }
    t = 0.f;
  }
  
  public void clear() {
    for (int i = 0; i < nX; i++) {
      for (int j = 0; j < nY; j++) {
        celdas[i][j].ocupada = false;
      }
    }    
  }
  
  public void setOcupacion(int i, int j, int c, boolean ocupacion) {
    celdas[i][j].ocupada = ocupacion;
    celdas[i][j].c = c;
  }
  
  public boolean getOcupacion(float x, float y) {
    float i = x/(float)gX;
    int j = floor(y/gY);    
    boolean tmp = false;
    for (int n = 0; n < nX; n++) {
      if (i == constrain(i,celdas[n][j].x, celdas[n][j].x+1)) 
        tmp = celdas[n][j].ocupada;
    }
    return tmp;
  }
  
  public int getColor(float x, float y) {
    float i = x/(float)gX;
    int j = floor(y/gY);    
    int tmp = 0;
    for (int n = 0; n < nX; n++) {
      if (i == constrain(i,celdas[n][j].x, celdas[n][j].x+1)) 
        tmp = celdas[n][j].c;
    }
    return tmp;    
  }
  
  public void idle() {
    for (int i = 0; i < nX; i++) {
      for (int j = 0; j < nY; j++) {
        celdas[i][j].t = t;
      }
    }
    t = ((t*100)+1)/100; 
/*    if (t > 1) {
      S.idle(); 
      t = 0.;
    }   */
  }
  
  public void draw() {
    for (int i = 0; i < nX; i++) {
      for (int j = 0; j < nY; j++) {
        celdas[i][j].draw();
      }
    }    
  }
  
}

class Tv {
  
  PImage tvcursor;
  float x,y;
  
  Tv() {
    tvcursor = loadImage("tv.png");
    x = width*.5f;
    y = height*.5f;
  }
  
  public void idle() {
    x += 0.1f*(mouseX-x); 
    y += 0.1f*(mouseY-y);    
  }
  
  public void draw(int cf) {
    if (cf < numL)
      image(L[cf].img,x-60,y-42,100,75); 
    else
      image(f.gifFondo, x-60,y-42,100,75); 
    image(tvcursor,x-65,y-48);    
  }
  
}
  static public void main(String args[]) {     PApplet.main(new String[] { "maeda4" });  }}