var Cell = function (x, y)
{
  this.x        = x;
  this.y        = y;
  this.life     = [];
  this.neighbor = [];
  this.r        = null;
  this.g        = null;
  this.b        = null;
  this.a        = null;

  for (var i = 0; i < Cell.INT_AGE_LENGTH; ++i)
  {
    this.life[i] = false;
  }
}

// STATICs
// ________________________________________________________________________

Cell.INT_AGE_LENGTH = 2;
Cell.DEFAULT_RED    = 255;
Cell.DEFAULT_GREEN  = 0;
Cell.DEFAULT_BLUE   = 0;
Cell.DEFAULT_ALHPA  = 1;

Cell.rgb2hex = function (r, g, b)
{
  // use Number.toString(radix)
  // parseInt(v, radix);
  return Cell.int2hexstr(r) + Cell.int2hexstr(g) + Cell.int2hexstr(b);
}

Cell.hex2arr = function (str)
{
  if (str[0] === '#')
  {
    str = str.substring(1);
  }
  var result = [];
  result[0]  = parseInt(str(0, 2), 16);
  result[1]  = parseInt(str(2, 4), 16);
  result[2]  = parseInt(str(4, 6), 16);
  return result;
}

Cell.int2hexstr = function (v)
{
  v = parseInt(v);
  var result = v.toString(16);
  if (v < 16)
  {
    result = '0' + result;
  }
  return result;
}



// SCRATCH PADS
// _______________________________________________________________________


Cell.prototype.getColor = function ()
{
  var result;
  switch (true)
  {
    case (this.r === null):
    case (this.g === null):
    case (this.b === null):
    case (this.a === null):
      result = null
    break;

    default:
      result = [this.r, this.g, this.b, this.a];
    break;
  }
  return result;
}


























// VIEW METHODS
// _______________________________________________________________________

Cell.prototype.turn = function ()
{
  //console.log('cell:', this.x, this.y);
  var c = [];
  for (var i = 0, len = this.neighbor.length; i < len; ++i)
  {
    if (this.neighbor[i].getLife(1))
    {
      c[c.length] = this.neighbor[i];
    }
  }
  //console.log(temp);
  //console.log('cell:', this.x, this.y, ' => ', c);
  var neighbors = c.length;
  switch (true)
  {
    case (neighbors === 3):
      this.life[0] = true;
      this.r = 0;
      this.g = 0;
      this.b = 0;
      this.a = 1;
      // REFACTOR ME
      // I believe you can write it better..
      for (var j = 0; j < neighbors; ++j)
      {
        this.r += c[j].r;
        this.g += c[j].g;
        this.b += c[j].b;
      }
      this.r = Math.floor(this.r / 3);
      this.g = Math.floor(this.g / 3);
      this.b = Math.floor(this.b / 3);

      // programmed mutantation..
      var r = Math.floor(Math.random() * 25600);
      if (r < 256)
      {
        this.r = r;
        this.g = Math.floor(Math.random() * 256);
        this.b = Math.floor(Math.random() * 256);
      }
    break;
    case (neighbors === 2):
      this.life[0] = this.life[1];
      if (!this.life[0])
      {
        this.a = this.a * .6;
        if (this.a < 0.1)
        {
          this.r = null;
          this.g = null;
          this.b = null
          this.a = 1;
        }
      }
    break;
    default:
      this.life[0] = false;
      this.a = this.a * .6;
      if (this.a < 0.1)
      {
        this.r = null;
        this.g = null;
        this.b = null
        this.a = 1;
      }
    break;
  }
  return this.life[0];
}


// UTILITY METHODS
// _______________________________________________________________________


Cell.prototype.getLife = function (age)
{
  age = age || 0;
  return this.life[age];
}


Cell.prototype.on = function (arr)
{
  arr = arr || [Cell.DEFAULT_RED, Cell.DEFAULT_GREEN, Cell.DEFAULT_BLUE, Cell.DEFAULT_ALPHA];
  this.life[0] = true;
  this.r = arr[0];
  this.g = arr[1];
  this.b = arr[2];
  this.a = arr[3];
}


Cell.prototype.off = function ()
{
  this.life[0] = false;
  this.r = null;
  this.g = null;
  this.b = null;
  this.a = null;
}


Cell.prototype.setNeighbor = function (cell)
{
//  if (this.neighbor.length >= 9)
//  {
//    throw new Error('to many neighbors');
//  }
  this.neighbor[this.neighbor.length] = cell;
}


Cell.prototype.shiftAge = function ()
{
  this.life.pop();
  this.life.unshift(false);
}


Cell.prototype.toggle = function ()
{
  this.life[0] = !this.life[0];
  //console.log('toggling: ', this.x, this.y, (this.life[0]?'true':'false'));
}



