/*
	Fireworks
	ClickPublish (TM)
	www.clickinnovate.com
*/

function FireworksController() { var self = this; this.intervalRate = 20; this.DEBUG = false; this.oFW = null; this.isIE = (navigator.appVersion.indexOf('MSIE')+1); this.isOpera = (navigator.userAgent.toLowerCase().indexOf('opera')+1); if (this.isOpera) this.isIE = false; this.fireworks = []; this.animator = null; this.gOID = 0; this.particleTypes = 6; this.particleXY = 10; this.tweenFade = [100,90,80,70,60,50,40,30,20,10,0]; this.isSafari = (navigator.appVersion.toLowerCase().indexOf('safari')+1?1:0); this.canvasX = null; this.canvasY = null; this.screenY = null; self.scrollY = null; self.getWindowCoords = function() { self.canvasX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth); self.canvasY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight); self.screenY = self.canvasY; self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop); self.canvasY += self.scrollY;}
this.getWindowCoordsAlt = function() { self.canvasX = window.innerWidth; self.canvasY = window.innerHeight; self.screenY = self.canvasY; self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop); self.canvasY += self.scrollY;}
this.getPanX = function(x) { x = parseInt(x); var pos = x/self.canvasX; if (pos<0.4) { pos *= -1;} else if (pos >= 0.4 && pos <= 0.6) { pos = 0.5;}
pos = parseInt(pos*100); return pos;}
this.isEmpty = function(o) { return (typeof(o)=='undefined'||(o==null&&o!=0)||(o==''&&o!=0)||o=='null');}
this.init = function() { self.oFW = document.getElementById('fw'); self.oFP = document.getElementById('fp'); if (typeof(enableDebugMode)!='undefined' && (self.DEBUG||window.location.toString().toLowerCase().indexOf('debug')>=0)) enableDebugMode(); self.getWindowCoords(); self.animator = new Animator();}
this.destructor = function() { for (var i=self.fireworks.length; i--;) { self.fireworks[i] = null;}
self.fireworks = null; if (soundManager) { soundManager.destructor(); soundManager = null;}
}
if (this.isSafari || this.isOpera) this.getWindowCoords = this.getWindowCoordsAlt;}
function Firework(oC,startX,startY,burstX,burstY,burstType,nRadius,nParticles,nCircles,allowRandom,obeyBoundaries) { var self = this; this.oID = 'fp'+(fc.gOID++); var p = ''; for (var i=0; i<arguments.length-1; i++) { p += arguments[i]+',';}
p += arguments[i]; writeDebug('firework('+p+')'); this.oC = oC; this.o = fc.oFW.cloneNode(!fc.isIE?true:false); this.particles = []; this.vX = -1; this.vY = -4; this.x = startX; this.y = startY; this.allowRandom = allowRandom; this.obeyBoundaries = obeyBoundaries; this.frame = 0; this.tween = []; this.active = false; this.moveTo = function(x,y) { self.o.style.left = x+'px'; self.o.style.top = y+'px'; self.x = x; self.y = y;}
this.slideTo = function(x,y) { self.tween = [fc.animator.createTween(self.x,x,'blast'),fc.animator.createTween(self.y,y,'blast')]; fc.animator.enqueue(self,self.animate,self.aniExplode);}
self.aniExplode = function() { self.o.style.background = 'none'; self.o.style.border = 'none'; for (var i=self.particles.length; --i;) { self.particles[i].o.style.display = 'block'; fc.animator.enqueue(self.particles[i],self.particles[i].animate);}
self.particles[i].o.style.display = 'block'; fc.animator.enqueue(self.particles[i],self.particles[i].animate,self.beginFade); var sID = 'boom'+parseInt(Math.random()*8); soundManager.setPan(sID,fc.getPanX(self.x)); soundManager.play(sID);}
self.beginFade = function() { self.tween = fc.animator.createTween(1,0,'fade'); fc.animator.enqueue(self,self.aniFade,self.destructor);}
this.aniFade = function() { for (var i=self.particles.length; i--;) { self.particles[i].moveRel(); self.particles[i].nextState(); self.particles[i].setOpacity(fc.tweenFade[self.frame]);}
if (self.frame++>=self.tween.length) { self.active = false; self.frame = 0; if (self._oncomplete) self._oncomplete(); self._oncomplete = null; return false;}
return true;}
this.destructor = function() { writeDebug('firework.destructor()'); for (var i=self.particles.length; i--;) { self.particles[i].destructor(); self.particles[i] = null;}
self.particles = null; self.oC.removeChild(self.o); self.o = null; self.oC = null;}
this.animate = function() { self.moveTo(self.tween[0][self.frame].data,self.tween[1][self.frame].data,'burst'); if (self.frame++>=self.tween[0].length-1) { self.active = false; self.frame = 0; if (self._oncomplete) self._oncomplete(); self._oncomplete = null; return false;}
return true;}
this.createBurst = function(circles,nMax,rMax,type) { writeDebug('firework.createBurst('+circles+','+nMax+','+rMax+','+type+')'); var i=0, j=0; var tmp = 0; var radiusInc = rMax/circles; var radius = radiusInc; var angle = 0; var angleInc = 0; var radiusOffset = (self.allowRandom?(0.33+Math.random()):1); var particlesPerCircle = []; var isRandom = Math.random()>0.5; var circleTypes = [type,circles>1?parseInt(Math.random()*fc.particleTypes):type]; var thisType = null; for (i=0; i<circles; i++) { particlesPerCircle[i] = parseInt(nMax*(i+1)/circles*1/circles)||1; angle = angleInc; angleInc = 360/particlesPerCircle[i]; thisType = circleTypes[i%2]; for (j=0; j<particlesPerCircle[i]; j++) { self.particles[tmp] = new FireworkParticle(self.o,self.allowRandom,thisType,burstX,burstY,self.obeyBoundaries); self.particles[tmp].slideTo(radius*Math.cos(angle*Math.PI/180),radius*radiusOffset*Math.sin(angle*Math.PI/180)); angle += angleInc; tmp++;}
radius += radiusInc;}
}
self.oC.appendChild(self.o); self.moveTo(self.x,self.y); self.createBurst(nCircles,nParticles,nRadius,burstType); self.slideTo(burstX,burstY); var sID = 'fire'+parseInt(Math.random()*2); soundManager.setPan(sID,fc.getPanX(self.x)); soundManager.play(sID); fc.animator.start();}
function FireworkParticle(oC,isRandom,type,baseX,baseY,obeyBoundaries) { var self = this; this.oC = oC; this.oID = 'fp'+(fc.gOID++); this.o = fc.oFP.cloneNode(true); this.obeyBoundaries = obeyBoundaries; this.type = null; this.oImg = this.o.getElementsByTagName('img')[0]; this.oImg._src = this.oImg.src; this.o.style.display = 'none'; this.baseX = baseX; this.baseY = baseY; this.x = 0; this.y = 0; this.vx = 0; this.vy = 0; this.frame = 0; this.tween = []; this.active = null; this.tweenType = 'blast'; this.states = []; this.state = parseInt(Math.random()*3); this.isRandom = isRandom; this._mt = 5; this.moveTo = function(x,y) { self.o.style.left = x+'px'; self.o.style.top = y+'px'; self.vx = x-self.x; self.vy = y-self.y; self.x = x; self.y = y;}
this.moveRel = function() { var toX = self.x+self.vx; var toY = self.y+self.vy; if (self.obeyBoundaries) { var xMax = fc.canvasX-self.baseX-fc.particleXY; var yMax = fc.canvasY-self.baseY-fc.particleXY; var yMin = fc.scrollY; if (self.vx>=0) { if (toX>=xMax) self.vx *= -1;} else if (self.vx<0 && toX+self.baseX<=0) self.vx *= -1; if (self.vy>=0) { if (toY>=yMax) self.vy *= -1;} else if (self.vy<0) { if (toY+self.baseY-yMin<=0) self.vy *= -1;}
}
self.moveTo(self.x+self.vx,self.y+self.vy);}
this.setOpacity = function(n) { self.oImg.style.marginLeft = -100+(n*fc.particleXY/10)+'px';}
this.nextState = function() { var vis = self.o.style.visibility; if (self.state == 2 && vis != 'hidden') { self.o.style.visibility = 'hidden';} else if (self.state != 2 && vis == 'hidden') { self.o.style.visibility = 'visible';}
self.state = parseInt(Math.random()*3);}
this.slideTo = function(x1,y1) { if (self.isRandom) { x1 += (x1*0.2*(Math.random()>0.5?1:-1)); y1 += (y1*0.2*(Math.random()>0.5?1:-1));}
self.tween = [fc.animator.createTween(self.x,x1,self.tweenType),fc.animator.createTween(self.y,y1,self.tweenType)]; var xMax = fc.canvasX-fc.particleXY; var yMax = fc.canvasY-fc.particleXY; var xMin = fc.particleXY-self.baseX; var yMin = fc.scrollY; var toX = null; var toY = null; if (self.obeyBoundaries) { for (var i=self.tween[0].length; i--;) { toX = self.tween[0][i].data+self.baseX; toY = self.tween[1][i].data+self.baseY; if (toX>=xMax) { self.tween[0][i].data -= (toX-xMax)*2;} else if (toX<0) { self.tween[0][i].data -= (toX*2);}
if (toY>=yMax) { self.tween[1][i].data -= (toY-yMax)*2;} else if (toY-yMin<=0) { self.tween[1][i].data -= (toY-yMin)*2;}
}
}
}
this.animate = function() { var f0 = self.tween[0][self.frame].data; var f1 = self.tween[1][self.frame].data; self.moveTo(f0,f1); if (self.frame++>=self.tween[0].length-1) { if (self._oncomplete) self._oncomplete(); self._oncomplete = null; self.active = false; self.frame = 0; return false;} else if (self.frame>10) { self.nextState();}
return true;}
this.destructor = function() { self.oImg = null; self.oC.removeChild(self.o); self.oC = null; self.o = null;}
this.setType = function(t) { self.type = t; self.oImg.style.marginTop = -(fc.particleXY*t)+'px';}
self.setType(type); self.oC.appendChild(self.o);}
function Animator() { var self = this; writeDebug('Animator()'); this.tweens = []; this.tweens['default'] = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1]; this.tweens['blast'] = [12,12,11,10,10,9,8,7,6,5,4,3,2,1]; this.tweens['fade'] = [10,10,10,10,10,10,10,10,10,10]; this.queue = []; this.queue.IDs = []; this.active = false; this.timer = null; this.createTween = function(start,end,type) { type = type||'default'; var tween = [start]; var tmp = start; var diff = end-start; var x = self.tweens[type].length; for (var i=0; i<x; i++) { tmp += diff*self.tweens[type][i]*0.01; tween[i] = new Object(); tween[i].data = tmp; tween[i].event = null;}
return tween;}
this.enqueue = function(o,fMethod,fOnComplete) { if (!fMethod) { writeDebug('animator.enqueue(): missing fMethod');}
if (typeof(self.queue.IDs[o.oID])=='undefined') { var i = self.queue.length; self.queue.IDs[o.oID] = i; self.queue[i] = o;} else { var i = self.queue.IDs[o.oID]; self.queue[i].active = true; self.queue[i].frame = 0;}
o.active = true; self.queue[i]._method = fMethod; self.queue[i]._oncomplete = fOnComplete?fOnComplete:null;}
this.animate = function() { var active = 0; for (var i=self.queue.length; i--;) { if (self.queue[i].active) { self.queue[i]._method(); active++;}
}
if (active==0 && self.timer) { self.stop();} else { }
}
this.start = function() { if (self.timer || self.active) { return false;}
self.active = true; self.timer = setInterval(self.animate,fc.intervalRate);}
this.stop = function() { clearInterval(self.timer); self.timer = null; self.active = false; self.queue = []; self.queue.IDs = [];}
}
function createFirework(nRadius,nParticles,nCircles,nBurstType,startX,startY,burstX,burstY,allowRandom,obeyBoundaries) { var tmp = ''; for (var i in arguments) { tmp += i+',';}
writeDebug('createFirework('+tmp+')'); if (fc.isEmpty(startX)) { startX = parseInt(Math.random()*fc.canvasX);} else { startX = parseInt(fc.canvasX*startX/100);}
if (fc.isEmpty(startY)) { startY = fc.canvasY-fc.particleXY;} else { startY = fc.canvasY-fc.screenY+parseInt(fc.screenY*startY/100);}
if (fc.isEmpty(burstX)) { burstX = parseInt(fc.canvasX*0.1+(Math.random()*fc.canvasX*0.8));} else { burstX = parseInt(fc.canvasX*burstX/100);}
if (fc.isEmpty(burstY)) { burstY = fc.canvasY-parseInt(Math.random()*fc.screenY);} else { burstY = fc.canvasY-parseInt(fc.screenY*(100-burstY)/100);}
if (fc.isEmpty(nBurstType)) { nBurstType = parseInt(Math.random()*fc.particleTypes);}
if (fc.isEmpty(nRadius)) { nRadius = 64+parseInt(Math.random()*fc.screenY*0.75);} else if (nRadius.toString().indexOf('%')>=0) { nRadius = parseInt(parseInt(nRadius)/100*fc.screenY);} else if (nRadius.toString().indexOf('.')>=0) { nRadius = parseInt(nRadius*fc.screenY);} else { nRadius = parseInt(nRadius*fc.screenY/100);}
if (fc.isEmpty(nParticles)) { nParticles = 4+parseInt(Math.random()*64);}
if (fc.isEmpty(nCircles)) { nCircles = Math.random()>0.5?2:1;}
if (fc.isEmpty(allowRandom)) { allowRandom = Math.random()>0.5;}
if (fc.isEmpty(obeyBoundaries)) { obeyBoundaries = Math.random()>0.5;}
fc.getWindowCoords(); fc.fireworks[fc.fireworks.length] = new Firework(document.getElementById('fireContainer'),startX,startY,burstX,burstY,nBurstType,nRadius,nParticles,nCircles,allowRandom,obeyBoundaries);}
function smNull() { this.movies = []; this.container = null; this.unsupported = 1; this.FlashObject = function(url) {}
this.addMovie = function(name,url) {}
this.setPan = function() {}
this.destructor = function() {}
this.play = function(movieName,soundID) {return false;}
this.defaultName = 'default';}
var fc = new FireworksController(); if (typeof(SoundManager)=='undefined') var soundManager = new smNull(); if (typeof(writeDebug)=='undefined') var writeDebug = function(){return false;}
function addEventHandler(o,evtName,evtHandler) { typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);}
function removeEventHandler(o,evtName,evtHandler) { typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);}
addEventHandler(window,'resize',fc.getWindowCoords); addEventHandler(window,'scroll',fc.getWindowCoords); addEventHandler(window,'load',fc.init); addEventHandler(window,'unload',fc.destructor); 