var snowmax=33; 							// set the number of snowflakes
var sinkspeed=0.5;							// set the speed of falling
var snowsize=20;							// set the size of snowflaxes (we need it to have different speed of falling)
var drag=0.22;								// linear drag coeficient
var milisec=25;								// refresh flakes every how many miliseconds
var n=0,m=0,dens=40;						// number of active flakes, counter for density, add new flake every how many milisec
var depthofall=768;							// how deep the flakes fall before they appear at the top again (set something for very old browsers)
var widthorizontal=1024;					// widht of the flake falling area (set something for very old browsers)
var snow=new Array(snowmax);				// main array; this hold properties of each flake; apart from some exceptions
var LRspeed=new Array(snowmax);				// speed of left/right wigling
var LRamp=new Array(snowmax);				// maximal left/right amplitude of flakes
var angle=new Array(snowmax);				// left/right angle variable
var vacant = new Array(snowmax);			// array holding free indexes for <span> to hold new flakes
var nhold,free=0;							// for efficiency, not to use too many open <span>
var removeflake,mothership;					// for removing the flakes
var tempX=0,oldX=0,speedX=0;				// mouse speed X
var tempY=0,oldY=0,speedY=0;				// mouse speed Y

var flakes=new Array("<img style='padding:32px; border: 0px solid #ff0000;' src='flakes/s1.png' />","<img style='padding:32px; border: 0px solid #ff0000;' src='flakes/s2.png' />");	

window.onresize = measurewindow;			// if the user resizes, then change depthofall and widthorizontal
document.onmousemove = measuremouse;		// if the user mov	es mouse, then get mouse speed 
var X;										// variable to kill the main timer
var pom='"';								// to get " to be dispalyed
var WS;										// can we use innerWidth or not
var FF;										// Firefox, yes or no?

// main calling function
function fall()
{
	document.getElementById("controlfall").style.display="block";
	document.getElementById("countflakes").innerHTML=n;
	
	WS=window.innerWidth?true:false;
	FF=(navigator.userAgent.indexOf("Firefox")!=-1)?true:false;		
	measurewindow();
	letitfall(); 
}

// this function determines mouse speed (uses location for that)
function measuremouse(e) 
{
	oldX=tempX;
	oldY=tempY;

	if (FF==false)
	{
		tempX=event.clientX;
		tempY=event.clientY;
	}
	else if (document.captureEvents) 
	{
		document.captureEvents(Event.MOUSEMOVE);
		tempX = e.pageX;
		tempY = e.pageY;
	}
	
	// determine speed
	speedX=tempX-oldX;
	speedY=tempY-oldY;

	// increase speed to make it more sensitive
	if (speedX>1 && speedX<13) speedX=13;
	if (speedX<-1 && speedX>-13) speedX=-13;
	if (speedY>1 && speedY<13) speedY=13;
	if (speedY<-1 && speedY>-13) speedY=-13;
}

// this function define an integer random number between zero and range-1
function randommaker(range) 
{		
	rand=Math.floor(range*Math.random());
    return rand;
}

// determine the window width and height as well as offset in vertical scroll
function measurewindow()
{
	if(WS==true) 
	{
		depthofall = window.innerHeight;
		widthorizontal = window.innerWidth;
	} 
	else // be kind to old browsers
	{
		depthofall = document.documentElement.clientHeight;
		widthorizontal = document.documentElement.clientWidth;
	}
}

// this function determines what happens when bumping into a flake with the mouse
function overitem(whichone)
{
	snow[whichone].VX=snow[whichone].VX+speedX;
	snow[whichone].VY=snow[whichone].VY+speedY;
}

// main function for making snow/rain/flowers/pumpkins fall
function letitfall() 
{	
	if ((n<snowmax || free>0) && (m % dens)==0 && m>60)
	{
		// be efficient (use IDs of flakes that have expired)
		nhold=-1;
		if (free>0)
		{
			nhold=n;
			n=vacant[free-1];
			free--;
		}
				
		// creates the flake
		var mommy = document.getElementById("parent");
		var newspan = document.createElement("span");
		var newid="s"+n;
		var newidINT=n;
		newspan.setAttribute("id",newid);
		newspan.onmouseover = function() {overitem(newidINT)};
		newspan.style.cssText="position: fixed;";
		newspan.innerHTML=flakes[randommaker(flakes.length)];
		mommy.appendChild(newspan);
		
		// initializes the flake	
		angle[n]=2*3.14*Math.random();   									// initial angle
		LRamp[n]=0.3+Math.random();   										// how much maximally left to right swing
		LRspeed[n]=0.03+Math.random()/25;									// speed of left to right (in radians per setTimeout)
		snow[n]=document.getElementById(newid);								// assign the id to snow[n]
		snow[n].size=randommaker((snowsize+1))+10;							// assign snow size (+10 is the minimal); used only for different speed
		snow[n].sink=sinkspeed*snow[n].size/5;								// determine snow falling speed; heavier for faster
		snow[n].posx=randommaker(widthorizontal);							// position X						
		snow[n].posy=-64;													// position Y	
		snow[n].style.left=snow[n].posx+"px";
		snow[n].style.top=snow[n].posy+"px";
		snow[n].VX=0;														// speed X
		snow[n].VY=0;														// speed Y
		
		// to introduce SPECIAL FLAKES
		if (angle[n]<1) newspan.innerHTML="<div style='color:#66a0ce; width:110px; border: 0px solid #ff0000; padding-left:0px; padding-right:0px; padding-top:32px; padding-bottom:32px;'><b>Happy <span style='color:#d5e8ff'>2012</span><span style='color:#a0a0a0'>!</span></b></div>";
		
		// be efficient (use IDs of flakes that have expired)
		if (nhold>0) n=nhold;
		else n++;
		
		document.getElementById("countflakes").innerHTML=n;
	}
	m++;	// to enable snow every "dens" number of milisec
	
	
	// *********************************** use for debugging
	// document.getElementById("shown").innerHTML="IE="+m+" "+X+"   n="+n+"free="+free+"dept="+depthofall+"mouse X="+tempX+" mouse Y="+tempY+"mouse speed X="+speedX+" mouse speed Y="+speedY;
	// *********************************** use for debugging
	
	// this updates the position of all flakes
	for (i=0;i<n;i++) 
	{
		angle[i]=angle[i]+LRspeed[i];										// the angle		
		snow[i].posx=snow[i].posx+LRamp[i]*Math.sin(angle[i])+snow[i].VX;	// position X
		snow[i].posy=snow[i].posy+snow[i].sink+snow[i].VY;					// position Y
		
		// speed X
		if (snow[i].VX>0) 
		{
			snow[i].VX=snow[i].VX-snow[i].VX*drag;
			if (snow[i].VX<0) snow[i].VX=0;
		}
		else if (snow[i].VX<0) 
		{
			snow[i].VX=snow[i].VX-snow[i].VX*drag;
			if (snow[i].VX>0) snow[i].VX=0;
		}
		
		// speed Y
		if (snow[i].VY>0) 
		{
			snow[i].VY=snow[i].VY-snow[i].VY*drag;
			if (snow[i].VY<0) snow[i].VY=0;
		}
		else if (snow[i].VY<0) 
		{
			snow[i].VY=snow[i].VY-snow[i].VY*drag;
			if (snow[i].VY>0) snow[i].VY=0;
		}
		
		snow[i].style.left=snow[i].posx+"px";
		snow[i].style.top=snow[i].posy+"px";
		
		// remove flakes once they go below depthofall
		if (snow[i].posy>=depthofall)
		{
			mothership=document.getElementById("parent");
			removeflake=document.getElementById("s"+i);
			if (removeflake!=null)
			{
				mothership.removeChild(removeflake);
				vacant[free]=i;
				free++;
			}
		}
		
		// periodic boundary
		if (snow[i].posx<-64)
		{
			snow[i].posx=widthorizontal-64;
			snow[i].style.left=snow[i].posx+"px";
		}
		
		if (snow[i].posx>widthorizontal-32)
		{
			snow[i].posx=-32;
			snow[i].style.left=snow[i].posx+"px";
		}
	}
	X=setTimeout("letitfall();",milisec);
}

function special(control)
{
	if (control=="no")
	{
		clearTimeout(X);
		
		for (i=0;i<n;i++) 
		{
			mothership=document.getElementById("parent");
			removeflake=document.getElementById("s"+i);
			if (removeflake!=null)
			{
				mothership.removeChild(removeflake);
			}
		}
		m=0;
		n=0;
		free=0;
		
		document.getElementById("controlfall").innerHTML="<a style='color:#a0a0a0; text-decoration:none;' href='javascript:special("+pom+"yes"+pom+");' title='Play with the flakes'>Let it <span style='color: #66a0ce; font-size: 110%;'>SNOW</span></a>";
		document.getElementById("controlfall").style.left="596px";
	}
	else 
	{
		document.getElementById("controlfall").innerHTML="<a style='color:#a0a0a0; text-decoration:none;' href='javascript:special("+pom+"no"+pom+");' title='Make them go away'>Remove <span id='countflakes' style='color: #ff0000;font-size: 110%;'>"+n+"</span> <span style='color: #66a0ce; font-size: 110%;'>FLAKES</span></a>";
		document.getElementById("controlfall").style.left="577px";
		X=setTimeout("letitfall();",milisec);
	}
}




