//
//  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;
	},
	
	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();
	}
})

/*
 * 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,
        timedFMSSlides: false,
        environment: 'prod',
        js_prod_dir: 'files/js_ob',
        js_dev_dir: 'files/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,
        noLimitBrainsonic: false
    },

    defaultChatOptions: {
        automatic_connexion: false,
        baseUrl: 'http://rcdn-0.brainsonic.com/c2/cdn/0',
        allowDoubleLogin: false,
        addInHistoryMessageDelegate: null,
        room: null,
        authorized_vip: true
    },

    defaultStatsOptions: {
        userId: null,
        statsUrlBase: 'http://vipstats-cdn.brainsonic.com',
        interval: 30000,
        page: 'live'
    },

    defaultWorkflowOptions: {
        interval: 5000,
        updaterUrl: 'files/workflow/Updater.aspx'
    },

    defaultConfigOptions: {
        testBandwith: false,
        testBandwidthImageSource: 'files/js/test_bandwidth.jpg',
        testBandwidthImageSize: 378857,
        onBandwithTestFinished: $empty
    },

    defaultTimedSlidesOptions: {
        interval: 1000,
        currentSlideTxtPath: 'files/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/timeService.aspx',
        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;
        this.options.noLimitBrainsonic = this.bsUtils.getQueryVariable('noLimitBrainsonic') == 'true';
        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(js_dir + '/moo.rd_v1.3.1_source.js');


        // CHAT INSTANCE
        if (this.options.chat) {
            js_loader.add(js_dir + '/chat/moo.rd_v1.3.1_source.js');
            js_loader.add(js_dir + '/chat/bs-moowrapper.js');
            js_loader.add(js_dir + '/chat/divscroller.js');
            js_loader.add(js_dir + '/chat/scrollbar.js');

            js_loader.add(js_dir + '/chat/BSChatMain.js');
            js_loader.add(js_dir + '/chat/BSChatConnexion.js');
            js_loader.add(js_dir + '/chat/BSChatMessage.js');
            js_loader.add(js_dir + '/chat/BSChatVo.js');
            js_loader.add(js_dir + '/chat/BSFunctions.js');
            js_loader.add(js_dir + '/chat/soapclient.js');
            js_loader.add(js_dir + '/chat/I18N/I18N_' + this.options.lang + '.js');
        }

        // STATISTICS
        if (this.options.stats) {
            js_loader.add(js_dir + '/jsonp.js');
        }

        // WORKFLOW
        if (this.options.workflow) {
            js_loader.add(js_dir + '/workflow.class.js');
        }

        // CONFIG DETECTION
        if (this.options.config) {
            js_loader.add(js_dir + '/PluginDetect.js');
        }

        // Player
        // Windows Media
        if (this.options.typePlayer.toLowerCase() == 'windowsmedia') {
            js_loader.add(js_dir + '/WmPlayer.js');
        }

        // LivePlayer
        if (this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'flash') {
            js_loader.add(js_dir + '/LivePlayer.js');
        }

        // SmartPlayer
        if ((this.options.typeLive.toLowerCase() == 'differe' || this.options.typeLive.toLowerCase() == 'fauxlive') && this.options.typePlayer.toLowerCase() == 'flash') {
            js_loader.add(js_dir + '/SmartPlayer.js');
            js_loader.add(js_dir + '/JavaScriptFlashGateway.js');
        }

        // JwPlayer
        if (this.options.typeLive.toLowerCase() == 'live_synchro' && this.options.typePlayer.toLowerCase() == 'flash') {
            js_loader.add(js_dir + '/swfobject.js');
            js_loader.add(js_dir + '/JwPlayer.js');
        }

        // SilverLight
        if (this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'silverlight') {
            // Je ne sais point quoi adder en js pour faire en sorte que ce bidule marche
            //js_loader.add(js_dir + '/swfobject.js');
            js_loader.add(js_dir + '/SilverLightPlayer.js');
        }


        if (this.options.accordion) {
            js_loader.add(js_dir + '/swfobject.js');
            js_loader.add('components/accordion/js/BSPanelContainerMain.js');
            js_loader.add('components/accordion/js/BSPanelContainerInjector.js');
        }

        // TIMED SLIDES
        if (this.options.timedSlides || (this.options.typePlayer.toLowerCase() == 'windowsmedia')) {
            js_loader.add(js_dir + '/TimedSlides.js');
        }

        if (this.options.timedFMSSlides) {
            js_loader.add(js_dir + '/TimedFMSSlides.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 = (this.options.timedFMSSlides) ? new TimedFMSSlides(element, timedSlidesOptions) : 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
    */
    _pingStatisticsServer: function(statsUrlBase, statId) {
        new JSonP(statsUrlBase + '/userPing.aspx', function() { }).send({
            statId: statId,
            fakeParam: new Date().getTime()
        });
    },

    initializeStatistics: function(projectName, statsOptions) {
        if (!this.options.noLimitBrainsonic) {
            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
            _this = this;
            new JSonP(statsOptions.statsUrlBase + '/userStart.aspx', function(data) {
                _this._pingStatisticsServer.periodical(statsOptions.interval, _this, [statsOptions.statsUrlBase, data.statId]);
                _this._pingStatisticsServer(statsOptions.statsUrlBase, data.statId);

            }).send({
                projectName: projectName,
                userId: statsOptions.userId,
                pingInterval: statsOptions.interval,
                page: statsOptions.page
            });
        }
    },

    initializeChat: function(liveId, chatOptions) {

        chatOptions = $merge(this.defaultChatOptions, chatOptions);
        ChatLive = new ChatLive(liveId, chatOptions);

        /* To manage Automatic Connexion*/
        var login = chatOptions.login;
        if ($empty(login))
            login = this.bsUtils.getQueryVariable('login');
        if (ChatLive.automatic_connexion && login)
            ChatLive.connexionUser(login);
    },

    /** configure player options and initialize 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);
        }
        else if (this.options.typeLive.toLowerCase() == 'live' && this.options.typePlayer.toLowerCase() == 'silverlight') {
            return new SilverLightPlayer(container, playerOptions);
        }

    },

    initializeWorkflow: function(typePage, options) {
        if (!this.options.noLimitBrainsonic) {
            var workflow = new Workflow(typePage, $extend($pick(options, {}), { queryTokens: this.options.queryTokens }));
            workflow.run();
        }
    }
});

