//
//  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,
	
	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();
	},
	
	alert: function(title, text) {
		var c = new Custom.Alert('<span>' + title + '</span>', text, {
			content: 'html',
			overlay: 'darken',
			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,
	
	bsAccordion: null,
	statId: null,
	
	
	onLiveInitialized: $empty,
	
	bsUtils: new BsUtils(),

	options: {
		/* JAVASCRIPT & CSS ASSETS */
		workflow: false,
		config: false,
		stats: false,
		typePlayer: 'none',  	/* Can be 'none', 'SmartPlayer' or 'WindowsMedia' */
		typeLive:   'live',     /* Can be 'live', 'fauxlive' or 'differe' */
		/* TOKENS */
		queryTokens: '',
		
		/* PANELS */
		panelContainer: null,
		panelsRefreshFrequency: 30000
	},

	defaultChatOptions: {
		path: 'components/chat',
		lang: 'fr',
		is_private:false,
		pass: ''
	},
	
	defaultStatsOptions: {
		userId: null,
		statsUrlBase: ''
	},

	defaultWorkflowOptions: {
		interval: 2000,
		updaterUrl: 'files/php/updater.php'
	},
	
	defaultConfigOptions: {
		testBandwith: false,
		testBandwidthImageSource: 'files/js/test_bandwidth.jpg',
		testBandwidthImageSize: 378857,
		onBandwithTestFinished: $empty
	},
	
	/* Player */
	
	player: null,
	
	
	//Commons parameters for players
	playerOptions: {
		width: 				null,
		height: 			null,
		currentPosition: 	0,
		urlTimeService: 	'files/php/timeService.php',
		objectId:     		'player',
		
		/* 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)
		});
		
		js_loader.add('files/js/moo.rd_v1.3.1_source.js');
		
		
		// STATISTICS
		if (this.options.stats) {
			js_loader.add('files/js/jsonp.js');
		}
		
		// WORKFLOW
		if (this.options.workflow) {
			js_loader.add('files/js/workflow.class.js');
		}

		// CONFIG DETECTION
		if (this.options.config){
			js_loader.add('files/js/PluginDetect.js');
		}
		
		// Player
		// Windows Media
		if(this.options.typePlayer.toLowerCase() == 'windowsmedia') {
			js_loader.add('files/js/WmPlayer.js');
		}
		
		// LivePlayer
		if(this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/js/LivePlayer.js');
		}
		
		// SmartPlayer
		if(this.options.typeLive.toLowerCase() != 'live' && this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/js/SmartPlayer.js');
			js_loader.add('files/js/JavaScriptFlashGateway.js');
		}
		 
		if(this.options.typePlayer.toLowerCase() == 'windowsmedia' 
		|| this.options.typePlayer.toLowerCase() == 'flash') {
			js_loader.add('files/js/PluginDetect.js');
		}
		
		js_loader.load();
	},
	
	
	
	/*
		Function: initializeAccordion
		Parameters: none
		Description: initialize the Accordion part of the interface
	*/
	initializeAccordion: function(togglers, stretchers)
	{
		this.options.stretchers.each(function(item)
		{
			item.setStyles({'height': '0', 'overflow': 'hidden'});
		});

		this.bsAccordion = new Accordion(togglers, stretchers,
		{ 
			opacity: true, 
			fixedHeight: this.options.accordionContainer.getStyle('height').toInt(), 
			fixedWidth: this.options.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');
			}
		});
		
		this.options.accordionContainer.setStyle('opacity', '1');
		this.bsAccordion.display(0);
		
		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);
	
		/*statsRequest = new JsonP(statsUrl + '?userId=' + statsOptions.userId);
		this.pingServer();
		this.pingServer.periodical(statsOptions.interval * 1000);*/
		
		// 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
			},
			onComplete: function(data) {
				this.statId = data.statId;
			}.bind(this)
		}).request();
		
		// Adding event on unload for sending stat end request
		window.addEvent('unload', function() {
			new JsonP(statsOptions.statsUrlBase + '/userEnd.php?statId=' + this.statId).request();
		}.bind(this));
	},
	
	/*pingServer: function() {
		statsRequest.request();
	},*/

	initializeChat: function(liveId, container, chatOptions) {
		container = $(container);
		chatOptions = $merge(this.defaultChatOptions, chatOptions);

		if ($defined(chatOptions.pass))
			container.set('html', '<iframe src="' + chatOptions.path + 'chat.html?idlive=' + liveId + '&lang=' + chatOptions.lang + '&history=' + chatOptions.history + '&loginform=' + chatOptions.loginForm + '&pass=' + chatOptions.pass + '" frameborder="0" scrolling="no" allowtransparency="yes"></iframe>');
	},

	/** 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;
			
			/*
			 *    "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(this.options.width))
			playerOptions.width  = $(container).getSize().x;
		if(!$defined(this.options.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' && 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();
	}
});

