// ----------------------------------------------------------------------------------------
// var	mousTrail="  * * *******************************" | Declare these in <head></head>.
// ,	mousOffset=[550,350]				  | mousOffset[x,y] starting positions
// ----------------------------------------------------------------------------------------
mousTrail=mousTrail.split(""); // chop it up into an array of single characters
var	posMax=mousTrail.length-1
,	fontSiz  =[6,8,10,12,14,16,18,20,22,20,18,15,12,9]
,	fontMult =1.7
,	colorWarpInterval ,	  colorWarpWait		=55555
,	wiggleInterval	  ,	  wiggleWaitReset	=   25
,	wiggleWarpTimeout ,	  wiggleWarpWaitReset	= 1800
,	ignoreMouseTimeout,	  ignoreMouseWait	=12000
,	wiggleWait		 =wiggleWaitReset
,	wiggleWaitResetMargin	 =wiggleWaitReset	+   10
,	wiggleWarpWaitResetMargin=wiggleWarpWaitReset	+  450
,	wiggleSlowDown	=.05
,	wiggleSlowDownWk=  wiggleSlowDown
,	wiggleWarpWait	=		   wiggleWarpWaitReset
,	wiggleWarpSlowDown=wiggleSlowDown*(wiggleWarpWaitReset/wiggleWaitReset)
,	chaseIt		=true
,	chaseItsOwnTail	=false
,	currColor=new Array(mousTrail.length)
,	starStyle=new Array(mousTrail.length)
,	letrStyle=new Array(7), n, addHTML="", lastColor
,	siz=0, sizStart=-1
,	rN,rI=11,r=255
,	gN,gI=14,g=128
,	bN,bI=18,b=  0
,	wN,wI
,	evt
,	rgb
,	rgbMax=638
,	rgbMin=128
,	zerOr1=0
,	warpIndex=0
,	x=new x_y(4,[+0.78,+1.55,+2.3,+3,+3.65,+4.24,+4.76,+5.2,+5.54,+5.8,+5.95,+6,+5.95,+5.8,+5.54,+5.2,+4.76,+4.24,+3.65,+3,+2.3,+1.55,+0.78,+0,-0.78,-1.55,-2.3,-3,-3.65,-4.24,-4.76,-5.2,-5.54,-5.8,-5.95,-6,-5.95,-5.8,-5.54,-5.2,-4.76,-4.24,-3.65,-3,-2.3,-1.55,-0.78,-0]) //length:48
,	y=new x_y(0,[-6,-5.95,-5.8,-5.54,-5.2,-4.76,-4.24,-3.65,-3,-2.3,-1.55,-0.78,-0,+0.78,+1.55,+2.3,+3,+3.65,+4.24,+4.76,+5.2,+5.54,+5.8,+5.95,+6,+5.95,+5.8,+5.54,+5.2,+4.76,+4.24,+3.65,+3,+2.3,+1.55,+0.78,+0,-0.78,-1.55,-2.3,-3,-3.65,-4.24,-4.76,-5.2,-5.54,-5.8,-5.95]) //length:48
; //---------------------------------------------------------------------------------------

for (n=0;n<mousTrail.length;n++) { addHTML+="\<span id='mousTrail"+n+"' class='mousTrail'\>"+mousTrail[n]+"\<\/span\>"; }
//-----------------------------------------------------------------------------------------

function x_y (startPos, algo) {
	this.ix		=0;
	this.csr	=0;
	this.prev	=0;
	this.incr	=0;
	this.scroll	=0;
	this.max	=0;
	this.p		=0;
	this.frameOffset=0;
	this.pos	=new Array(mousTrail.length);
	this.whichWay	=false;
	this.alg	=algo;
	this.algMax	=this.alg.length-2;
	this.start	=posMax%this.algMax+startPos;
	this.decr	=2.8/this.algMax;
	this.incrStart	=(mousTrail.length/this.algMax)*3;
} // --------------------------------------------------------------------

function mousTrailsSetup (pWiggleWaitReset,pWiggleWarpWaitReset,pIgnoreMouseWait) {
//	document.getElementsByTagName("body")[0].innerHTML+=addHTML;
	if (!document.getElementById && document.all) { 
	     document.getElementById = new Function('id','return document.all[id]')}
	letrStyle[0]=document.getElementById("nameLtr0").style;
	letrStyle[1]=document.getElementById("nameLtr1").style;
	letrStyle[2]=document.getElementById("nameLtr2").style;
	letrStyle[3]=document.getElementById("nameLtr3").style;
	letrStyle[4]=document.getElementById("nameLtr4").style;
	letrStyle[5]=document.getElementById("nameLtr5").style;
	letrStyle[6]=document.getElementById("nameLtr6").style;
	for (n=0;n<starStyle.length;++n) { starStyle[n]=document.getElementById("mousTrail"+n).style; }
	wiggleWaitReset      =pWiggleWaitReset     ||wiggleWaitReset;     // Save parm||default to common field.
	wiggleWarpWaitReset  =pWiggleWarpWaitReset ||wiggleWarpWaitReset; // Save parm||default to common field.
	ignoreMouseWait      =pIgnoreMouseWait     ||ignoreMouseWait;     // Save parm||default to common field.
	//------ define the individual characters ---------
        x.pos[0]=(mousOffset&&mousOffset[0])? mousOffset[0]:550;
        y.pos[0]=(mousOffset&&mousOffset[1])? mousOffset[1]:350;
	obj=document.getElementById("mousTrail0").style;
	obj.left=x.pos[0]+'px';
	obj.top =y.pos[0]+'px';
	//------ first, establish initial positions -------
	for (n=1;n<mousTrail.length;n++) {
	  x.pos[n]=x.pos[n-1]+(x.alg[x.ix]*1.5)+(n/x.algMax); x.ix=(x.ix<x.algMax) ? x.ix+=1 : 0;
	  y.pos[n]=y.pos[n-1]+(y.alg[y.ix]*1.5)+(n/y.algMax); y.ix=(y.ix<y.algMax) ? y.ix+=1 : 0;
	  if(++siz>=siz.length)siz=0; // 
	  //-------------- define the individual characters -------------------------------
	  obj=document.getElementById("mousTrail"+n).style;
	  obj.left=x.pos[n]+'px';
	  obj.top =y.pos[n]+'px';
	} //-------------------------------------------------------------------------------
//	document.onkeypress =doKey;
	document.onmousemove= chaseMouse;
	document.onclick    =ignoreMouse;
	document.ondblclick =resumeFullSpeed; // Only needed when NOT setup to resume speed upon any mouse-movement.
	colorWarpInterval=setInterval("colorWarp()" ,colorWarpWait);
	wiggleWarpTimeout=setTimeout("wiggleWarp()",wiggleWarpWait);
	wiggleInterval   =setInterval(   "wiggle()"    ,wiggleWait);
	wiggle();
	return true;
} // end mousTrailsSetup () ----------------------------------------------------------------

function doKey (e) {
	var F12=123,keyPressed=(e)?e.which:window.event.keyCode;
//      window.alert("keyPressed="+keyPressed);
	if(keyPressed>0&&keyPressed<936){window.alert("keyPressed="+keyPressed);}
} // end doKey () --------------------------------------------------------------------------

function chaseMouse (e) {
	if (!chaseIt)     return true; // Skip if mouse-chasing is off (from single-click).
	evt=e||window.event;
	if (!evt.clientX) return true;
	wiggleSlowDownWk=0;
//	if      (evt.target)     targ = evt.target;      | Activate these if you need to
//	else if (evt.srcElement) targ = evt.srcElement;  |  know the target of the event. (Not needed here.)
//	if (targ.nodeType == 3)  targ = targ.parentNode; | This one defeats a Safari bug.
	chaseItsOwnTail = false; // Stop chasing it's own tail, in case that's in effect.
	getScroll();			// Get window/frame scroll values
//	x.frameOffset = evt.screenX - evt.clientX; // used for bouncing off left/right borders
//	y.frameOffset = evt.screenY - evt.clientY; // used for bouncing off top/bottom borders
	x.frameOffset = 0-x.scroll;	// used for bouncing off left/right borders
	y.frameOffset = 0-y.scroll;	// used for bouncing off top/bottom borders
	if		(evt.pageX||evt.pageY) {
		x.csr = (evt.pageX);
		y.csr = (evt.pageY);
	}
	else if 	(evt.clientX||evt.clientY) {
		x.csr = (evt.clientX+x.scroll);	// Determine X 
		y.csr = (evt.clientY+y.scroll);	//         & Y coordinates of mouse (cursor) 
	}
	x.prev =x.csr;
	y.prev =y.csr;
	if (wiggleWait>wiggleWaitResetMargin) {
	  clearInterval(wiggleInterval);     // Cancels Interval set earlier w/ setInterval method. 
	  wiggleInterval=setInterval("wiggle()",wiggleWaitReset);
	}
	if (wiggleWarpWait>wiggleWarpWaitResetMargin) {
	  clearTimeout(wiggleWarpTimeout);
	  wiggleWarpTimeout=setTimeout("wiggleWarp()",wiggleWarpWaitReset);
	}
	wiggleWait      =wiggleWaitReset;     // This undoes any SlowDown currently applied
	wiggleWarpWait  =wiggleWarpWaitReset; // This undoes any SlowDown currently applied
	wiggleSlowDownWk=wiggleSlowDown;      // Set back to real SlowDown value (not 0)
} // end chaseMouse () ---------------------------------------------------------------------

function ignoreMouse () { // turns off mouse-tracking briefly when cursor clicked
	chaseIt=!chaseIt; 
	if (!chaseIt)ignoreMouseTimeout=setTimeout("ignoreMouse()",ignoreMouseWait);
	return true;
} // end ignoreMouse () --------------------------------------------------------------------

function wiggle () {
	zerOr1=1-zerOr1;
	if (++warpIndex>2)warpIndex=0;
	if (chaseItsOwnTail) { // chaseItsOwnTail : makes the start of the string chase after the end of the string
	  x.csr=x.pos[posMax];
	  y.csr=y.pos[posMax];
	}
	x.ix=x.start+zerOr1; x.incr=x.incrStart;  // Set initial x.ix & x.incr
	y.ix=y.start+zerOr1; y.incr=y.incrStart;  // Set initial y.ix & y.incr 
	if(++sizStart>=fontSiz.length)sizStart=0; // Set index to initial size
	siz= sizStart;
	if (x.whichWay) if (x.start>0       ) --x.start; else { ++x.start; x.whichWay=false; }
	           else if (x.start<x.algMax) ++x.start; else { --x.start; x.whichWay=true;  }
	if (y.whichWay) if (y.start>0       ) --y.start; else { ++y.start; y.whichWay=false; }
	           else if (y.start<y.algMax) ++y.start; else { --y.start; y.whichWay=true;  }
	lastColor=currColor[posMax]; // Save last color for when chasing tail
	for (n=posMax; n>0; --n) {   // Load the string of stars starting from tail end.
	  y.p=y.pos[n]=(y.pos[n]+y.pos[n-1]+(y.alg[y.ix]*y.incr))/2; // Calc new x/y positions
	  x.p=x.pos[n]=(x.pos[n]+x.pos[n-1]+(x.alg[x.ix]*x.incr))/2; // & save them in .pos[n].
	  bounceBorder();
	  obj=starStyle[n]; //=document.getElementById("mousTrail"+n).style;
	  obj.left=x.p+'px';                // Set the
	  obj.top =y.p+'px';                // position.
	  if (++siz>=fontSiz.length) siz=0; // 
	  obj.fontSize  =(fontMult*fontSiz[siz])+'px'; 
	  obj.color=currColor[n]=currColor[n-1];
	  x.ix=(x.ix<x.algMax) ? x.ix+2 : zerOr1;  //   | These all apply to
	  y.ix=(y.ix<y.algMax) ? y.ix+2 : zerOr1;  //   | the next time we
	  x.incr-=x.decr; // Produce inward spiraling   | loop thru here for
	  y.incr-=y.decr; // (instead of just a circle) | the next inward star.
	}
	if (chaseItsOwnTail) {
	  currColor[0]=lastColor;
	}
	else { // Each color (r,g,b) runs up & down the 256 (0-255) degrees of that color, bouncing back & forth 
	  rN=r+rI;
	  gN=g+gI;
	  bN=b+bI;
	  rgb=rN+gN+bN;
	  if      (rgb<rgbMin) {
//	    document.all.info.innerHTML="<span style='color:blue'>rgb["+rgb+"] &lt; Min<br />r:"+r+" rI:"+rI+"<br />g:"+g+" gI:"+gI+"<br />b:"+b+" bI:"+bI+"</span>";// +"<br />"+document.all.info.innerHTML;
	    if            (rI<0) 
	      if          (gI<0) 
	        if        (bI<0)
	          if      (rN<=gN && rN<=bN) rI=0-rI
	          else
                    if    (gN<=bN && gN<=rN) gI=0-gI
	            else                     bI=0-bI
	        else 
	          if      (rN<=gN)           rI=0-rI
	          else                       gI=0-gI
	      else                     
	        if        (bI<0   && bN<=rN) bI=0-bI
	        else                         rI=0-rI
	    else 
              if          (gI<0) 
	        if        (bI<0   && bN<=gN) bI=0-bI
	        else                         gI=0-gI 
	      else                     
	        if        (bI<0)             bI=0-bI
                else      {}
//	    document.all.info.innerHTML+="<span style='color:green'><br />rgb["+rgb+"] &lt; Min<br />r:"+r+" rI:"+rI+"<br />g:"+g+" gI:"+gI+"<br />b:"+b+" bI:"+bI+"</span>";// +"<br />"+document.all.info.innerHTML;
	  } else if (rgb>rgbMax) {
//	    document.all.info.innerHTML="<span style='color:red'>rgb["+rgb+"] &gt; Max<br />r:"+r+" rI:"+rI+"<br />g:"+g+" gI:"+gI+"<br />b:"+b+" bI:"+bI+"</span>";// +"<br />"+document.all.info.innerHTML;
	    if            (rI>0) 
	      if          (gI>0) 
	        if        (bI>0) 
	          if      (rN>=gN && rN>=bN) rI=0-rI
	          else
                    if    (gN>=bN && gN>=rN) gI=0-gI
	            else                     bI=0-bI
	        else 
	          if      (rN>=gN)           rI=0-rI
	          else                       gI=0-gI
	      else                     
	        if        (bI>0   && bN>=rN) bI=0-bI
	        else                         rI=0-rI
	    else 
              if          (gI>0) 
	        if        (bI>0   && bN>=gN) bI=0-bI
	        else                         gI=0-gI 
	      else                     
	        if        (bI>0)             bI=0-bI
                else      {}
//	    document.all.info.innerHTML+="<span style='color:green'><br />rgb["+rgb+"] &gt; Max<br />r:"+r+" rI:"+rI+"<br />g:"+g+" gI:"+gI+"<br />b:"+b+" bI:"+bI+"</span>";// +"<br />"+document.all.info.innerHTML;
          }
	  r+=rI; if (r>255) { r=510-r; if (rI>0) rI=0-rI; } else if (r<0) { r=0-r; if (rI<0) rI=0-rI; }
	  g+=gI; if (g>255) { g=510-g; if (gI>0) gI=0-gI; } else if (g<0) { g=0-g; if (gI<0) gI=0-gI; }
	  b+=bI; if (b>255) { b=510-b; if (bI>0) bI=0-bI; } else if (b<0) { b=0-b; if (bI<0) bI=0-bI; }
	  wN=(posMax)*5;
	  rN=(r+wN); if (rN>255) {rN=510-rN;} else if (rN<0) {rN=0-rN;}
	  gN=(g+wN); if (gN>255) {gN=510-gN;} else if (gN<0) {gN=0-gN;}
	  bN=(b+wN); if (bN>255) {bN=510-bN;} else if (bN<0) {bN=0-bN;}
	  currColor[0]="rgb("+rN+","+gN+","+bN+")";
	}
	obj=starStyle[0]; //=document.getElementById("mousTrail"+n).style;
	x.p=x.pos[0]=x.csr+(   zerOr1 *4); // These extra additions/subtraction are to make that leading 
	y.p=y.pos[0]=y.csr-((1-zerOr1)*4); // star hover around the cursor, but not sit exactly on it.
	bounceBorder();
	obj.left=x.p+'px';                // Set the
	obj.top	=y.p+'px';                // position.
	if (++siz>=fontSiz.length) siz=0; // 
	obj.fontSize  =(fontMult*fontSiz[siz])+'px'; 
	obj.color=currColor[0];
	x.ix=(x.ix<x.algMax) ? x.ix+2 : zerOr1;  //   | These all apply to
	y.ix=(y.ix<y.algMax) ? y.ix+2 : zerOr1;  //   | the next time we
	x.incr-=x.decr; // Produce inward spiraling   | loop thru here for
	y.incr-=y.decr; // (instead of just a circle) | the next inward star.
	letrStyle[0].color=starStyle[0].color;
	letrStyle[1].color=starStyle[3].color;
	letrStyle[2].color=starStyle[6].color;
	letrStyle[3].color=starStyle[9].color;
	letrStyle[4].color=starStyle[12].color;
	letrStyle[5].color=starStyle[15].color;
	letrStyle[6].color=starStyle[18].color;
        if (chaseItsOwnTail) { 
//	  bod.style.scrollbar3dLightColor   =starStyle[16].color;// "#9A68BA";
//	  bod.style.scrollbarHighlightColor =starStyle[18].color;// "#EABAFA";
	  bod.style.scrollbarFaceColor      =starStyle[20].color;// "#BA88EA";
//	  bod.style.scrollbarShadowColor    =starStyle[22].color;// "#9A68BA";
//	  bod.style.scrollbarDarkShadowColor=starStyle[24].color;// "#7A489A";
	  bod.style.scrollbarTrackColor     =starStyle[26].color;// "#938893";
//	  bod.style.scrollbarArrowColor     =starStyle[28].color;// "#AA0000";
	}
	wiggleWait    +=wiggleSlowDownWk;   // Slow down wiggle gradually
	wiggleWarpWait+=wiggleWarpSlowDown; // Slow down wiggleWarp gradually
} // end wiggle () -------------------------------------------------------------------------

function wiggleWarp () { // A "Warp" often occurs ... giving MousTrail an attention-deficit.
	if        (warpIndex==0) {      // That's why it looks like a puppy chasing a cricket ...
	  y.p=((y.pos[posMax]*2)+(y.csr*3)+(y.prev  ))/6;
	  x.p=((x.pos[posMax]*2)+(x.csr*3)+(x.prev  ))/6;
	  chaseItsOwnTail=false;
	} else if (warpIndex==1) {      // ... or something similar (this one more yearning for it's roots)
	  y.p=((y.pos[posMax]*2)+(y.csr*2)+(y.prev*2))/6;
	  x.p=((x.pos[posMax]*2)+(x.csr*2)+(x.prev*2))/6;
	  chaseItsOwnTail=false;
	} else {			// ... or it's truly chasing it's own tail. ("posMax" points to last dot.)
	  y.p=(y.pos[posMax]);
	  x.p=(x.pos[posMax]);
	  chaseItsOwnTail=true;
	}
	if    (!chaseItsOwnTail) {
//	  bod.style.scrollbar3dLightColor   ="#9A68BA";
//	  bod.style.scrollbarHighlightColor ="#EABAFA";
	  bod.style.scrollbarFaceColor      ="#BA88EA";
//	  bod.style.scrollbarShadowColor    ="#9A68BA";
//	  bod.style.scrollbarDarkShadowColor="#7A489A";
	  bod.style.scrollbarTrackColor     ="#938893";
//	  bod.style.scrollbarArrowColor     ="#AA0000";
	}
	bounceBorder();
	y.csr=y.p;	// The "csr" locations are where the trail starts.  It's normally where the cursor is
	x.csr=x.p;	// (hence the name "csr"), but here, we're decoying it off on a wild goose chase.
	wiggleWarpTimeout=setTimeout("wiggleWarp()",wiggleWarpWait);
	if (wiggleSlowDownWk) {              // Rather than reset Wiggle to it's SlowDown speed constantly,
	  clearInterval(wiggleInterval);     // we do it here, as it's less often (less overhead) but still effective.
	  wiggleInterval=setInterval("wiggle()",wiggleWait);
	}
} // end wiggleWarp () ---------------------------------------------------------------------

function colorWarp () {		       // A "Warp" occasionally occurs ... changing the color increment pattern.
	wI=rI; rI=gI; gI=bI; bI=wI;    // Rotate the r|g|b color Increments (wI : just a work-field for juggling)
//	document.all.info.innerHTML="Red : "+rI+"<br />Green : "+gI+"<br />Blue : "+bI+"<br />"+document.all.info.innerHTML;
} // end colorWarp () ----------------------------------------------------------------------

function bounceBorder () { // ---- Bounce off borders
	x.max=(screen.availWidth -14)-x.frameOffset;
	y.max=(screen.availHeight-43)-y.frameOffset;
	if	(y.p<10   ) y.p= 20      -y.p;
	else if (y.p>y.max) y.p=(2*y.max)-y.p;
	if	(x.p<10   ) x.p= 20      -x.p;
	else if (x.p>x.max) x.p=(2*x.max)-x.p;
} // end bounceBorder () -------------------------------------------------------------------

function getScroll () { // ---- Establish how far the window/frame has been scrolled ---- //
	if      (  window.innerHeight                 ) { x.scroll = window.pageXOffset; 
							  y.scroll = window.pageYOffset; }
	else if (  document.documentElement 
	        && document.documentElement.scrollTop ) { x.scroll = document.documentElement.scrollLeft;
							  y.scroll = document.documentElement.scrollTop ; }
	else if (  document.body                      ) { x.scroll = document.body.scrollLeft;
							  y.scroll = document.body.scrollTop ; }
//	else window.alert('Scrolling not determined'); // _.scroll fields default to zero
} // end getScroll () ----------------------------------------------------------------------

function resumeFullSpeed () { // Runs on cursor double-click
	wiggleWait=wiggleWaitReset;       // Each time, it resumes full speed.
	wiggleSlowDownWk=(wiggleSlowDownWk)? 0:wiggleSlowDown; // Each time, it turns Slow-Down function ON or OFF.
//	document.all.info.innerHTML="resumeFullSpeed : "+wiggleSlowDownWk+"<br />"+document.all.info.innerHTML;
	return true;
} // end resumeFullSpeed () --------------------------------------------------------------------