/*
 * Lemmings
 * Código original: http://crisp.tweakblogs.net/blog/3881/dhtml-lemmings-primer.html
 *
*/

// Objeto Lemming

function Lemming() {
  if (this == window) {
    return new Lemming();
  }

  // Propiedades
  this.digger = false;
  // Limites iniciales
  this.limitTop = 32;
  this.limitBottom = Lemmings.gridHeight-64;
  this.limitLeft = 32;
  this.limitRight = Lemmings.gridWidth-64;
  // Posición inicial
  this.top =  -32;
  this.left = Math.floor(Math.random() * (this.limitRight-32)+32);
  // Desplazamiento
  this.dx =   Math.random() > 0.5 ? 2 : -2;
  this.dy = 2;

  // Div lemming
  this.element = document.createElement('div');
  this.element.className = "lemming";
  this.element.style.cssText = 'position:absolute;top:'+this.top+'px;left:'+this.left+'px;height:'+32+'px;width:'+32+'px;z-index:42;overflow:hidden;';

  var aleat = Math.random();
  this.floater = aleat > 0.3;
  this.climber = aleat > 0.8;

  // Métodos
  this.changeAni = function(ani) {
    this.ani = ani;
    this.anicounter = 0;
    this.imgleft = 32;
    this.maximgleft = Lemmings.preload[this.ani].num;
    this.tipo = Lemmings.preload[this.ani]['tipo'];
    this.element.style.backgroundImage = 'url('+Lemmings.preload[this.ani][this.tipo == 's'?'l':this.dx > 0 ? 'r' : 'l'].src+')';
  };

  this.changeDir = function() {
    this.dx = -this.dx;
    this.element.style.backgroundImage = 'url('+Lemmings.preload[this.ani][this.dx > 0 ? 'r' : 'l'].src+')';
  };

  this.anima = function() {
    // Si la ventana se está cerrando, elimina lemming
    if (closing) {
      Lemmings.layout.removeChild(this.element);
      this.element = null;
      delete this;
      return;
    }
    // Animación
    this[this.ani]();

    // Actualiza posición
    if (this.element) {
      this.imgleft -= this.imgleft == this.maximgleft ? this.imgleft : 32;
      this.element.style.backgroundPosition = this.imgleft+'px';
      this.element.style.top = this.top+'px';
      this.element.style.left = this.left+'px';
      setTimeout(this.anima, spriteSpeed);
    }
  }.bind(this);

  this.walk = function() {
    this.left += this.dx;
    if (hole >= 0 && (this.left == hole - 10 || this.left == hole - 9) && this.top < Lemmings.gridHeight-32) {
      this.limitTop = 0;
      this.limitBottom = Lemmings.gridHeight-32;
      this.limitLeft = 0;
      this.limitRight = Lemmings.gridWidth-32;
      this.changeAni('fall');
    }
    else if (this.left < this.limitLeft-8 || this.left > this.limitRight+8) {
      if (this.climber) {
        this.changeAni('climb');
       }
      else {
        this.changeDir();
      }
    }
    aleat = Math.random();
    aleat2 = Math.random();
    this0 = (this.dx < 0 && this.left <= this.limitLeft - 8) || (this.dx > 0 && this.left >= this.limitRight + 8);
    this8 = this.left > this.limitLeft + 8 && this.left < this.limitRight - 8;
    this32 = this.left > this.limitLeft + 32 && this.left < this.limitRight - 32;
    if (aleat < 0.005 && this8) {
      this.changeAni('explode');
    } else if (aleat > 0.005 && aleat < 0.008 && this8) {
      this.changeAni('confused');
    } else if (aleat > 0.108 && aleat < 0.11 && this8) {
      this.changeAni('frie');
    } else if (digger && aleat > aleat2 && aleat < aleat2+0.002 && this32 && this.top == Lemmings.gridHeight-32) {
      this.changeAni('build');
    } else if (aleat > 0.312 && aleat < 0.315 && this8) {
      this.changeAni('block');
    } else if (!digger && aleat > aleat2+0.002 && aleat < aleat2+0.003 && this8) {
      this.changeAni('dig');
    } else if (!digger && aleat > aleat2 && aleat < aleat2+0.1 && this0) {
      this.changeAni('bash');
    } else if (!digger && aleat > aleat2+0.003 && aleat < aleat2+0.004 && this32) {
      this.changeAni('mine');
    }
  };

  this.fall = function() {
    if (this.top < this.limitBottom) {
      this.top += this.dy;
      this.anicounter++;

      if (this.top < this.limitBottom) {
        this.top += this.dy;
        this.anicounter++;

        if (this.floater && this.anicounter > 16) {
          this.changeAni('floatstart');
        }
        return;
      }
    }
    this.changeAni(this.anicounter > 64 ? 'splut' : 'walk');
  };

  this.floatstart = function() {
    if (this.top < this.limitBottom) {
      this.top += this.dy;

      if (this.imgleft == this.maximgleft) {
        this.changeAni('float');
      }
    }
    else {
      this.changeAni('walk');
    }
  };

  this.float = function() {
    if (this.top < this.limitBottom) {
      this.top += this.dy;
    }
    else {
      this.changeAni('walk');
    }
  };

  this.confused = function() {
    if (this.imgleft == this.maximgleft) {
      if (this.top < this.limitBottom) {
        this.changeAni('fall');
        return;
      }
      this.changeAni('walk');
    }
  };

  this.block = function() {
    if (this.imgleft == this.maximgleft) {
      this.changeAni('walk');
    }
  };

  this.dig = function() {
    if (digger && !this.digger) {
      this.changeAni('walk');
      return;
    }
    if (hole < 0) {
      digger = true;
      this.digger = true;
      hole = this.left+10;
      this.limitTop = 0;
      this.limitBottom = Lemmings.gridHeight-32;
      this.limitLeft = 0;
      this.limitRight = Lemmings.gridWidth-32;
    }
    if (this.imgleft == this.maximgleft) {
      makestep(this.top+32, this.left+10,12,2,'#000');
      this.top += this.dy;
    }
    if (digger && this.top >= this.limitBottom) {
      this.changeAni('confused');
    }
  };

  this.bash = function() {
    if (hole < 0) {
      digger = true;
      this.digger = true;
      hole = this.left+8;
      this.limitTop = 0;
      this.limitBottom = Lemmings.gridHeight-32;
      this.limitLeft = 0;
      this.limitRight = Lemmings.gridWidth-32;
    }
    if ((this.imgleft < -288 && this.imgleft > -480) || (this.imgleft < -800 && this.imgleft > -992)) {
      makestep(this.top+14, this.left+(this.dx > 0 ? 24:6),2,12,'#000');
      this.left += this.dx;
    }
    if (this.left < this.limitLeft-6 || this.left > this.limitRight+4) {
      this.changeDir();
      this.changeAni('fall');
    }
  };

  this.mine = function() {
    if (digger && !this.digger) {
      this.changeAni('walk');
      return;
    }
    if (hole < 0) {
      digger = true;
      this.digger = true;
      hole = this.left+(this.dx > 0 ? 14:6);
      this.limitTop = 0;
      this.limitBottom = Lemmings.gridHeight-32;
      this.limitLeft = 0;
      this.limitRight = Lemmings.gridWidth-32;
    }
    if (this.imgleft == this.maximgleft) {
      makestep(this.top+32, this.left+(this.dx > 0 ? 14:6),12,2,'#000');
      this.top += this.dy;
      this.left += this.dx;
    }
    if (digger && this.top >= this.limitBottom) {
      this.changeAni('confused');
    }
  };

  this.build = function() {
    if (this.imgleft == this.maximgleft) {
      makestep(this.top+30, this.left+(this.dx > 0 ? 14:6),12,2,'#F7D6D6');
      this.left += 2 * this.dx;
      this.top -= this.dy;

      if (++this.anicounter == 10) {
        this.changeAni('confused');
        return;
      }
    }
  };

  this.explode = function() {
    if (this.imgleft == this.maximgleft) {
      this.element.parentNode.removeChild(this.element);
      this.element = null;

      // explosion
      var i = 12;
      while (i--) {
        if (!closing) {
          new Spark(this.left+16, this.top+24).fly();
        }
      }

      // spawn new lemming
      if (!closing) setTimeout(Lemming, 1000*Math.random()+30);
      delete this;
    }
  };

  this.splut = function() {
    if (this.imgleft == this.maximgleft) {
      this.element.parentNode.removeChild(this.element);
      this.element = null;

      // spawn new lemming
      if (!closing) setTimeout(Lemming, 30);
      delete this;
    }
  };

  this.frie = function() {
    if (this.imgleft == this.maximgleft) {
      this.element.parentNode.removeChild(this.element);
      this.element = null;

      // spawn new lemming
      if (!closing) setTimeout(Lemming, 30);
      delete this;
    }
  };

  this.climbtop = function() {
    if (this.imgleft == this.maximgleft) {
      this.top -= this.dy*7;
      this.left += (this.dx < 0 ? this.dy*2:-this.dy*2);
      var aleat = Math.random();
      this.floater = aleat > 0.3;
      this.climber = aleat > 0.8;
      this.changeDir();
      this.changeAni('fall');
    }
  };

  this.climb = function() {
    if (this.imgleft == this.maximgleft) {
      this.top -= this.dy*6;
    }
    else {
      if (this.top < this.limitTop) {
        this.changeAni('climbtop');
      }
    }
  };

  this.changeAni('fall');
  Lemmings.layout.appendChild(this.element);
  this.anima();

}

function makestep(top, left, width, height, col) {
  var s = document.createElement('div');
  s.style.cssText = 'position:absolute;top:'+top+'px;left:'+left+'px;height:'+height+'px;width:'+width+'px;z-index:41;font-size:0px;line-height:0px;background-color:'+col+';';
  s.className = "lemming";

  Lemmings.layout.appendChild(s);
}

function Spark(x,y) {
  this.x = x;
  this.y = this.firsty = y;

  var a = Math.random() * 6.294;
  var s = Math.min(Math.random() * 5, 4);
  this.dx = s * Math.sin(a);
  this.dy = s * Math.cos(a) - 4;

  var colors = ['#fff','#ff0','#f0f','#f00','#0ff','#0f0','#00f'];

  this.spark = document.createElement('div');
  this.spark.className="lemming";
  var sparkSize = Math.floor(Math.random()*3+1);
  this.spark.style.cssText = 'position:absolute;width:'+sparkSize+'px;height:'+sparkSize+'px;overflow:hidden;background:'+colors[Math.floor(Math.random()*colors.length)]+';left:'+x+'px;top:'+y+'px;z-index:43';

  this.fly = function() {
    this.y += this.dy += 0.18;
    this.x += this.dx;

    if (this.y < 0 || this.y > this.firsty + 100) {
      this.spark.parentNode.removeChild(this.spark);
      this.spark = null;
      delete this;
    }
    else {
      this.spark.style.left = this.x+'px';
      this.spark.style.top = this.y+'px';

      setTimeout(this.fly, 10);
    }
  }.bind(this);

  Lemmings.layout.appendChild(this.spark);
}

function preloadLemmings() {
  function carga(lem) {
    Lemmings.preload[lem[0]] = {
      num: -32*(lem[2]-1),
      tipo: lem[1],
      l: new Image(),
      r: lem[1]=='b'?new Image():null
    };

    Lemmings.preload[lem[0]].l.src = preloadUrl+'lemming_'+lem[0]+'_'+(lem[1]=='b'?'l':'s')+'.gif';
    Lemmings.preload[lem[0]].l.width = '32';
    Lemmings.preload[lem[0]].l.height = '32';
    if (lem[1]=='b') {
      Lemmings.preload[lem[0]].r.src = preloadUrl+'lemming_'+lem[0]+'_r.gif';
      Lemmings.preload[lem[0]].r.width = '32';
      Lemmings.preload[lem[0]].r.height = '32';
    }
  }

  var preloadUrl = 'lemmings/';
  Lemmings.preload = {};
  var bichos = [['walk','b',8],['mine','b',24],['bash','b',32],['frie','s',14],['dig','b',16],['build','b',16],['block','b',16],['climb','b',8],['climbtop','b',8],['fall','b',4],['explode','s',16],['splut','s',16],['floatstart','b',6],['float','b',8],['confused','b',8]];
  for (i in bichos) {
    carga(bichos[i]);
  };
}

function Lemmings() {
  Lemmings.layout = document.getElementById('creditos');
  if (Lemmings.layout) {
    spriteSpeed = 70;
    numLemmings = 8;
    hole = -1; // pos left of hole
    digger = false;
    // Carga sprites
    preloadLemmings();
    Lemmings.gridWidth = Lemmings.layout.clientWidth;
    Lemmings.gridHeight = Lemmings.layout.clientHeight;
    // Crea lemmings
    for (var i = 1; i <= numLemmings; i++) {
      setTimeout(Lemming, i * 1000);
    }
  }
}

$(document).ready( function(){
  Lemmings();
});

