//calls initial function on resize - needs some special handling code because good ol' ie handles
//the resize event differently to all other browsers - as usual. Works by setting a timeout on resize event
//then cancelling it if another is called within 10 millisec

var resizeTimeoutId;

function window_resize(e) {
     window.clearTimeout(resizeTimeoutId);
     resizeTimeoutId = window.setTimeout('doEffects("#ab1212");', 10);
}

window.onresize = window_resize;


//Initial call function. call this from the page body onload or resize event. Builds a containing div in the background if it doesn't already exist
//or empties it if it does, then fills with effects. This is important to stop multiple instances or memory leaks on page resizing

function doEffects(color){
	//check if host div exists and build if it doesn't.
	var host = document.getElementById('host');
	var windowSize = getWindowSize();
	if(!host){
		host = document.createElement('div');
		host.setAttribute('id','host');
		host.style.width = windowSize[0]-20;
		host.style.height = windowSize[1]-20;
		host.style.position = 'absolute';
		host.style.top = '0px';
		host.style.zIndex = '-1000'; //or something equally as large, just to make sure it's at the very back (haha equally as large)
		document.body.appendChild(host);
	}
	else{
		host.style.width = windowSize[0]-20;
		host.style.height = windowSize[1]-20;
		host.innerHTML = ''; //empty host div if already exists
	}
	
	//create effects
	floatSquares();
//	scrollText(color);
//	staticText(color);
	rainSquares(color);
}


//floatSquares. Moves 3 divs left and right across center of screen to emulate 3 layer perspective/parallax scrolling
//Configure the appearance in the top section of the function. Uncomment lines marked 'for dev only' to help positioning

function floatSquares(){
	
	//---configuration vars - Edit from here to change initial appearance and behaviour---//
	var time = 50; //initial speed	
	var minSpeed = 40; //max and min travel speed - lower number = faster moving
	var maxSpeed = 90;
	//---//
	var animateOpacity = true; //change to false if you don't want the flickering effect
	var opacity = 100; //initial opacity
	var minOpacity = 40; //max and min opacity amounts 100 = opaque
	var maxOpacity = 100;
	var opacityTime = 80; //inital opacity animation speed
	var minOpacitySpeed = 80; //min and max speed at which opacity animates
	var maxOpacitySpeed = 250; //set to minSpeed and maxSpeed to sync with travel speed
	//---//
	var largeImg = 'url(images/bgLines.png) repeat-x'; //optional images for div backgrounds. transparent png's work best. Standard CSS syntax
	var medImg = largeImg; //change these to different image paths, else all use the same image
	var smallImg = largeImg;
	var zIndex = '-100'; //z index value, negative numbers move effect further back - standard CSS behaviour
	//---end of configuration vars. No need to edit anything else in this function unless uncommenting background colours for positioning---//

	//calc position data
	var windowSize = getWindowSize();
	var divWidth = (windowSize[0]-50);
	var divHeight = Math.ceil(windowSize[1]/5);
	var leftPos = Math.ceil((windowSize[0]/2)-(divWidth/2));
	var topPos = Math.ceil((windowSize[1]/2)-(divHeight/2));

	//create basic divs and append to host div
	var outerDiv = document.createElement('div');
	outerDiv.style.width = divWidth+'px';
	outerDiv.style.height = divHeight+'px';
		
	outerDiv.style.position = 'absolute';
	outerDiv.style.left = leftPos+'px';
	outerDiv.style.top = topPos+'px';
	outerDiv.style.zIndex = zIndex;
//	outerDiv.style.backgroundColor = 'red'; //for dev only - use for positioning
	
	var div01 = document.createElement('div');
	div01.style.width = Math.ceil(divWidth/2)+'px';
	div01.style.height = divHeight+'px';
	div01.style.marginLeft = '0px';
	div01.style.background = largeImg;
//	div01.style.backgroundColor = 'green'; // for dev only - use for positioning
	
	var div02 = document.createElement('div');
	div02.style.width = Math.ceil((parseInt(div01.style.width)/3)*2)+'px'; //66% parent div width
	div02.style.height = Math.ceil((parseInt(div01.style.height)/3)*2)+'px'; //66% parent div height
	div02.style.marginLeft = (parseInt(div01.style.width) - parseInt(div02.style.width))+'px'; //difference between div width and parent div width
	div02.style.position = 'relative';
	div02.style.top = Math.ceil((parseInt(div01.style.height) - parseInt(div02.style.height))/2)+'px'; //difference in height divided by 2
	div02.style.background = medImg;
//	div02.style.backgroundColor = 'blue'; // for dev only - use for positioning
	
	var div03 = document.createElement('div');
	div03.style.width = Math.ceil((parseInt(div02.style.width)/3)*2)+'px'; //66% parent div width
	div03.style.height = Math.ceil((parseInt(div02.style.height)/3)*2)+'px'; //66% parent div height
	div03.style.marginLeft = (parseInt(div02.style.width) - parseInt(div03.style.width))+'px'; //difference between div width and parent div width
	div03.style.position = 'relative';
	div03.style.top = Math.ceil((parseInt(div02.style.height) - parseInt(div03.style.height))/2)+'px'; //difference in height divided by 2
	div03.style.background = smallImg;
//	div03.style.backgroundColor = 'yellow'; //for dev only - use for positioning
	
	div02.appendChild(div03);
	div01.appendChild(div02);
	outerDiv.appendChild(div01);
	document.getElementById('host').appendChild(outerDiv);

	
	//start animation
	moveRight();
	if(animateOpacity) animOpacity();
	
	//animate div movement
	function moveRight(){
		div01.style.marginLeft = (parseInt(div01.style.marginLeft)+9)+'px';
		div02.style.marginLeft = (parseInt(div02.style.marginLeft)-3)+'px';
		div03.style.marginLeft = (parseInt(div03.style.marginLeft)-2)+'px';
		if(parseInt(outerDiv.style.width)-(parseInt(div01.style.marginLeft)+parseInt(div01.style.width)) < 60) time += 10; //slow down for the last 60 pixels
		if(parseInt(div01.style.marginLeft) < parseInt(div01.style.width)) setTimeout(moveRight,time);
		else{
			time = randValue(minSpeed,maxSpeed);
			opacityTime = randValue(minOpacitySpeed,maxOpacitySpeed);
			moveLeft();
		}
	}
	
	function moveLeft(){
		div01.style.marginLeft = (parseInt(div01.style.marginLeft)-9)+'px';
		div02.style.marginLeft = (parseInt(div02.style.marginLeft)+3)+'px';
		div03.style.marginLeft = (parseInt(div03.style.marginLeft)+2)+'px';
		if(parseInt(div01.style.marginLeft) < 60) time+= 10; //slow down for 60 pixels
		if(parseInt(div01.style.marginLeft) > 0) setTimeout(moveLeft,time);
		else{
			time = randValue(minSpeed,maxSpeed);
			opacityTime = randValue(minOpacitySpeed,maxOpacitySpeed);
			moveRight();
		}	
	}
	
	//animate div opacity
	function animOpacity(){
		div01.style.opacity = opacity/100;
		div01.style.filter = 'alpha(opacity='+opacity+')';
		opacity = randValue(minOpacity,maxOpacity);
		setTimeout(animOpacity,opacityTime);
	}
}

//scrollText. String scroller - scrolls 2 text strings in opposite directions. Has nice fade in/out effect.
//If no string is passed a random animated string is created. If passing a color use CSS format string '#FFFFFF'.
//If no colour is passed then default is black. Any font style is inherited from parent div or body style. Colour can also be inherited.
//If passing a string but no colour then use '' (empty string) in place of colour eg scrollText('','Some String');
//TODO: optimise generation of 2 divs to save code repetition - auto resize on window resize

function scrollText(color,textString){
	
	//---configuration vars - extreme values can make things permanently disappear, so be careful :)---//
	var minSpeed = 40; //min travel speed in millisec - remember lower numbers == faster movement
	var maxSpeed = 100; //max travel speed
	var randStringLength = 100; //random char string length in characters if no string passed
	var speedA = 150; //initial speed
	var speedB = 150;
	var textOpacity = 0.4; //opacity of string. Float from 0-1
	var fontFallback = '14px'; //default font size if no CSS style is applied or inherited
	var zIndex ='-100'; //z index value, lower == further back. Standard CSS syntax
	//---No need to edit this function further---//
	
	//set up some default values if no params are passed
	if(textString == '' || textString == null){
		var useRandom = true;
		textString = randString(randStringLength);
	}
	color = (color == null || color == '') ? 'black' : color;

	//calc size and position data
	var windowSize = getWindowSize();
	var divWidth = windowSize[0]-50;
	var topPosA = Math.floor(windowSize[1]/3); //floor or ceil will do - just needs to be a whole number for position
	var topPosB = topPosA*2; //we'll have 2 divs, 1/3 and 2/3 down the screen scrolling in opposite directions
	var leftPos = Math.floor(windowSize[0]/2)-(divWidth/2); //horizontally centered based on window size when div is created
	
	//create divs and append to host div
	var outerDivA = document.createElement('div');
	var outerDivB = document.createElement('div');
	
	outerDivA.style.width = divWidth;
	outerDivA.style.position = 'absolute';
	outerDivA.style.top = topPosA+'px';
	outerDivA.style.left = leftPos+'px';
	outerDivA.style.zIndex = '-100';
	//specify font size here for innerDiv width calcs if not already specified by stylesheet
	outerDivA.style.fontSize = (outerDivA.style.fontSize == '') ? fontFallback : outerDivA.style.fontSize;
	outerDivA.style.color = color;
	
	outerDivB.style.width = divWidth;
	outerDivB.style.position = 'absolute';
	outerDivB.style.top = topPosB+'px';
	outerDivB.style.left = leftPos+'px';
	outerDivB.style.zIndex = zIndex;
	outerDivB.style.fontSize = (outerDivB.style.fontSize == '') ? fontFallback : outerDivB.style.fontSize;
	outerDivB.style.color = color;
	
	var innerDivA = document.createElement('div');
	var innerDivB = document.createElement('div')
	//width is fontSize multiplied by number chars in string
	var innerDivWidth = (parseInt(outerDivA.style.fontSize)*textString.length)/2;
	
	innerDivA.setAttribute('id','divA');//we need to include id, display and opacity values for fade functions to work
	innerDivA.style.display = 'none';
	innerDivA.style.opacity = '0';
	innerDivA.style.filter = 'alpha(opacity=0)'; //ie uses different opacity settings
	innerDivA.style.width = innerDivWidth+'px';
	innerDivA.innerHTML = textString;
	innerDivA.marginLeft = '0px';
	
	innerDivB.setAttribute('id','divB');
	innerDivB.style.display = 'none';
	innerDivB.style.opacity = '0';
	innerDivB.style.filter = 'alpha(opacity=0)';
	innerDivB.style.width = innerDivWidth+'px';
	innerDivB.innerHTML = textString;
	
	//we hold it in a var so we can return to this value later
	var maxMargin = divWidth - innerDivWidth;
										
	innerDivB.style.marginLeft = maxMargin+'px';
	
	outerDivA.appendChild(innerDivA);
	outerDivB.appendChild(innerDivB);
	document.getElementById('host').appendChild(outerDivA);
	document.getElementById('host').appendChild(outerDivB);
	
	//animate divs	
	function moveRight(){
		if(parseInt(innerDivA.style.marginLeft) < maxMargin){
			innerDivA.style.marginLeft = (parseInt(innerDivA.style.marginLeft)+1)+'px';
			if(parseInt(innerDivA.style.marginLeft) == (maxMargin-50)) hide('divA');
			if(useRandom) innerDivA.innerHTML = randString(randStringLength);
			setTimeout(moveRight,speedA);
		}
		else{
			innerDivA.style.marginLeft = '0px';
			show('divA',textOpacity);
			speedA = randValue(minSpeed,maxSpeed);
			setTimeout(moveRight,speedA);
		}
		
	}
	
	function moveLeft(){
		if(parseInt(innerDivB.style.marginLeft) > 0){
			innerDivB.style.marginLeft = (parseInt(innerDivB.style.marginLeft)-1)+'px';
			if(parseInt(innerDivB.style.marginLeft) == 50) hide('divB');
			if(useRandom) innerDivB.innerHTML = randString(randStringLength);
			setTimeout(moveLeft,speedB);
		}
		else{
			innerDivB.style.marginLeft = maxMargin+'px';
			show('divB',textOpacity);
			speedB = randValue(minSpeed,maxSpeed);
			setTimeout(moveLeft,speedB);
		}
	
	}
	
	//and Go!
	moveRight();
	moveLeft();
	show('divA',textOpacity);
	show('divB',textOpacity);
}

//staticText. Creates a still div across center of the screen and animates with random characters Matrix stylee
//Takes a colour in CSS form '#FFFFFF', defaults to black if no colour is passed, or inherits colour from document.
//Automatically fits screen with on call. 

function staticText(color){
	
	//---Configuration vars - use these to edit appearance---//
	var zIndex = '-99'; //z index depth. Usual CSS syntax
	var opacity = '0.5'; //opacity amount, float 0-1, 1 is opaque
	var fontFallback = '18px'; //font size to use if not specified in document CSS
	var animSpeed = 100; //rate at which text animates in millisec. Larger == slower.
	//---No need to edit function beyodnd here---//
	
	color = (color == null) ? 'black' : color; //set default color if none is passed
	
	//calc position data
	var windowSize = getWindowSize();
	var divWidth = windowSize[0]-50;
	var topPos = Math.floor(windowSize[1]/2);
	var leftPos = Math.floor(windowSize[0]/2)-(divWidth/2);
	
	//create div and append to host div
	var staticDiv = document.createElement('div');
	staticDiv.style.width = divWidth+'px';
	staticDiv.style.color = color;
	//sets font size only if not set by stylesheet
	staticDiv.style.fontSize = (staticDiv.style.fontSize == '') ? fontFallback : staticDiv.style.fontSize;
	staticDiv.style.position = 'absolute';
	staticDiv.style.top = topPos+'px';
	staticDiv.style.left = leftPos+'px';
	staticDiv.style.zIndex = zIndex;
	staticDiv.style.opacity = opacity;
	staticDiv.style.filter = 'alpha(opacity='+opacity*100+')';
	
	document.getElementById('host').appendChild(staticDiv);
	
	//calc string length based on font size and divWidth
	var stringLength = Math.floor((divWidth/parseInt(staticDiv.style.fontSize)*2));
	
	//fill div with chars and animate
	function animDiv(){
		staticDiv.innerHTML = randString(stringLength);
		setTimeout(animDiv,animSpeed);
	}
	
	animDiv();
}

//rainSquares. Creates square divs which 'rain' down in the background. Pass CSS colour as
//an option '#FFFFFF', else defaults to black. Borders can be switched off and background
//colour or images added - eg snowflakes or something equally as twee. Transparent png works best.
//Theoretically possible to make circles and ovoids using CSS radius property
//Possible TODO: add checkdate function to make snowflakes in december, pumpkins in october etc etc

function rainSquares(color){
	color = (color == null) ? 'black' : color; //set default color if none is passed

	//---Edit these vars to set appearance---//
	var squareSize = 75;//square size in px if using fixed size
	var randomSize = false; //set to true to use random sizes - works better with large maxCount
	var minSize = 6; //min square size in px if randomSize = true
	var maxSize = 12; //max square size in px if randomSize = true
	var maxCount = 10; //max squares on screen
	var minSpawnFreq = 1000; //min and max time between spawning in millisec
	var maxSpawnFreq = 2500; //set these a few seconds apart
	var padding = 20; //space in px between squares
	var opacity = 0.4; //opacity - float between 0 and 1
	var minSpeed = 10; //minimum speed in milliseconds
	var maxSpeed = 80; //remember larger is longer, therefore SLOWER
	var borderWidth = '1px'; //border thickness in pixels
	var borderStyle = 'solid'; //can be solid, dashed, dotted or none
	var backgroundImage = ''; //if used should be in CSS format 'url(../images/an_image.png)'
	var backgroundColor = ''; //optional background colour. Overrides background image
	var zIndex = '-150'; //CSS z index
	var CSSclassName = 'none'; //optional CSS style applied to main div, inheritable by squares (try putting rads in this way)
	//---End of editable vars---//
	
	//calc some dims
	var windowSize = getWindowSize();
	var divWidth = windowSize[0]-50;
	var divHeight = windowSize[1]-20;
	var topPos = Math.floor(windowSize[1]/2)-Math.floor(divHeight/2);
	var leftPos = Math.floor(windowSize[0]/2)-Math.floor(divWidth/2);
	
	var month = new Date();
	month = month.getMonth();
	if(month == 11){
		squareSize = 34;
		borderStyle = 'none';
		backgroundImage = 'url(images/flake.png) no-repeat';
		maxCount = 50;
	}
	
	//build main div and append to host div
	var mainDiv = document.createElement('div');
	mainDiv.style.width = divWidth+'px';
	mainDiv.style.height = divHeight+'px';
	mainDiv.style.position = 'absolute';
	mainDiv.style.top = topPos+'px';
	mainDiv.style.left = leftPos+'px';
	mainDiv.style.zIndex = zIndex;
	mainDiv.className = CSSclassName;
	
	document.getElementById('host').appendChild(mainDiv);
	
	//we shall call this every time we want a new square
	function createSquare(){
	
		//birth square at top and random horizontal pos
		var squareDiv = document.createElement('div');
		squareDiv.style.width = squareSize+'px';
		squareDiv.style.height = squareSize+'px';
		squareDiv.style.opacity = opacity;
		squareDiv.style.filter = 'alpha(opacity='+opacity*100+')';
		squareDiv.style.border = borderWidth;
		squareDiv.style.borderColor = color;
		squareDiv.style.borderStyle = borderStyle;
		squareDiv.style.marginTop = '-'+squareSize+'px'; //negative square size spawns off screen.
		squareDiv.style.marginLeft = setMargin();
		squareDiv.style.position = 'absolute'; //squares spawn under each other as divs will according to HTML standards if not set
		squareDiv.style.background = backgroundImage;
		squareDiv.style.backgroundColor = backgroundColor;
		mainDiv.appendChild(squareDiv);
		
		maxCount--; //reduce available squares by 1 each time a new one is created
		
		var speed = randValue(minSpeed,maxSpeed);
		//animate square
		var squareHeight = (!randomSize) ? squareSize : maxSize;
		function rain(){
			if(parseInt(squareDiv.style.marginTop) < (divHeight-squareHeight)){
				squareDiv.style.marginTop = (parseInt(squareDiv.style.marginTop)+1)+'px';
				setTimeout(rain,speed);
			}
			else{
				squareDiv.style.borderBottom = '0px';
				splash();
			}
		}
		
		//splash - shrink to nothing when hitting bottom
		function splash(){
			if(parseInt(squareDiv.style.height) > 0){
				squareDiv.style.marginTop = (parseInt(squareDiv.style.marginTop)+1)+'px';
				squareDiv.style.height = (parseInt(squareDiv.style.height)-1)+'px';
				setTimeout(splash,speed);
			}
			else{
				mainDiv.removeChild(squareDiv);
				maxCount++; //increase available squares on destruction
			}		
		}
		
		//and GO!
		rain();		
	}
	
	var posInUse = new Array(); //empty array to hold position indexes being used
	
	//this generates a random left margin value in px to offset raining squares
	function setMargin(){
		//divide available screenspace by square width to get max number of squares without overlapping
		var maxSquares = (!randomSize) ? Math.floor(divWidth/(squareSize+padding)) : Math.floor(divWidth/(maxSize+padding));
		
		//create an array to contain all possible positions
		var posArray = new Array();
		var posVal = 0;
		//load position values into array
		for(i=0;i<maxSquares;i++){
			posArray[i] = posVal;
			posVal += (squareSize+padding);
		}
	
		var pos = randValue(0,posArray.length-1);
		//check index is not in use and return next available index if it is
		if(posInUse[pos]){
			do{
				pos++;
				if(pos == posArray.length){ //all indexes are taken
					for(i=0;i<posInUse.length;i++) posInUse[i] = false; //loop through and set all to false again
					pos = 0; //reset index
					break; //escape loop and start all over
				}
				
			}
			while(posInUse[pos])
			posInUse[pos] = true;
			return posArray[pos]+'px';
		}
		else{
			posInUse[pos] = true;
			return posArray[pos]+'px';
		}
	}
	
	//function to actually spawn squares at random times
	function spawnSquare(){
		if(maxCount > 0){
			if(randomSize) squareSize = randValue(minSize,maxSize);
			var time = randValue(minSpawnFreq,maxSpawnFreq);
			createSquare();
		}
		setTimeout(spawnSquare,time);
	}
	
	//finally set the whole thing going
	spawnSquare();
}



