// JavaScript Document
//snow flake

(function($){
	$.fn.snowflakes = function(options){
		
		var element = this;
		
		// random fuction for generating random vals
		random = function random(min, max){
			return Math.round(min + Math.random()*(max-min)); 
		}
		
		// snow flake class
		function Flake(_x, _y, _size, _speed)
		{
			// Flake properties
			this.id = flakeId; 
			this.x  = _x;
			this.y  = _y;
			this.size = _size;
			this.speed = _speed;
			this.step = 0;
			this.stepSize = random(1,10) / 100;
			this.resetting = false;
			this.repeat = options.iterations;
			this.counter = 0;
			
			var flakeMarkup = "<div id='flake-" + this.id + "' style='width: " + this.size + "px; height: " + this.size + "px; position: absolute; top: " + this.y + "px; left:" + this.x + "px; font-size: 0px; z-index: " + options.flakeIndex + ";pointer-events:none;-webkit-transform-style:preserve-3d;'><img src=\"snowflakes/sf_" + this.id + ".png\" alt='snowflake' style='width:100%;'/></div>";
			
			if($(element).get(0).tagName === $(document).get(0).tagName){
				$('body').append(flakeMarkup);
				//Make snowfall area 20% body width
			}else{
				$(element).append(flakeMarkup);
			}
			
			this.element = document.getElementById('flake-' + this.id);
			// Update function, used to update the snow flakes, and checks current snowflake against bounds
			this.update = function(){
				//Check if snowflake is still fading and how many descents it has made
				if (this.resetting && this.counter < this.repeat) {
					if (this.element.style.opacity == 0) {
						this.reset();
					}
					return;
				};
				
				//Display none for elements that have completed all iterations.
				if (this.counter == this.repeat) {
					this.element.style.display = 'none';
				};
				
				this.y += this.speed;
				
				if(this.y > (elHeight) - this.size){
					//Keep track of snowflake descent iteration
					this.counter++;
					//Prevent a snowflake from being updated until it is fully faded out.
					this.resetting = true;
					//Fade out the snowflake
					if ( $.browser.msie ) {
						this.element.style.opacity= 0;
				 	} else {
				    	$('#flake-'+ this.id).fadeOut(500);
				 	}
				}
				
				this.element.style.top = this.y + 'px';
				this.element.style.left = this.x + 'px';
				
				this.step += this.stepSize;
				this.x += Math.cos(this.step);
				//CSS3 Progressive enhancement for rotation
				$('#flake-'+ this.id).css("-moz-transform" , "rotate("+this.x+"deg)");
				$('#flake-'+ this.id).css("-webkit-transform" , "rotate("+this.x+"deg)");
				$('#flake-'+ this.id).css("-ms-transform" , "rotate("+this.x+"deg)");
				$('#flake-'+ this.id).css("-o-transform" , "rotate("+this.x+"deg)");
				$('#flake-'+ this.id).css("transform" , "rotate("+this.x+"deg)");
			}
			
			// Resets the snowflake once it reaches one of the bounds set
			this.reset = function(){
				if ( $.browser.msie ) {
					this.element.style.opacity = 1;
			 	} else {
			    	$('#flake-'+ this.id).fadeIn(500);
			 	}
				this.y = -options.maxSize;
				this.x = random(0, elWidth);
				this.stepSize = random(1,10) / 100;
				this.size = random((options.minSize * 100), (options.maxSize * 100)) / 100;
				this.speed = random(options.minSpeed, options.maxSpeed);
				this.resetting = false;
			}
		}
	
		//Make width 20% and height 90% if body tag is selected. Fixes Rockport specific z-index issues in IE.
		if ($(element).get(0).tagName == 'BODY') {
			elHeight = $(element).height() * .9;
			elWidth = $(element).width() * .2;
		} else {
			elHieght = $(element).height();
			elWidth = $(element).width();
		}
		// plugin vars
		var flakes = [],
			flakeId = 0,
			i = 0,
			elHeight = elHeight,
			elWidth = elWidth,
			defaults = {
				flakeCount : 35,
				flakeIndex: 999999,
				minSize : 1,
				maxSize : 3,
				minSpeed : 2,
				maxSpeed : 3,
				iterations : 3
				},
			options = $.extend(defaults, options);		
		
		// Bind the window resize event so we can get the innerHeight again
		$(window).bind("resize", function(){  
			if ($(element).get(0).tagName == 'BODY') {
				elHeight = $(element).height() * .9;
				elWidth = $(element).width() * .2;
			} else {
				elHieght = $(element).height();
				elWidth = $(element).width();
			}
		}); 
		

		// initialize the flakes
		for(i = 0; i < options.flakeCount; i++){
			flakeId = i;
			flakes[i] = new Flake(random(0,elWidth), random(0, -500), random((options.minSize * 100), (options.maxSize * 100)) / 100, random(options.minSpeed, options.maxSpeed));
		}
	
		// this controls flow of the updating snow
		function snow(){
			for( i = 0; i < options.flakeCount; i++){
				flakes[i].update();
			}
		}
		setInterval(function(){snow()}, 30);
		
	};
})(jQuery);
