/* fireflies.js
 2005 T. R. Treadwell */

var g_nNumFlies = 20;
var g_nIndexFly = 0;
var g_SpeedLimitLower = 0.2;
var g_SpeedLimitUpper = 3;
var g_SpeedChangeFactor = 0.05;
var g_HeadingChangeAmt = 0.2;
var g_FrameDuration = 100;	// minimum duration of frame in ms
var g_PhaseDuration = 4000;	// duration of flash cycle in ms
var g_LightOnTime = 0.3;	// ratio of light on time to total flash cycle

var g_nTimer=0;
var g_Pi = 3.14159;
var g_Pi2 = 6.28318;
var g_HeadingLimitLower = -1 * g_Pi;
var g_HeadingLimitUpper = g_Pi;
var g_timLastFrame = 0;
var g_arrFlies = new Array();

var g_nMinX = 10;
var g_nMinY = 10;
var g_nMaxX = 790;		// default if window width is not detected
var g_nMaxY = 590;		// default if window height is not detected
var g_fPhaseIncr = g_FrameDuration / g_PhaseDuration;

function startAnim()
{
  setDimensions();
//  alert("g_nMaxX=" + g_nMaxX);
  initFlies();
  moveFlies();
}

function setDimensions()
{
  var nWinWidth = 0;
  var nWinHeight = 0;
  if(window.innerWidth)
  {				// Mozilla and other standards-compliant browsers
    g_nMaxX = window.innerWidth - 10;
    g_nMaxY = window.innerHeight - 10;
  }
  else if(document.all)
  {				// IE
    g_nMaxX = document.body.clientWidth - 10;
    g_nMaxY = document.body.clientHeight - 10;
  }
}

function initFlies()
{
  var nI = 0;
  for(nI=0; nI < g_nNumFlies; ++nI)
  {
    var oFly = new firefly();
    drawFirefly(oFly);
    g_arrFlies.push(oFly);
  }
}

function moveFlies()
{
  var nI = 0;
  for(nI=0; nI < g_nNumFlies; ++nI)
  {
    var oFly = g_arrFlies[nI];
    moveFirefly(oFly);
    drawFirefly(oFly);
  }
  g_nTimer = window.setTimeout("moveFlies();",g_FrameDuration);
}

function firefly(nX,nY,fSpeed,fHeading,fPhase,sColor)
{
 /* constructor for firefly
 nX 		= x-position (pixels)
 nY 		= y-position (pixels)
 fSpeed		= absolute speed, distance/s (along X axis, distance = # of pixels)
 fHeading 	= compass angle of motion, where "north" = up = 0
 fPhase 	= phase of flash pattern, 0.0 - 1.0
 sColor 	= color of firefly in CSS format #nnnnnn	*/

 this.Id = "firefly" + g_nIndexFly;
 this.nX = nX || RandomWithinRange(g_nMinX, g_nMaxX);
 this.nY = nY || RandomWithinRange(g_nMinY, g_nMaxY);
 this.fSpeed = fSpeed || RandomWithinRange(g_SpeedLimitLower, g_SpeedLimitUpper);
 this.fHeading = fHeading || RandomWithinRange(g_HeadingLimitLower, g_HeadingLimitUpper);
 this.fPhase = fPhase || RandomWithinRange(0.0, 1.0);
 this.backgroundImage = "img/ff" + padZeros(g_nIndexFly, 3) + ".png";
 
 oElem = document.getElementById(this.Id);
 if(oElem != null)
 {
   oElem.style.backgroundImage = "url(\"" + this.backgroundImage + "\")";
   oElem.style.backgroundRepeat = "no-repeat";
   oElem.style.height = "3px";
 }
 ++g_nIndexFly;
}

function moveFirefly(oFirefly)
{
 // adjust speed randomly
 fSpeedChangeFactor = 1 + ((Math.random() - 0.5) * 2 * g_SpeedChangeFactor);
 oFirefly.fSpeed *= fSpeedChangeFactor;
 if(oFirefly.fSpeed < g_SpeedLimitLower) oFirefly.fSpeed = g_SpeedLimitLower;
 if(oFirefly.fSpeed > g_SpeedLimitUpper) oFirefly.fSpeed = g_SpeedLimitUpper;

 // adjust heading randomly
 fHeadingIncr = (Math.random() - 0.5) * 2 * g_HeadingChangeAmt;
 oFirefly.fHeading += fHeadingIncr;
 if(oFirefly.fHeading < g_HeadingLimitLower) oFirefly.fHeading += g_Pi2;
 if(oFirefly.fHeading > g_HeadingLimitUpper) oFirefly.fHeading -= g_Pi2;

 // calculate new position
 oFirefly.nX += Math.sin(oFirefly.fHeading) * oFirefly.fSpeed;
 if(oFirefly.nX < g_nMinX) oFirefly.nX = g_nMaxX;
 if(oFirefly.nX > g_nMaxX) oFirefly.nX = g_nMinX;
 
 oFirefly.nY += Math.cos(oFirefly.fHeading) * oFirefly.fSpeed;
 if(oFirefly.nY < g_nMinY) oFirefly.nY = g_nMaxY;
 if(oFirefly.nY > g_nMaxY) oFirefly.nY = g_nMinY;
 
 // calculate phase
 oFirefly.fPhase += g_fPhaseIncr;
 if(oFirefly.fPhase > 1) oFirefly.fPhase -= 1;
}

function drawFirefly(oFirefly)
{
  oElem = document.getElementById(oFirefly.Id);
  if(oElem != null)
  {
    if((oFirefly.fPhase > 0) && (oFirefly.fPhase < g_LightOnTime))
    {
      oElem.style.left = Math.ceil(oFirefly.nX) + "px";
      oElem.style.top = Math.ceil(oFirefly.nY) + "px";
      oElem.style.visibility = "visible";
    }
    else
    {
      oElem.style.visibility = "hidden";
    }
  }
}

function padZeros(strX, nWidth)
{
  var strOut = new String(strX);
  while(strOut.length < nWidth)
    strOut = "0" + strOut;

  return strOut;
}

function RandomWithinRange(nMin, nMax)
{
  return nMin + (Math.random() * (nMax - nMin));
}
