var passiveImage=new Image
passiveImage.src="life_pas.gif"
var activeImage=new Image
activeImage.src="life_act.gif"

var ready=false
var running=false
var count=0
var timerId

var initialDensity=0.25
var stopMessage="stop"

var fieldSize
var screenField
var nextField
var lastField
var oneButLastField

function initializeField()
{
  var countY
  var countX

  for (countY=0;countY<=fieldSize+1;countY++)
  {
    screenField[countY][0]=false
    screenField[countY][fieldSize+1]=false
  }
  for (countX=1;countX<=fieldSize;countX++)
  {
    screenField[0][countX]=false
    screenField[fieldSize+1][countX]=false
  }
  for (countY=1;countY<=fieldSize;countY++)
    for (countX=1;countX<=fieldSize;countX++)
      screenField[countY][countX]=false
}

function randomizeField()
{
  var countY
  var countX

  for (countY=1;countY<=fieldSize;countY++)
    for (countX=1;countX<=fieldSize;countX++)
      nextField[countY][countX]=Math.random()<initialDensity
  count=0
}

function updateScreen()
{
  var totalActive
  var stableState
  var bistableState
  var tristableState
  var countY
  var countX

  totalActive=0
  stableState=true
  bistableState=true
  tristableState=true
  for (countY=1;countY<=fieldSize;countY++)
    for (countX=1;countX<=fieldSize;countX++)
    {
      if (nextField[countY][countX])
        totalActive++
      if (nextField[countY][countX]!=lastField[countY][countX])
        bistableState=false
      if (nextField[countY][countX]!=oneButLastField[countY][countX])
        tristableState=false
      oneButLastField[countY][countX]=lastField[countY][countX]
      lastField[countY][countX]=screenField[countY][countX]
      if (screenField[countY][countX]!=nextField[countY][countX])
      {
        stableState=false
        document.images["cell_"+countY+"_"+countX].src=
          nextField[countY][countX]?activeImage.src:passiveImage.src
        screenField[countY][countX]=nextField[countY][countX]
      }
    }
  if (totalActive==0)
  {
    window.alert("The population has died out in generation "+count+". The game is stopped.")
    doStop()
  }
  else if (stableState&&(count>0))
  {
    window.alert("The population has reached a stable state in generation "+count+". The game is stopped.")
    doStop()
  }
  else if (bistableState&&(count>1))
  {
    window.alert("The population has reached a bistable state in generation "+count+". The game is stopped.")
    doStop()
  }
  else if (tristableState&&(count>2))
  {
    window.alert("The population has reached a tristable state in generation "+count+". The game is stopped.")
    doStop()
  }
  document.fieldForm["Count"].value=running?count:stopMessage
}

function nextStage()
{
  var countY
  var countX
  var actives
  var offsetY
  var offsetX

  for (countY=1;countY<=fieldSize;countY++)
    for (countX=1;countX<=fieldSize;countX++)
    {
      actives=-screenField[countY][countX]
      for (offsetY=-1;offsetY<=1;offsetY++)
        for (offsetX=-1;offsetX<=1;offsetX++)
          if (screenField[countY+offsetY][countX+offsetX])
            actives++
      if (!screenField[countY][countX]&&(actives==3))
        nextField[countY][countX]=true
      else if (screenField[countY][countX]&&(actives<=1))
        nextField[countY][countX]=false
      else if (screenField[countY][countX]&&(actives>=4))
        nextField[countY][countX]=false
    }
  count++
}

function initializeTimer()
{
  timerId=setTimeout("nextStage();updateScreen();if (running) initializeTimer()",1000)
}

function doStart()
{
  if (ready&&!running)
  {
    running=true
    nextStage()
    updateScreen()
    if (running) initializeTimer()
  }
}

function doStop()
{
  if (ready&&running)
  {
    running=false
    clearTimeout(timerId)
    document.fieldForm["Count"].value=stopMessage
  }
}

function doReset()
{
  if (ready&&!running)
  {
    randomizeField()
    updateScreen()
  }
}

function enableScript(size)
{
  fieldSize=size
  screenField=new Array(fieldSize+2)
  nextField=new Array(fieldSize+2)
  lastField=new Array(fieldSize+2)
  oneButLastField=new Array(fieldSize+2)
  for (countY=0;countY<=fieldSize+1;countY++)
  {
    screenField[countY]=new Array(fieldSize+2)
    nextField[countY]=new Array(fieldSize+2)
    lastField[countY]=new Array(fieldSize+2)
    oneButLastField[countY]=new Array(fieldSize+2)
  }
  initializeField()
  randomizeField()
  updateScreen()
  ready=true
}
