/*
 * Copyright 2006, Peter Rowntree. All Rights Reserved.
 * http://www.hdyn.com/mail/contact.php?addr=pr
 */

var g_boxes=null;
function initBoxes(holder)
{
   g_boxes=new Boxes("g_boxes",holder);
   return g_boxes;
}

function Boxes(name,holder)
{
   this.clock=new GPTimer();
   this.nodeSet=null;
   this.name=name;
   this.holder=holder;
   this.repeatAt=-1; //no repeat
   this.min=-1;
   this.wiggleProc=simpleWiggleProc;
   this.waitMillis=13;
   this.whOpts=[70,49,1.7,1.7];  //w, h, and their factors
   this.setRepeatAt=function(repeatAt)	//now unused
   {
      this.repeatAt=repeatAt;
   }
   //wiggleProc == null => no wiggle
   this.setWiggleProc=function(wiggleProc)
   {
      this.wiggleProc=wiggleProc;
   }
   this.setWait=function(waitMillis)
   {
      this.waitMillis=waitMillis;
   }
   this.setWHOpts=function(opts)
   {
      this.whOpts=opts;
   }
   this.doRndShrink=function()
   {
      if(this.nodeSet == null)
         return;
      var node=this.nodeSet.item(rand(this.nodeSet.length));
      var w=rand(node.offsetWidth*this.whOpts[2]);
      var h=rand(node.offsetHeight*this.whOpts[3]);
      if(w > 1 && h > 1)
      {
         var s=node.style;
         s.width=w+"px";
         s.height=h+"px";
         if(this.wiggleProc != null)
            this.wiggleProc(node,s);
      }
      else
      {
         this.holder.removeChild(node);
         if(this.min >= 0)
         {
            if(this.nodeSet.length <= this.min)
            {
               this.doBoxes();
               return;
            }
         }
         else if(this.nodeSet.length <= 0)
         {
            this.clrBoxes(false);
            return;
         }
      }
      this.clock.doAfter(this.name+".doRndShrink()",this.waitMillis);
   }
   this.doBoxes=function()
   {
      var holder=this.holder;
      holder.style.width="100%";
      holder.style.height="100%";
      var w=this.whOpts[0]
      var h=this.whOpts[1];
      var nRows=Math.floor(holder.offsetHeight/h);
      if(nRows < 1)
         nRows=1;
      var nCols=Math.floor(holder.offsetWidth/w);
      if(nCols < 1)
         nCols=1;
      var x=Math.floor((holder.offsetWidth-nCols*w)/2);
      var y=Math.floor((holder.offsetHeight-nRows*h)/2);
      var sc=[0,0,0];
      var hdc=[0,0,0];
      var vdc=[0,0,0];
      setDeltas(sc,hdc,vdc,nRows,nCols);
      for(var r=0; r<nRows; ++r)
      {
         for(var c=0; c<nCols; ++c)
         {
            var d=document.createElement('div');
            d.className="boxDims";
            var s=d.style;
            s.backgroundColor=progColor(sc,hdc,null);
            s.left=(x+c*w)+"px";
            s.top=(y+r*h)+"px";
            s.zIndex=rand(8);
            holder.appendChild(d);
         }
         progColor(sc,null,vdc);
         for(var j=0; j<3; ++j)
            sc[j]-=hdc[j]*nCols;
      }
      this.nodeSet=holder.getElementsByTagName("div");
      this.min=Math.round(nRows*nCols/2);
//      if(this.min > this.repeatAt)
//         this.min=this.repeatAt;
      this.doRndShrink();
   }
   this.clrBoxes=function(clrHolder)
   {
      this.nodeSet=null;
      if(clrHolder)
         this.holder.innerHTML="";
      this.holder.style.width="0px";
      this.holder.style.height="0px";
   }
}

//--------- helpers ------------------------------------------------------------

function simpleWiggleProc(node,style)
{
   style.left=(node.offsetLeft+rand(100)*(1-rand(3)))+"px";
   style.top=(node.offsetTop+rand(100)*(1-rand(3)))+"px";
}

function setDeltas(sc,hdc,vdc,nRows,nCols)
{
   var d;
   for(var j=0; j<3; ++j)
   {
      var nc=rand(256);
      var hd=rand(256)-nc;
      var vd=rand(256)-nc;
      var endC=nc+hd+vd;
      if(endC > 255) //=> hd>0 && vd>0
      {
         d=Math.floor((endC-255)/(2*(hd/vd)));
         vd-=d;
         hd-=endC-255-d;
      }
      else if(endC < 0)  //=> hd<0 && vd<0
      {
         d=Math.ceil(endC/(2*(hd/vd)));
         vd-=d;
         hd-=endC-d;
      }
      hdc[j] = hd < 0 ? Math.ceil(hd/nCols) : Math.floor(hd/nCols);
      vdc[j] = vd < 0 ? Math.ceil(vd/nRows) : Math.floor(vd/nRows);
      sc[j]=nc;
   }
}

function progColor(sc,hdc,vdc)
{
   for(var j=0; j<3; ++j)
      sc[j]+=(hdc == null ? 0 : hdc[j]) + (vdc == null ? 0 : vdc[j]);
   return "rgb("+sc[0]+","+sc[1]+","+sc[2]+")";
}

function rand(lt)
{
   return Math.floor(Math.random()*0.99999*lt);
}

//------------------------------------------------------------------------------

