/// Frohe Weihnachten wuenscht buero digitale
/// René Teinze, r.teinze@buero-digitale.de
/// http://www.buero-digitale.de
/// LICENSE: free, but Email would be nice, if you use it
/// LIZENZ: frei, aber Email waere nett, wenn du es benutzt

/// Einbindung / Including in HTML:
/*
		<script type="text/javascript" src="BD_snow.js" ></script>
		<script type="text/javascript">
		BD_snow.config= {
			/// additional configuration options / zusaetzliche Konfiguration
			/// all active(not commented out) options have to be separated with commas
			/// alle aktive(nicht auskommentierte) Optionen muessen durch Komma voneinander getrennt sein
			/// following lines are optional / folgende Zeilen sind optional
			 graphic: 'snow3_16x16.gif' // Schneeflocke / snow-graphic
			,altsymbol: '*' // if no graphic is given / wenn keine Grafik gegeben
			,altsymbolcolor: '#dddddd' // font-color if no graphic is given / Textfarbe, wenn keine Grafik
			,altsymbolsize: 24 // font-size if no graphic is given / Textgroesse, wenn keine Grafik
			,amplitude: 20 // Ausschlag / left-right-moving
			,interval: 2 // Sekunden-Abstand der Flocken +/-? / time-distance of new snow
			,speed: 50 // Geschwindigkeit: grosse Zahl=langsam / speed: higher value=slower
			,snowontop: true // snow moves over the webcontent / Schnee bewegt sich ueber dem Webinhalt
			,partition: [5,3,3,5] // Partition on screen / Verteilung auf dem Bildschirm => [5,3,3,5]=more on borders | [10,10,6,3,3,3]=more left
		}
		</script>
*/

if(typeof(BD)=='undefined') {
	var BD= {};
}

BD.Math= new (function(){
	var $this= this;
	var $aSinDeg= [];
	var $fFaktor= 180/window.Math.PI;
	
	var __construct= function(){
		for($i1=0; $i1<360; $i1++){
			$aSinDeg.push(Math.sin($i1/$fFaktor));
		}
	}

	/// <summary>Generiert eine Zufallszahl innerhalb der optional angegebenen Grenzen.</summary>
	$this.random= function( $iMinEing, $iMaxEing ) {
		var $iMinEing, $iMaxEing;
		
		// Zufallszahl generieren
		var $fZuf= Math.random(); // z. B. 0.236483644
		if(BD.Math.random.arguments.length==0){
			return $fZuf;
		}
		else if(BD.Math.random.arguments.length==1){
			$iMaxEing= BD.Math.random.arguments[0];
			$iMinEing= 0;
		}
		else if(BD.Math.random.arguments.length==2){
			$iMinEing= BD.Math.random.arguments[0];
			$iMaxEing= BD.Math.random.arguments[1];
		}
		
		// in echte Zahlen umwandeln
		$iMinEing= Math.floor($iMinEing);
		$iMaxEing= Math.floor($iMaxEing);
		
		// 0 falls keine Zahl uebergeben wurde
		if(isNaN($iMinEing)) { $iMinEing=0; }
		if(isNaN($iMaxEing)) { $iMaxEing=0; }
		
		// echte Min.- und Max.-Werte ermitteln
		var $iMin= Math.min($iMinEing, $iMaxEing);
		var $iMax= Math.max($iMinEing, $iMaxEing);
		
		// Zahlenbereich anpassen
		var $iZuf= Math.floor( $fZuf * ($iMax-$iMin+1) + $iMin )
		
		// Zufallszahl zurueckgeben
		return $iZuf;
	}//BD.Math.random

	$this.sin= function( $iEing ) { // sinus
		if($iEing<0){
			return -$aSinDeg[Math.floor($iEing * $fFaktor) % 360];
		}
		else{
			return $aSinDeg[Math.floor($iEing * $fFaktor) % 360];
		}
	}
	
	__construct();
	
	return $this;
})();//BD.Math


BD_snow= new (function(){
	var $this= this;
	$this.version= '1.0.4';
	var $iCountFlocken= 0;
	var $iCountOverflow= 0;
	var $iStartposCorr= 0;
	var $iBaseStep= 0.7; // base stepwidth
	
	// Basic-configuration, will be overidden by include-script, so don't change here
	// Grundkonfiguration, wird ueberschrieben durch das include-script, also nicht hier aendern
	$this.oConf= {
		 graphic: false
		,altsymbol: '*'
		,altsymbolcolor: '#dddddd'
		,altsymbolsize: 24
		,amplitude: 20
		,interval: 3
		,speed: 50
		,snowontop: true
		,partition: [5,1,1,5]
		,maxflakes: false
	}

	var __construct= function(){
		if(!docloaded()){
			setTimeout(__construct, 2000);
			return false;
		}
		for(var $s1 in $this.config){
			$this.oConf[$s1]= $this.config[$s1];
		}
		
		if($this.oConf.graphic){
			var $oIm= new Image();
			$oIm.onerror= function(){$this.oConf.graphic=false;}
			$oIm.src= $this.oConf.graphic;
		}
		if($this.oConf.graphic){
			$this.iImgW= (($oIm.width>0)?($oIm.width):($this.oConf.altsymbolsize));
			$this.iImgH= (($oIm.height>0)?($oIm.height):($this.oConf.altsymbolsize));
		}
		else{
			$this.iImgW= $this.oConf.altsymbolsize;
			$this.iImgH= $this.oConf.altsymbolsize;
		}
	
		$this.iDocW = $this.env.w;
		$this.iDocH = $this.env.h;
		var $oE_Body= document.getElementsByTagName('body')[0];

		$this.oE_frame= document.createElement('div');
		$this.oE_frame.style.position= 'fixed';
		$this.oE_frame.style.width= $this.iDocW()+'px';
		$this.oE_frame.style.height= $this.iDocH()+'px';
		$this.oE_frame.style.left= '0px';
		$this.oE_frame.style.top= '0px';
		$this.oE_frame.style.overflow= 'hidden';
		$this.oE_frame.style.background= 'transparent';
		$this.oE_frame.style.zIndex= (($this.oConf.snowontop)?(1000):(-1));
		if($this.oConf.snowontop){
			$this.oE_frame= $oE_Body;
		}
		else{
			$oE_Body.insertBefore($this.oE_frame, $oE_Body.firstChild);
		}
				
		if(!$this.oConf.maxflakes){
			$this.oConf.maxflakes= Math.floor( $this.iDocH() / ($iBaseStep*($this.oConf.interval*1000/$this.oConf.speed)) ) + 2;
		}
				
		createFlocke();
	}

	$this.env= new (function($parent){
		var $this= this;
		$this.w= function(){
			return window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
		}
		$this.h= function(){
			return window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
		}
		$this.top= function(){
			return $parent.oE_frame.pageYOffset || $parent.oE_frame.scrollTop || 0;
			//  scrollHeight und ggf. offsetHeight
		}
		return $this;
	})($this);
	
	var docloaded= function(){
		if(
			document.getElementsByTagName('body')[0]
			&&
			(window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth))
			&&
			(window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight))
		){
			return true;
		}
		return false;
	}//docloaded
	
	var Flocke= function($parent){
		var $this= this;
		var $iDx, $iPosX, $iPosY;    // coordinate and position variables
		var $iAmp, $iStepX, $iStepY;  // amplitude and step variables
		var $oE_Flocke;
		var $oInterval;
		var $iOpacity;
		var $iFadeHeight; // height of fading area.
		var $iPosYToCallNext;
		
		var __construct= function(){
			$iCountFlocken++;
			$iDx = 0; 
			$iAmp = Math.random()*$parent.oConf.amplitude;
			$iPosX = getPosX();
			$iPosY = -30 - $parent.iImgH;
			$iStepX = 0.02 + Math.random()/10;
			$iStepY = $iBaseStep + Math.random();
			$iOpacity= 100;
			$iFadeHeight= $iStepY*100/5+$parent.iImgH;
			$iPosYToCallNext= $iPosY + Math.floor($iStepY*($parent.oConf.interval*1000/$parent.oConf.speed)) + Math.floor($iStartposCorr);
			if(!$iPosYToCallNext) { $iPosYToCallNext=100; }
			
			$oE_Flocke= document.createElement('div');
			$oE_Flocke.style.position= 'absolute';
			$oE_Flocke.style.top= $iPosY+'px';
			$oE_Flocke.style.left= $iPosX+'px';
			if($parent.oConf.graphic){
				$oE_Flocke.style.width= $parent.iImgW+'px';
				$oE_Flocke.style.height= $parent.iImgW+'px';
				$oE_Flocke.style.backgroundRepeat= 'no-repeat';
				$oE_Flocke.style.backgroundImage= 'url('+$parent.oConf.graphic+')';
			}
			else{
				$oE_Flocke.appendChild(document.createTextNode($parent.oConf.altsymbol));
				$oE_Flocke.style.color= $parent.oConf.altsymbolcolor;
				$oE_Flocke.style.fontSize= $parent.oConf.altsymbolsize+'px';
			}
			$parent.oE_frame.appendChild($oE_Flocke);
			
			$oInterval= setInterval(letItSnow, $parent.oConf.speed);
		}
		
		var getPosX= function(){
			var $i1, $iMax=0, $fMax=0, $fMaxTemp;
			for($i1=0; $i1<$parent.oConf.partition.length; $i1++){
				$fMaxTemp= $parent.oConf.partition[$i1] * Math.random();
				if($fMaxTemp>$fMax){
					$fMax= $fMaxTemp;
					$iMax= $i1;
				}
			}
			
			var $iPuffer= $parent.iImgW + $iAmp;
			var $iAvailW= $parent.iDocW() - 2*$iPuffer;
			var $iPartW= $iAvailW / $parent.oConf.partition.length;
			var $iPos= Math.floor( $iPuffer/2 + $iMax * $iPartW  +  Math.random() * $iPartW );

			return $iPos;
		}
		
		var hide= function(){
			var $fOpac100= $iOpacity/100;
			$oE_Flocke.style.filter = 'Alpha(opacity=' + ($iOpacity) + ')'; // IE only
			$oE_Flocke.style.MozOpacity = $fOpac100; // Mozilla only
			$oE_Flocke.style.opacity = $fOpac100; // Chrome, Mozilla

			return ($iOpacity-=5);
		}
		
		var letItSnow= function(){
			$iPosY += $iStepY;
			if ($iPosY > ($parent.oE_frame.scrollHeight-$iFadeHeight)) { // IE, Chrome
			//if ($iPosY > ($parent.env.top()+$parent.env.h()-($iStepY*100/2+$parent.iImgH))) { // Chrome
				if(hide()<=0){
					clearInterval($oInterval);
					$parent.oE_frame.removeChild($oE_Flocke);
					$iCountFlocken--;
				}
			}
			$iDx += $iStepX;
			$oE_Flocke.style.left = $iPosX + $iAmp*BD.Math.sin($iDx)  + "px";
			$oE_Flocke.style.top = $iPosY + "px";
			
			if($iPosYToCallNext && $iPosY>$iPosYToCallNext){ // start next
				createFlocke();
				$iPosYToCallNext= false;
			}
			// document.getElementById('BD_snow-output').innerHTML= $iCountFlocken + ' of ' + $parent.oConf.maxflakes + ' (Count:' + $iCountOverflow + ', Corr:'+$iStartposCorr+')';
		}
						
		__construct();
	}// Flocke

	var createFlocke= function(){
		// time to next Flocke
		//var $iSpan= $this.oConf.interval/3;
		//var $iRand= Math.random()*($iSpan);
		//$iRand= Math.floor($this.oConf.interval + ($iSpan/2-$iRand))*1000;
		//setTimeout(createFlocke, $iRand);
		
		var $iTime;
		if($iCountFlocken<$this.oConf.maxflakes){
			new Flocke($this);
			$iStartposCorr-=1;
		}
		else{
			setTimeout(createFlocke, 1000);
			$iStartposCorr+=3;
			$iCountOverflow++;
		}
	}
	
	__construct();
	
	return $this;
}// Schnee
)();

