var boxPlayer = Class.create({

    initialize: function(config) {
    	window.pl = this;

    	this.isIE = navigator.userAgent.match(/msie/i);
    	this.isOpera = navigator.userAgent.match(/opera/i);
    	this.isFirefox = navigator.userAgent.match(/firefox/i);
    	this.isSafari = navigator.userAgent.match(/safari/i);

    	window.soundManager = new SoundManager();

    	window.soundManager.useFlashBlock = true;
    	window.soundManager.url = 'swf/';

    	//this.debugMode = (window.location.href.toString().match(/debugMode=1/i)?true:false); // enable with #debug=1 for example
    	window.soundManager.debugMode = (window.location.href.toString().match(/debugMode=1/i)?true:false);
    	window.soundManager.debugFlash = (window.location.href.toString().match(/debugFlash=1/i)?true:false);

    	window.soundManager.onload = function() {
    	    $('mainDiv').fire("sm2:loaded");
    	};

    	window.soundManager.onready(function(){
    	    if (window.soundManager.supported() && $('sm2-support').visible())
    		$('sm2-support').hide();
    	});

    	window.soundManager.onerror = function() {
    	    $('sm2-support').insert('<h3>Oupps !</h3><p>Le site Reaction Power Trio ne peut démarrer !</p>'+
    		    		    '<p id="flashblocker">Si vous utilisez un bloqueur de flash (flash blocker) essayez d\'autoriser le composant flash ci-dessous.</p>'+
    		    		    '<p>Si Adobe Flash Player n\'est pas present sur votre navigateur ou est d\'une version trops ancienne, vous devez installer, pour votre navigateur, une version supérieure ou éguale à Flash Player 9 pour vous permettre de visionner notre site.</p>'+
    		    		    '<div><a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img src="img/Get_Flash_Player.jpg" /></a></div>'+
    		    		    '<p>Vous pouvez égualement consulter la page de recherche d\'erreurs (en anglais) de ce site : <a href="troubleshoot/" target="_blank">Troubleshooting</a></p>');
    	    if(window.soundManager.getMoviePercent()){
    		$('flashblocker').hide();
    	    }
    	    if($('loading').visible()) $('loading').hide();
    	    $('sm2-support').show();
    	};

    	this.config = Object.extend ({
    		flashVersion: 9,
    		usePeakData: true,
    		allowRightClick:true,
    		autoStart: false,
    		playNext: false,
    		updatePageTitle: true,
    		useFavIcon: true,
    		useHighPerformance: true
    	}, config || {});

    	window.soundManager.flashVersion = this.config.flashVersion;
    	window.soundManager.useHighPerformance = this.config.useHighPerformance;
    	if (window.soundManager.flashVersion >= 9) {
    	    window.soundManager.defaultOptions.usePeakData = this.config.usePeakData;
    	}

    	window.soundManager.beginDelayedInit();

    	this.css = {
    		sDefault: 'sm2_link',
    		sLoading: 'sm2_loading',
    		sPlaying: 'sm2_playing',
    		sPaused: 'sm2_paused'
    	};

    	this.links = [];
	this.sounds = [];
	this.soundsByObject = [];
	this.lastSound = null;
	this.soundCount = 0;
	this.strings = [];
	this.pageTitle = document.title;
	this.lastWPExec = new Date();
	this.xbmImages = [];
    	this.statusBar = $($('statusbar-template').cloneNode(true));
    	this.statusBar.id = '';

    	if (this.config.useFavIcon) {
    	    if (this.isFirefox || this.isOpera) {
    		this.createXBMData();
    	    } else {
    		this.config.useFavIcon = false;
    	    }
    	}
    	document.observe("stage:loaded", this.initBoxPlayer.bindAsEventListener(this));
    }, //initialize

    initBoxPlayer: function(e) {
	e.stop();
    	window.soundManager._writeDebug('boxPlayer.initialize()');

    	var foundItems = 0;
	$$('a').each((function(link, i) {
	    if ((window.soundManager.canPlayURL(link.href) || link.hasClassName('playable')) && !link.hasClassName('exclude')) {
		link.rel = 'boxPlayerMP3Sound'+i;
		this.links[this.links.length] = link;
		link.down().addClassName(this.css.sDefault);
		foundItems++;
	    }
	}).bind(this));
	if (foundItems>0) {
	    Event.observe(document, 'click', this.handleClick.bindAsEventListener(this));
	    Event.observe(window, 'unload', function(){ Event.unloadCache; });
	}
	window.soundManager._writeDebug('boxPlayer.init(): Found '+foundItems+' relevant items.');
	$('mainDiv').fire("bp:inited");
	if (this.config.autoStart) {
	    this.handleClick({ target: this.links[0] });
	}
    }, //initBoxPlayer

    createXBMData: function() {
	window.soundManager._writeDebug('createXBMData');
	var ico = null;
	var i=0;
	var j=0;
	for (i=0; i<16; i++) {
	    this.xbmImages[i] = [];
	}
	for (var i=0; i<16; i++) {
        	for (j=0; j<16; j++) {
        	    ico = new XBMImage(16,16,'img'+i+'x'+j);
        	    ico.drawBoxFilled(0,16-i,7,16-(i-16));
        	    ico.drawBoxFilled(9,16-j,16,16-(j-16));
        	    this.xbmImages[i][j] = 'data:image/x-bitmap,'+encodeURI(ico.getXBM());
        	}
	}
    }, //createXBMData

    getSoundByObject: function(o) {
	return (typeof this.soundsByObject[o.rel] != 'undefined'?this.soundsByObject[o.rel]:null);
    },

    getSoundIndex: function(o) {
	for (var i=this.links.length; i--;) {
	    if (this.links[i].rel == o.rel) return i;
	}
	return -1;
    },

    setPageTitle: function(sTitle) {
	if (!this.config.updatePageTitle) return false;
	try {
	    document.title = (sTitle?sTitle+' - ':'')+this.pageTitle;
	} catch(e) {
	    this.setPageTitle = function() {return false;}
	}
    },

    stopSound: function(oSound) {
	window.soundManager._writeDebug('stopping sound: '+oSound.sID);
	window.soundManager.stop(oSound.sID);
	window.soundManager.unload(oSound.sID);
    },

    handleClick: function(e) {
	window.soundManager._writeDebug('handleClick');
	if (e.isRightClick()) {
	    if (!this.config.allowRightClick) e.stop();
	    return (this.config.allowRightClick);
	}
	var o = e.findElement('a');
	if (o) {
	    if (!o.href || (!window.soundManager.canPlayURL(o.href) && !o.hasClassName('playable')) || o.hasClassName('exclude')) {
		if (this.isIE && o.onclick) {
		    return false;
		}
		return true;
	    }
	    var soundURL = o.href;
	    var thisSound = this.getSoundByObject(o);
	    if (thisSound) {
		this.setPageTitle(thisSound._data.originalTitle);
		if (thisSound == this.lastSound) {
		    if (thisSound.readyState != 2) {
			if (thisSound.playState != 1) {
			    thisSound.play();
			} else {
			    thisSound.togglePause();
		        }
		    } else {
			window.soundManager._writeDebug('Warning: sound failed to load (security restrictions, 404 or bad format)',2);
		    }
		} else {
		    if (this.lastSound) this.stopSound(this.lastSound);
		    thisSound.togglePause();
		}
	    } else {
		thisSound = window.soundManager.createSound({
		    	id:'boxPlayerMP3Sound'+(this.soundCount++),
		    	url:soundURL,
		    	onplay:this.events.play,
		    	onstop:this.events.stop,
		    	onpause:this.events.pause,
		    	onresume:this.events.resume,
		    	onfinish:this.events.finish,
		    	whileloading:this.events.whileloading,
		    	whileplaying:this.events.whileplaying,
		    	onload:this.events.onload
		});
		var oStatusBar = $(this.statusBar.cloneNode(true));
		o.down().insert(oStatusBar);
		this.soundsByObject[o.rel] = thisSound;
		thisSound._data = {
			oLink: o,
		        oSpan: o.down(),
		        oStatus: o.down('span.statusbar'),
		        oLoading: o.down('span.loading'),
		        oPosition: o.down('span.position'),
		        nIndex: this.getSoundIndex(o),
		        className: this.css.sPlaying,
		        originalTitle: o.down().innerHTML.stripTags().unescapeHTML(),
		        metadata: null
		};
		this.sounds.push(thisSound);
		if (this.lastSound) this.stopSound(this.lastSound);
		thisSound.play();
	    }
	    this.lastSound = thisSound;
	    e.stop();
	    return false;
	} else {
	    return true;
	}
    }, //handleClick

    resetPageIcon: function() {
	if (!this.config.useFavIcon) return false;
	if ($('favicon')) {
	    $('favicon').href = '/favicon.ico';
	}
    },

    updatePeaks: function() {
	if (window.pl.config.flashVersion > 8 && window.pl.config.useFavIcon && window.pl.config.usePeakData) {
	    if (!window.pl.isOpera) {
		window.pl.setPageIcon(window.pl.xbmImages[parseInt(15*this.peakData.left)][parseInt(15*this.peakData.right)]);
	    } else {
		window.pl.setPageIcon(window.pl.xbmImages[1+parseInt(14*this.peakData.left)][1+parseInt(14*this.peakData.right)]);
	    }
	}
    },

    setPageIcon: function(sDataURL) {
	if (!window.pl.config.useFavIcon || !window.pl.config.usePeakData || !sDataURL) return false;
	if (!$('favicon')) {
	  var link = $('favicon');
	  link = document.createElement('link');
	  link.id = 'favicon';
	  link.rel = 'shortcut icon';
	  link.type = 'image/x-bitmap';
	  link.href = sDataURL;
	} else {
	    var link = $('favicon');
	    link.href = sDataURL;
	}
	document.getElementsByTagName('head')[0].appendChild(link);
    },

    getDurationEstimate: function(oSound) {
	return (oSound.durationEstimate);
    },

    fireFinish: function() {
	$('mainDiv').fire("sm2sound:finish");
    },

    events: {

	play: function() {
	    this._data.oSpan.removeClassName(this._data.className);
	    this._data.className = window.pl.css.sPlaying;
	    this._data.oSpan.addClassName(this._data.className);
	    window.pl.setPageTitle(this._data.originalTitle);
	},

	stop: function() {
	    this._data.oSpan.removeClassName(this._data.className);
	    this._data.className = '';
	    this._data.oPosition.style.width = '0px';
	    window.pl.setPageTitle();
	    window.pl.resetPageIcon();
	},

	pause: function() {
	    this._data.oSpan.removeClassName(this._data.className);
	    this._data.className = window.pl.css.sPaused;
	    this._data.oSpan.addClassName(this._data.className);
	    window.pl.setPageTitle();
	    window.pl.resetPageIcon();
	},

	resume: function() {
	    this._data.oSpan.removeClassName(this._data.className);
	    this._data.className = window.pl.css.sPlaying;
	    this._data.oSpan.addClassName(this._data.className);
	},

	finish: function() {
	    this._data.oPosition.style.width = '0px';
	    this._data.oLink.fade({ duration: 4, afterFinish: function(){
		this._data.oSpan.removeClassName(this._data.className);
		this._data.className = '';
		if (window.pl.config.playNext && this._data.nIndex<window.pl.links.length-1) {
		    window.pl.handleClick({target:window.pl.links[this._data.nIndex+1]});
		} else {
		    window.pl.setPageTitle();
		    window.pl.resetPageIcon();
		}
		window.pl.fireFinish();
	    }.bind(this)});
	},

	whileloading: function() {
	    this._data.oLoading.style.width = (((this.bytesLoaded/this.bytesTotal)*100)+'%');
	},

	onload: function() {
	    if (!this.loaded) {
		setTimeout(function(){
		    $('mainDiv').insert('<span style="font-size:1em">Load failed, d\'oh! '+(window.soundManager.sandbox.noRemote?' Possible cause: Flash sandbox is denying remote URL access.':(window.soundManager.sandbox.noLocal?'Flash denying local filesystem access':'404?'))+'</span>');
		},5000);
	    }
	},

	whileplaying: function() {
	    var d = new Date();
	    if (d-window.pl.lastWPExec>500) {
		if (window.soundManager.flashVersion >= 9) {
	            if (window.pl.config.usePeakData && this.instanceOptions.usePeakData) {
	        	window.pl.updatePeaks.apply(this);
		    }
		}
	        this._data.oPosition.style.width = (((this.position/window.pl.getDurationEstimate(this))*100)+'%');
	        window.pl.lastWPExec = d;
	    }
	}
    } // events{}

});

// XBM support

// xbmDraw.js XBM drawing library
// (c)2002 David L. Blackledge
// http://David.Blackledge.com
// Written April, 2002
// You may use this if you keep this copyright notice intact
//
// See http://David.Blackledge.com/XBMDrawLibrary.html
// Some unused functions removed, see site for complete library

function array_copy(o_array) {
 var ret_array = new Array();
 if(typeof(ret_array.concat) == "function")
  return ret_array.concat(o_array);
 for(var j = 0 ; j < o_array.length ; ++j) {
  ret_array[ret_array.length] = o_array[j];
 }
 return ret_array;
}

function XBMImage_body() {
 var bod = "";
 for(var i = 0 ; i < this.height ; ++i) {
  for(var j = 0 ; j < this.width/8 ; ++j) {
   if(typeof(this.data[i]) != "undefined" && typeof(this.data[i][j]) != "undefined") {
    // must be reversed to work right, apparently.
    var bool = 0;
    bool = this.data[i][j];
    var hex = (new Number(bool)).toString(16);
    if(hex.length == 1)
     hex = "0"+hex;
    bod += "0x"+hex+",";
   } else {
    bod += "0x00,";
   }
  }
 }
 if(bod.length > 0) // remove trailing comma
  bod = bod.substring(0,bod.length-1);
 return bod;
}

function XBMImage_draw(x,y) {
 if(!(x > -1 && x < this.width && y > -1 && y < this.height))
  return;
 if(typeof(this.data[y]) == "undefined")
   this.data[y] = new Array();
 var bit = x%8;
 var byt = (x-bit)/8;
 if(typeof(this.data[y][byt]) == "undefined")
   this.data[y][byt] = 0;
 this.data[y][byt] |= (0x01<<bit);
}

// attempt to do a fast horizontal line algorithm.
function XBMImage_drawHLine(x1,y1,x2) {
 if(!(y1 > -1 && y1 < this.height))
  return;
 if(x1 > x2){
  var xs = x1;x1=Math.max(0,x2);x2=Math.min(this.width,xs);
 }
 var filled = 0xFF;
 var startbits = x1%8;
 var startbyt = (x1-x1%8)/8;
 var endbits = 8-x2%8;
 var endbyt = (x2-x2%8)/8;
 if(startbyt == endbyt) {
  this.data[y1][startbyt]|=(filled <<startbits)&(filled>>endbits);
  return;
 }
 for(var i = startbyt+1 ; i < endbyt ; ++i) {
  this.data[y1][i] = filled;
 }
 for(var j=x1; j < (x1+(8-x1%8)) ; ++j)
  this.draw(j,y1);
 this.data[y1][endbyt] |= (filled >>endbits);
}

function XBMImage_drawVLine(x1,y1,y2) {
 if(!(x1 > -1 && x1 < this.width))
  return;
 if(y1 > y2){
  var ys = y1;y1=Math.max(0,y2);y2=Math.min(this.height,ys);
 }
 var bit = x1%8;
 var byt = (x1-bit)/8;
 var bitmask = (0x01<<bit);
 for(var y = y1 ; y <= y2 ; ++y)
  this.data[y][byt] |= bitmask;
}

function XBMImage_drawLine(x1,y1,x2,y2) {
 if(x1 > x2) {
  var xx = x1; x1 = x2; x2 = xx;
  var yy = y1; y1 = y2; y2 = yy;
 }
 var y = y1;
 if(y1 == y2)
   if(x1 == x2)
	 return this.draw(x1,y1);
   else
	 return this.drawHLine(x1,y1,x2);
 if(x1 == x2) return this.drawVLine(x1,y1,y2);
 var slope=(y1-y2)/(x1-x2);
 var yint = y1-Math.floor(slope*x1); // y-intercept
 for(var x = x1; x < x2; ++x) {
  if(slope > 0) { //y1<y2 (top to bottom)
   for(y = Math.floor(slope*x)+yint ; y < (Math.floor(slope*(x+1))+yint) ; ++y) {
    this.draw(x,y);
   }
   if(Math.floor(slope*x) == Math.floor(slope*(x+1)))
    this.draw(x,y);
   if(x==x2-1) {
    for(y ; y <= y2 ; ++y) {
     this.draw(x,y);
    }
   }
  } else { //y1>y2 (bottom to top)
   for(y = Math.floor(slope*x)+yint ; y > (Math.floor(slope*(x+1))+yint) ; --y) {
    this.draw(x,y);
   }
   if(Math.floor(slope*x) == Math.floor(slope*(x+1)))
    this.draw(x,y);
   if(x==x2-1) {
    for(y ; y >= y2 ; --y) {
     this.draw(x,y);
    }
   }
  }
 }
 return null;
}

function XBMImage_drawBoxFilled(x1,y1,x2,y2) {
 for(var y = y1; y <= y2; ++y)
  this.drawHLine(x1,y,x2);
}

function XBMImage_getXBM() {
 return this.header + this.body() + this.footer;
}

function XBMImage_setXBM(str){
 var xbmdata = str.substring(str.indexOf("{")+1,str.lastIndexOf("}"));
 var a_data = xbmdata.split(",");
 for(var j = 0 ; j < this.height ; ++j) {
  this.data[j] = new Array();
  for(var i = 0 ; i < Math.floor(this.width/8) ; ++i) {
   var a_idx = i+j*(Math.floor(this.width/8));
   if(a_idx < a_data.length)
    this.data[j][i] = (new Number(parseInt(a_data[a_idx],16))).valueOf();//parseInt(a_data[a_idx]);
  }
 }
}

function XBMImage(width,height,name) {
 this.name = name;
 this.width = width+((width%8)>0?(8-(width%8)):0); //expand to a multiple of 8
 this.height = height;
 this.header = "#define "+name+"_width "+this.width+"\n"+
   "#define "+name+"_height "+this.height+"\n"+
   "static char "+name+"_bits[] = {\n";
 this.footer = "};";
 this.data = new Array(this.height);
 for(var i = 0 ; i < this.data.length ; ++i) {
  this.data[i] = new Array(this.width);
  for(var j = 0 ; j < this.data[i].length ; ++j) {
   this.data[i][j] = 0;
  }
 }
 this.frames = new Array(); // store copies of this.data;
 this.body = XBMImage_body;
 this.draw = XBMImage_draw;
 this.drawLine = XBMImage_drawLine;
 this.drawHLine = XBMImage_drawHLine;
 this.drawVLine = XBMImage_drawVLine;
 this.drawBoxFilled = XBMImage_drawBoxFilled;
 this.getXBM = XBMImage_getXBM;
 this.setXBM = XBMImage_setXBM;
 this.xbm = this.getXBM();
}

/*window.soundManager.url = 'swf/';
window.soundManager.flashVersion = 9;
window.soundManager.debugMode = (window.location.href.toString().match(/debug=1/i)?true:false); // enable with #debug=1 for example

window.soundManager.onload = function() {
    new boxPlayer();
}*/