//
//  Insert javascript files dynamicly
//  author: Michel Meyer
//  company: Brainsonic
//  version: 0.1
//  date :   2008/10/07
//
//
//  class attributes:
//
//  onComplete:         call when all files are loaded


var JavascriptLoader = new Class({
	
	Implements:       Options,
	
	javascripts:      [],
	counter:          0,
	length:           0,
	queryTokens:      null,
	statId:	  		  null,
	
	options: {
		onComplete: $empty
	},
	
	/** Constructor
	 * 
	 * @param {String} queryTokens   token for stream securization
	 * @param {Object} options
	 * 
	 */
	initialize: function(queryTokens, options){
		this.setOptions(options);
		this.queryTokens = queryTokens;
	},
	
	/** add a javascript file to the include list
	 * 
	 * @param {Object} javascriptUrl
	 */
	add: function(javascriptUrl){
		this.javascripts.push(javascriptUrl);
		this.length = this.javascripts.length;
	},
	
	/** insert all js files with mootools asset 
	 * 
	 */
	load: function(){
		
		this.javascripts.each(function(javascript){			
			new Asset.javascript(javascript + this.queryTokens, {
				onload: function(){
					this._javascriptLoaded();		
				}.bind(this)
			});
		}.bind(this));
	},
	
	/** private: call when a file is rightly included, call onComplete when all are loaded
	 * 
	 */
	_javascriptLoaded: function(){
		this.counter++;
		
		if(this.counter >= this.length){
			//reinitialize loader
			this.counter = 0;
			this.length = 0;
			this.javascripts = [];
			
			this.options.onComplete();
		}
	}
});



var BsUtils = new Class({
	prompt: function(title, text) {
		var c = new Custom.Prompt(title, text, {
			content: 'html',
			overlay: 'lighten',
			zones: {
				box: 'custom-box',
				head: 'custom-head', 
				body: 'custom-body',
				buttonBox: 'custom-buttonBox',
				promptBox: 'custom-input'
			},
			buttons: {
    			confirmButton: 'custom-button',
   				closeButton: 'custom-button',
   				cancelButton: 'custom-button'
			}
		});
		c.create();
	},
	

	getQueryVariable: function(variable) {
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		for (var i=0;i<vars.length;i++)
		{
			var pair = vars[i].split("=");
			if (pair[0] == variable)
			{
				return pair[1];
			}
		}
	},

	getUid: function() {
		var today = new Date();
		var uid = today.getFullYear() + "" + today.getMonth() + "" + today.getDate() + "" + today.getUTCHours() + "" + today.getUTCMinutes() + "" + today.getUTCSeconds() + "" + 100000000000000000*Math.random();
		return uid;
	}
})

/*
 * Script: live.class.js
 * Author: Brainsonic - http://www.brainsonic.com
 */

var Live = new Class({
	Implements: Events,
	Implements: Options,
	
	onLiveInitialized: $empty,
	
	bsUtils: new BsUtils(),

	options: {
		/* JAVASCRIPT & CSS ASSETS */
		id:'',
		workflow: false,
		config: false,
		stats: false,
		accordion: false,
		timedSlides: false,
		environment: 'prod',
		js_prod_dir: 'js_ob',
		js_dev_dir: 'js',
		typePlayer: 'none',  	/* Can be 'none', 'flash' or 'windowsmedia' */
		typeLive:   'live',     /* Can be 'live', 'fauxlive' or 'differe' */
		lang: 'FR',
		/* TOKENS */
		queryTokens: '',
		
		/* PANELS */
		panelContainer: null,
		panelsRefreshFrequency: 30000
	},

	defaultChatOptions: {
		automatic_connexion: false
	},
	
	defaultStatsOptions: {
		userId: null,
		statsUrlBase: 'http://storage17.brainsonic.com/StatsLive/',
		interval: 2000,
		page: 'live'
	},

	defaultWorkflowOptions: {
		interval: 2000,
		updaterUrl: 'files/php/updater.php'
	},
	
	defaultConfigOptions: {
		testBandwith: 				false,
		testBandwidthImageSource: 	'files/js/test_bandwidth.jpg',
		testBandwidthImageSize: 	378857,
		onBandwithTestFinished: 	$empty
	},
	
	defaultTimedSlidesOptions: {
		interval:				1000,
		currentSlideTxtPath:	'files/php/currentSlide.txt',
		slidesPath:				'images/slides',
		slidePrefix:			'',
		slideExtension:			'.png'
	},
	
	defaultAccordionOptions: {
		displayedPanel: 0,
		useRefresh: false
	},
	
	/* Player */
	
	player: null,
	
	/*Accordion*/
	
	bsPanelContainer:null,
	bsAccordion: null,	
	
	// Timed Slides
	timedSlides: null,
	
	//Commons parameters for players
	playerOptions: {
		width: 				null,
		height: 			null,
		currentPosition: 	0,
		urlTimeService: 	'files/php/timeService.php',
		objectId:     		'player',
		
		volume:				0,
		autostart:			true,
		allowfullscreen:	true,
		fmsID:				0,
		urlXmlFms:			'files/xml/componentAjax.xml',
		shownavigation:		false,
		
		/* EVENTS */
		
		onLoad:  $empty,        /* fired when player is insert in DOM */
		onReady: $empty         /* fired when player is ready */
	},
	
	
	/**
	 * Constructor
	 * Initialize the live framework asynchronously
	 * Example: var myLive = new Live(myFunction, {workflow: true, config: false, stats: true});
	 *
	 * @param onLiveInitialized {function} function called when the initialization is finished
	 * @param options {object} the differents functionalities that must be loaded. Functionalities are 'workflow', 'config', 'stats'. All are 'false' by default
	 */
	initialize: function(onLiveInitialized, options) {
		this.setOptions(options);
		this.onLiveInitialized = onLiveInitialized;
		
		var js_loader = new JavascriptLoader(this.options.queryTokens, {
			onComplete: function(){
				this.onLiveInitialized();
			}.bind(this)
		});
		
		var js_dir = this.options.environment == 'prod' ? this.options.js_prod_dir : this.options.js_dev_dir; 
		
		js_loader.add('files/' + js_dir + '/moo.rd_v1.3.1_source.js');
		
		
		// CHAT INSTANCE
		if (this.options.chat) {
			js_loader.add('files/' + js_dir + '/chat/moo.rd_v1.3.1_source.js');
			js_loader.add('files/' + js_dir + '/chat/bs-moowrapper.js');
			js_loader.add('files/' + js_dir + '/chat/divscroller.js');
			js_loader.add('files/' + js_dir + '/chat/scrollbar.js');
			
			js_loader.add('files/' + js_dir + '/chat/BSChatMain.js');
			js_loader.add('files/' + js_dir + '/chat/BSChatConnexion.js');
			js_loader.add('files/' + js_dir + '/chat/BSChatMessage.js');
			js_loader.add('files/' + js_dir + '/chat/BSChatVo.js');
			js_loader.add('files/' + js_dir + '/chat/BSFunctions.js');
			js_loader.add('files/' + js_dir + '/chat/soapclient.js');
			js_loader.add('files/' + js_dir + '/chat/I18N/I18N_'+this.options.lang+'.js');
		}
		
		// STATISTICS
		if (this.options.stats) {
			js_loader.add('files/' + js_dir + '/jsonp.js');
		}
		
		// WORKFLOW
		if (this.options.workflow) {
			js_loader.add('files/' + js_dir + '/workflow.class.js');
		}

		// CONFIG DETECTION
		if (this.options.config){
			js_loader.add('files/' + js_dir + '/PluginDetect.js');
		}
		
		// Player
		// Windows Media
		if(this.options.typePlayer.toLowerCase() == 'windowsmedia') 
		{
			js_loader.add('files/' + js_dir + '/WmPlayer.js');
		}
		
		// LivePlayer
		if(this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/' + js_dir + '/LivePlayer.js');
		}
		
		// SmartPlayer
		if((this.options.typeLive.toLowerCase() == 'differe' || this.options.typeLive.toLowerCase() == 'fauxlive') && this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/' + js_dir + '/SmartPlayer.js');
			js_loader.add('files/' + js_dir + '/JavaScriptFlashGateway.js');
		}
		
		// JwPlayer
		if(this.options.typeLive.toLowerCase() == 'live_synchro' && this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/' + js_dir + '/swfobject.js');
			js_loader.add('files/' + js_dir + '/JwPlayer.js');
		}
		 
		if(this.options.accordion)
		{	
			js_loader.add('files/' + js_dir + '/swfobject.js');		
			js_loader.add('components/accordion/' + js_dir + '/BSPanelContainerMain.js');
			js_loader.add('components/accordion/' + js_dir + '/BSPanelContainerInjector.js');			
		}
		
		// TIMED SLIDES
		if (this.options.timedSlides || (this.options.typePlayer.toLowerCase() == 'windowsmedia'))
		{	
			js_loader.add('files/' + js_dir + '/TimedSlides.js');		
		}
		
		js_loader.load();
	},
	
	/**
	* Configure timed slides
	*
	* @param {String} element                   	Id of the element where the slides will be displayed
	* @param {Array} timedSlidesOptions	Options for the timedSlides object (interval, currentSlideTxtPath, slidesPath, slidePrefix, slideExtension)
	*/
	initializeTimedSlides: function(element, timedSlidesOptions) 
	{
		timedSlidesOptions = $merge(this.defaultTimedSlidesOptions, timedSlidesOptions);	
		this.timedSlides = new TimedSlides(element, timedSlidesOptions);
		this.timedSlides.run();
	},	
	
	/*
		Function: initializeAccordion
		Parameters: none
		Description: initialize the Accordion part of the interface
	*/
	initializeAccordion: function(accordionContainer, togglers, stretchers, accordionOptions)
	{
		accordionOptions = $merge(this.defaultAccordionOptions, accordionOptions);
		stretchers.each(function(item)
		{
			item.setStyles({'height': '0', 'overflow': 'hidden'});
		});

		this.bsAccordion = new Accordion(togglers, stretchers,
		{ 
			opacity: true, 
			fixedHeight: accordionContainer.getStyle('height').toInt(), 
			fixedWidth: accordionContainer.getStyle('width').toInt(),
			transition: Fx.Transitions.Quad.easeOut,
			onActive: function(toggler, elt)
			{
				this.fireEvent('accordion_active');
			},
			onBackground: function(toggler, elt)
			{
				this.fireEvent('accordion_background');
			}
		});
		
		accordionContainer.setStyle('opacity', '1');
		this.bsAccordion.display(accordionOptions.displayedPanel);
		if (accordionOptions.useRefresh)
			this.bsPanelContainer = new BSPanelContainer(this.options.id, 'http://espadon.bs-devdebian01.bs.lan/logsAjax/', this.bsAccordion);
		return this.bsAccordion;
	},
	
	initializePanels: function()
	{
		this.refreshPanels();
		this.refreshPanels.periodical(this.panelsRefreshFrequency, this);
	},

	/* 
		Function: refreshPanels 
	   	Parameters: none
		Description: Add dynamic panels availability
	*/
	refreshPanels: function()
	{
		var i;
	
		try
		{
			if(window.ActiveXObject)
			{
				i = new ActiveXObject("Microsoft.XMLDOM");
				i.async = false;
				i.load('files/xml/live.xml');
				this.displayPanelChanges(i);
			}
			else 
				if(document.implementation && document.implementation.createDocument)
				{
					i = document.implementation.createDocument('', '', null);
					i.load('files/xml/live.xml');
					i.onload = this.displayPanelChanges(i);
				}
		}
		catch(ex){}				
	},
	
	displayPanelChanges: function(xmldocument)
	{
		var tabList = xmldocument.getElementsByTagName('tab');
		$each(tabList, function(element)
		{
			/* utiliser ici: panelContainer */
			/* var frame = $$('#accordionContainer div.accordion')[element.getAttribute('id')].getFirst(); */
			if(frame.getTag() == "iframe")
			{
				if(frame.getProperty('src') != element.getAttribute('url'))
				{
					frame.setProperty('src', element.getAttribute('url'));

					if(element.getAttribute('toggle') == "true")
						myAccordion.showThisHideOpen(element.getAttribute('id'));
				}						
			}
		});
	},

	/*
		Function: initializeStats
		Parameters: none
		Description: initialize the Statistics part of the interface
	*/
	initializeStatistics: function(projectName, statsOptions) {
		statsOptions = $merge(this.defaultStatsOptions, statsOptions);
	
		// Getting stat cookie value to know if it's the first time the user come
		if(!$defined(statsOptions.userId)) {
			var statCookieValue = Cookie.read(projectName + '-userId');
			if(!$defined(statCookieValue)) {
				statsOptions.userId = new BsUtils().getUid();
				Cookie.write(projectName + '-userId', statsOptions.userId, {duration: 1});
			}
			else {
				statsOptions.userId = statCookieValue;
			}
		}
		
		// Sending stat start request
		new JsonP(statsOptions.statsUrlBase + '/userStart.php', {
			data: {
				projectName: projectName,
				userId: statsOptions.userId,
				pingInterval: statsOptions.interval,
				page: statsOptions.page
			},
			onComplete: function(data) {
				//this.statId = data.statId;
				//this.statsRequest = new JsonP(statsOptions.statsUrlBase + '/userPing.php?statId=' + data.statId);
				this._pingStatisticsServer(statsOptions.statsUrlBase, data.statId);
				this._pingStatisticsServer.periodical(statsOptions.interval, this, [statsOptions.statsUrlBase, data.statId]);
			}.bind(this)
		}).request();
	},
	
	_pingStatisticsServer: function(statsUrlBase, statId) {
		new JsonP(statsUrlBase + '/userPing.php', {
			data: {
				statId: statId,
				fakeParam: new Date().getTime()
			}
		}).request();
	},

	initializeChat: function(liveId, chatOptions) {
		
		chatOptions = $merge(this.defaultChatOptions, chatOptions);
		ChatLive = new ChatLive(liveId, chatOptions);
		
		/* To manage Automatic Connexion*/
		var login = this.bsUtils.getQueryVariable('login');
		if (ChatLive.automatic_connexion && login)
			ChatLive.connexionUser(login);
	},	
	
	/** configure player options and initalize the player
	 * 
	 * @param {String} videoUrl         video or smartplayer config file url
	 * @param {String} container        element where insert embed code
	 * @param {Object} playerOptions    options for players
	 */
	initializePlayer: function(videoUrl, container, playerOptions) {
		
		this.playerOptions = $merge(this.playerOptions, playerOptions);
		
		switch( this.options.typeLive.toLowerCase() ) {
			// Live Player Initialization 
			case 'live':
				this.player = this._createPlayer(videoUrl, container, this.playerOptions);
				break;
				
			// JW Live Player Initialization 
			case 'live_synchro':
				this.player = this._createPlayer(videoUrl, container, this.playerOptions);
				break;
			
			// "Faux Live" Player Initialization 
			case 'fauxlive':
				// the first save the time client at starting making request to call service ( to caculate elapsed time later)
				this.timeRequest = new Date().getTime();
				// then call ajax service
				var request = new Request({url: this.playerOptions.urlTimeService});
				request.addEvent('success', function(timeThreshold) {
					var elapsedTime = (new Date().getTime() - this.timeRequest)/1000;
					if (timeThreshold > 0 && timeThreshold != -1){
						this.playerOptions.currentPosition = timeThreshold.toInt() + elapsedTime.toInt();
					}
					this.player = this._createPlayer(videoUrl, container, this.playerOptions);
					
				}.bind(this));
				request.send();
			
				break;
			
			// "Differe" Player Initialization 
			case 'differe':
				var currentPosition = new BsUtils().getQueryVariable('currentPosition');
				if(!$defined(currentPosition) || currentPosition == '')	currentPosition = 0;
				
				this.playerOptions.currentPosition = currentPosition;
				this.playerOptions.showControls = true;
				this.player = this._createPlayer(videoUrl, container, this.playerOptions);
			
				break;
		}
	},

	/** return a player in function of configuration 
	 * 
	 * @param {String} videoUrl         video or smartplayer config file url
	 * @param {String} container        element where insert embed code
	 * @param {Object} playerOptions    options for players
	 */
	_createPlayer: function(videoUrl, container, playerOptions){
		
		//define player dimension if they are not allready setted
		if(!$defined(playerOptions.width))
			playerOptions.width  = $(container).getSize().x;
		if(!$defined(playerOptions.height))
			playerOptions.height = $(container).getSize().y;
		
		if(this.options.typePlayer.toLowerCase() == 'windowsmedia') {
			return new WmPlayer(videoUrl, container, playerOptions);
		}
		else if(this.options.typeLive.toLowerCase() == 'live_synchro' && this.options.typePlayer.toLowerCase() == 'flash') {
			return new JwPlayer(videoUrl, container, playerOptions);
		}
		else if(this.options.typeLive.toLowerCase() != 'live' && this.options.typePlayer.toLowerCase() == 'flash' ) {
			return new SmartPlayer(videoUrl, container, playerOptions);
		}
		else if(this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'flash') {
			return new LivePlayer(videoUrl, container, playerOptions);
		}
	},
	
	initializeWorkflow: function(typePage, options) {
		var workflow = new Workflow(typePage, $extend($pick(options, {}), {queryTokens: this.options.queryTokens}));
		workflow.run();
	}
});

