/**
 * @author m.donay@meta-fusion.com
 */
com.metafusion.PlayerApplication = function(){

    //-----// static constants //-----//
    
    com.metafusion.PlayerApplication.SESSION_ONDEMAND = 1;
    com.metafusion.PlayerApplication.SESSION_LIVE = 2;
    
    com.metafusion.PlayerApplication.LIVECOMMAND_REDIRECT = "refresh"; // was: "stop", "ovw", "overview"
    com.metafusion.PlayerApplication.LIVECOMMAND_RELOAD = "reload"; // was: "live", "golive", "goLive"
    com.metafusion.PlayerApplication.validFormats = [];
    com.metafusion.PlayerApplication.validFormats['wm'] = 1;
    com.metafusion.PlayerApplication.validFormats['real'] = 1;
    //com.metafusion.PlayerApplication.validFormats['flash'] = 1;
    
    //-----// public members //-----//
    
    com.metafusion.PlayerApplication.prototype.classname = "com.metafusion.PlayerApplication";
    com.metafusion.PlayerApplication.prototype.sessionType = com.metafusion.PlayerApplication.SESSION_ONDEMAND;
    com.metafusion.PlayerApplication.prototype.sessionData = null;
    com.metafusion.PlayerApplication.prototype.congressData = null;
    com.metafusion.PlayerApplication.prototype.currentSlideID = null;
    com.metafusion.PlayerApplication.prototype.currentSlideSrc = null;
    com.metafusion.PlayerApplication.prototype.playheadUpdateTimer = null;
    com.metafusion.PlayerApplication.prototype.refresh_sent = false;	
	com.metafusion.PlayerApplication.prototype.currentPlayPos = 0;
    //com.metafusion.PlayerApplication.prototype.lastEvent = "";
    
    
    /**
     * videossource/content stuff tranfered to Session.inc.js
     */
    // Real
    // "http://mfile.akamai.com/24893/rm/akamai.meta-fusion.com/metafusion/unfccc/cdm41_080730/080802_1545_CDM41_enc03_ondem.ram?obj=v0001"
    // Windowsmedia
    // "http://support.microsoft.com/support/mediaplayer/wmptest/samples/new/mediaexample.wmv"
    // "http://mfile.akamai.com/18609/wmv/akamai.meta-fusion.com/metafusion/dgppn/051123_t1_0900_enc5.asx?obj=v0001"
    // "http://yourstreaminghost.com/streamdemo/windowsplayer/windows-media-player-list.wmv.asx"
    // "http://www.mediacollege.com/video/format/windows-media/streaming/file-sequence.asx"
    
    com.metafusion.PlayerApplication.prototype.video = null;
    //Pointer to the Playerclass: com.meta-fusion.{WMPlayer, RealPlayer, FlashPlayer}
    com.metafusion.PlayerApplication.prototype.videotype = "unknownVideoType";
    //short string that identifies the format: {wm, real, flash}
    com.metafusion.PlayerApplication.prototype.videoformat = "unknownFormat";
    com.metafusion.PlayerApplication.prototype.videospeed = "unknownSpeed";
    
    com.metafusion.PlayerApplication.prototype.sliderMax = 1000;
    com.metafusion.PlayerApplication.prototype.videoWidth = 320;
    com.metafusion.PlayerApplication.prototype.videoHeight = 240;
    com.metafusion.PlayerApplication.prototype.slideWidth = 500;
    com.metafusion.PlayerApplication.prototype.slideHeight = 375;
    
    //only valid for RealPlayer (WMPlayer is more clever)
    //http://service.real.com/help/library/guides/extend/htmfiles/appd_gui.htm
    com.metafusion.PlayerApplication.prototype.showPlayerControls = "MuteVolume";
    com.metafusion.PlayerApplication.prototype.player = null;
    
    //-----// public functions //-----//
    
    /**
     * initializes the application
     * - sort stuff from the database
     * - make decisions regarding dynamic stuff
     * - set up agenda / slides
     */
    com.metafusion.PlayerApplication.prototype.init = function(_sessionType, _language, _format, _speed){
    
        switch (_sessionType) {
            case "ondemand":
                papp.sessionType = com.metafusion.PlayerApplication.SESSION_ONDEMAND;
                break;
            case "live":
                papp.sessionType = com.metafusion.PlayerApplication.SESSION_LIVE;
                break;
            default:
                papp.sessionType = com.metafusion.PlayerApplication.SESSION_ONDEMAND;
                break;
        }
        
        papp.congressData = new com.metafusion.Congress();
        papp.sessionData = new com.metafusion.Session();
        
        
        /**
         * @see init*.inc.php
         * @see Session.inc.js:Session()
         * @see PlayerApplication.js:showPlayer(...)
         * Malte: I'd prefer getting format and speed from what's available,
         * rather then trusting external parameters.
         * [malte] @var foundVideo: take the first video entry. or the last.
         * [malte] well, trust is relative. $_GET &format={wm, real, flash}
         */
        if (_format == null || _format == "" || !(_format in com.metafusion.PlayerApplication.validFormats)) { //asume nothing is set
            var foundVideo = false;
            var takeFirst = false;
            
            for (var lang in papp.sessionData.video) {
                for (var format in papp.sessionData.video[lang]) {
                    for (var speed in papp.sessionData.video[lang][format]) {
                        if (papp.sessionData.video[lang][format][speed].link != null) {
                            papp.videoformat = format;
                            papp.videospeed = speed;
                            foundVideo = true;
                        }
                        if (foundVideo && takeFirst) 
                            break;
                    }
                    if (foundVideo && takeFirst) 
                        break;
                }
                if (foundVideo && takeFirst) 
                    break;
            }
        }
        else 
            if (_speed == null || _speed == "") { // format seems to be set
                var foundVideo = false;
                var takeFirst = true;
                papp.videoformat = _format;
                
                for (var lang in papp.sessionData.video) {
                    for (var speed in papp.sessionData.video[lang][_format]) {
                        if (papp.sessionData.video[lang][_format][speed].link != null) {
                            papp.videospeed = speed;
                            foundVideo = true;
                        }
                        if (foundVideo && takeFirst) 
                            break;
                    }
                    if (foundVideo && takeFirst) 
                        break;
                }
            }
            else {
                papp.videoformat = _format;
                papp.videospeed = _speed;
            }
        
        switch (papp.videoformat) {
            case "wm":
                papp.videotype = com.metafusion.WMPlayer;
                break;
            case "real":
                papp.videotype = com.metafusion.RealPlayer;
                break;
            case "flash":
                papp.videotype = com.metafusion.FlashPlayer;
                break;
            default:
                error((typeof papp.videoformat) + "video format has not been set properly");
                break;
        }
        
        var count = 1;
        var playerTabs1 = '<ul>';
        var playerTabs2 = '';
        
        for (var lang in papp.sessionData.video) {
            playerTabs1 += '<li><a href="#lang' + count.toString() + '" onclick="papp.switchToLanguage(\'' + lang + '\');">' + lang + '</a></li>';
            playerTabs2 += '<div id="lang' + count.toString() + '" class="playerTab" style="height:' + papp.videoHeight + 'px;width:' + papp.videoWidth + 'px;">';
            playerTabs2 += '  <div id="' + lang + '" class="tmpPlayer" style="height:' + papp.videoHeight + 'px;width:' + papp.videoWidth + 'px;"></div>';
            playerTabs2 += '</div>';
            count++;
        }
        playerTabs1 += '</ul>';
        $('#playerTabs').html(playerTabs1 + playerTabs2);
        
    }
    
    /**
     * starts / continues the playback of the session (all media)
     */
    com.metafusion.PlayerApplication.prototype.play = function(){
        if (papp.player) {
            papp.player.play();
        }
    }
    
    /**
     * pauses the playback of the session (all media)
     */
    com.metafusion.PlayerApplication.prototype.pause = function(){
        if (papp.player && papp.sessionType == com.metafusion.PlayerApplication.SESSION_ONDEMAND) {
            papp.player.pause();
        }
    }
    
    /**
     * stops the playback of the session (all media)
     */
    com.metafusion.PlayerApplication.prototype.stop = function(){
        if (papp.player) {
            papp.player.stop();
        }
    }
    
    /**
     * TODO: implement this
     * jumps to the previous interesting time.
     * this is most likely a slide changing point, but may also be the start / end or some other point :-)
     */
    com.metafusion.PlayerApplication.prototype.prev = function(){
        if (papp.player && papp.sessionType == com.metafusion.PlayerApplication.SESSION_ONDEMAND) {
            log(this.classname + ": prev()");
            if (papp.sessionData.hasSlides) {
                var SlideObject = null;
                if (papp.currentSlideID == null) {
                    var momentaryPosition = papp.player.getPosition();
                    SlideObject = papp.sessionData.getPreviousSlideByTime(momentaryPosition);
                    papp.currentSlideID = SlideObject.slideID;
                }
                else {
                    SlideObject = papp.sessionData.getPreviousSlideBySlideID(papp.currentSlideID);
                    if (papp.currentSlideID == SlideObject.slideID) {
                        return; // nothing to be done
                    }
                    papp.currentSlideID = SlideObject.slideID;
                    
                }
                if (SlideObject != null) {
                    $('#slide').innerHTML = '<img src="' + SlideObject.src + '" onerror="imageNotFound(this, \'' + papp.congressData.slideBase + '404image.jpg\')" width="500" height="375" alt="' + SlideObject.descr + '" />';
                    $('#slideText').innerHTML = SlideObject.descr;
                    updateSlider(SlideObject.slidetime);
                    papp.player.setPosition(SlideObject.slidetime);
                }
            }
        }
    }
    
    /**
     * TODO: implement this
     * jumps to the next interesting time.
     * this is most likely a slide changing point, but may also be the start / end or some other point :-)
     */
    com.metafusion.PlayerApplication.prototype.next = function(){
        debug("NEXTCLICK");
        if (papp.player && papp.sessionType == com.metafusion.PlayerApplication.SESSION_ONDEMAND) {
            log(this.classname + ": next()");
            if (papp.sessionData.hasSlides) {
                var SlideObject = null;
                if (papp.currentSlideID == null) {
                    var momentaryPosition = papp.player.getPosition();
                    SlideObject = papp.sessionData.getNextSlideByTime(momentaryPosition);
                    
                    papp.currentSlideID = SlideObject.slideID;
                }
                else {
                    SlideObject = papp.sessionData.getNextSlideBySlideID(papp.currentSlideID);
                    if (papp.currentSlideID == SlideObject.slideID) {
                        return; // nothing to be done
                    }
                    papp.currentSlideID = SlideObject.slideID;
                    
                }
                if (SlideObject != null) {
                    //debug("SO.ID:" + SlideObject.slideID);
                    //debug("SlideObject.src:" + SlideObject.src);
                    //debug("SlideObject.descr:" + SlideObject.descr);
					//debug('two "imageNotFound(this, "' + papp.congressData.slideBase + '404image.jpg")"');
                   	$('#slide').innerHTML = '<img src="' + SlideObject.src + '" onerror="imageNotFound(this, \'' + papp.congressData.slideBase + '404image.jpg\')" width="500" height="375" alt="' + SlideObject.descr + '" />';
                    debug("Setting Slidetext to " + SlideObject.descr);
                    debug("inner: " + $('#slideText').innerHTML);
                    $('#slideText').innerHTML = SlideObject.descr;
                    if ($$('slideText')) {
                        $$('slideText').innerHTML = SlideObject.descr;
                    }
                    
                    updateSlider(SlideObject.slidetime);
                    papp.player.setPosition(SlideObject.slidetime);
                }
            }
        }
    }
    
    com.metafusion.PlayerApplication.prototype.showHeadlines = function(div_id_hl1, div_id_hl2, div_id_hl3){
        if ($$(div_id_hl1)) {
            $$(div_id_hl1).innerHTML = papp.congressData.bannertitel1;
        }
        if ($$(div_id_hl2)) {
            $$(div_id_hl2).innerHTML = papp.congressData.bannertitel2;
        }
        if ($$(div_id_hl3)) {
            $$(div_id_hl3).innerHTML = papp.congressData.bannertitel3;
        }
    }
    
    com.metafusion.PlayerApplication.prototype.fillWebPageTitle = function(){
		document.title = papp.congressData.bannertitel1 + " - " + papp.congressData.bannertitel2 + " - " +papp.congressData.bannertitel3;
    }
    
    /**
     * Inserts the infotext into the pageobject with the given ID
     * @param {Object} div_id ID of the div in which the Agenda will be inserted
     */
    com.metafusion.PlayerApplication.prototype.showInfotext = function(div_id){
        var output = '';
        output += '<dl>';
        output += '<dt> Organizer: </dt>';
        output += '<dd> ' + papp.sessionData.organisation + ' </dd>';
        output += '<dt> Type: </dt>';
        output += '<dd> ' + papp.sessionData.type + ' </dd>';
        output += '<dt> Time: </dt>';
        output += '<dd> ' + papp.sessionData.datetime.slice(0, papp.sessionData.datetime.length-3) + ' ' + papp.congressData.timezonename + ' </dd>';
        output += '<dt> Location: </dt>';
        output += '<dd> ' + papp.sessionData.location + ' </dd>';
        output += '</dl>';
        
        $$(div_id).innerHTML = output;
    }
    
    
    /**
     * Inserts the Agenda into the pageobject with the given ID
     * @param {Object} div_id ID of the div in which the Agenda will be inserted
     */
    com.metafusion.PlayerApplication.prototype.showAgenda = function(div_id){
        $$(div_id).innerHTML = papp.sessionData.getAgenda();
    }
    
    /**
     * Inserts the workprogramme into the pageobject with the given ID
     * @param {Object} div_id ID of the div in which the workprogramme will be inserted
     */
    com.metafusion.PlayerApplication.prototype.showWorkprogramme = function(div_id){
        $$(div_id).innerHTML = papp.sessionData.getWorkprogramme();
    }
    
    /**
     * Inserts the Subtitle into the pageobject with the given ID
     * For live sessionsthis will be the livetext, for undemand
     * TODO: what shall be displayed for ondemand sessions?
     * @param {Object} div_id ID of the div in which the Agenda will be inserted
     */
    com.metafusion.PlayerApplication.prototype.showSubtitle = function(tag_id){
        if (papp.sessionType == com.metafusion.PlayerApplication.SESSION_LIVE) {
        
            $$(tag_id).innerHTML = urldecode(papp.sessionData.livetext);
        }
        else {
            $$(tag_id).innerHTML = papp.sessionData.title;
        }
    }
	
	/**
	 * wrapper for switching and maintaining the playhead position
	 * @param {String} lang: id of the HTMLObject to contain the player
	 */
	com.metafusion.PlayerApplication.prototype.switchToLanguage = function(lang)
	{
		//papp.currentPlayPos=papp.player.getPosition();
		//[malte] bugfix 091104: player plugin rudiments stayed alive after switching
		papp.stop();
		papp.showPlayer(lang);
		//setTimeout("papp.player.setPosition(papp.currentPlayPos)", 1000);
	}
    
    /**
     * make sure you have set the parameters properly:
     * @param {String} target: id of the HTMLObject to contain the player
     * @param {String} language: {de, en, floor}
     */
    com.metafusion.PlayerApplication.prototype.showPlayer = function(_target){
    
        var errormsg = '';
        if (papp.videotype == null || (typeof papp.videotype != "function")) {
            errormsg = "No valid videotype defined";
        }
        if (papp.sessionData.video == null) {
            errormsg == '' ? errormsg : errormsg += "\n";
            errormsg += "No valid videosource defined";
        }
        if (errormsg != '') {
            error(this.classname + ': ' + errormsg);
            return;
        }
        if (this.player && $$(this.player.target)) {
            $$(this.player.target).innerHTML = "";
        }
        
        /**
 		* show the yery first available player
 		*/
        if (_target == null) {
            for (var firstTarget in papp.sessionData.video) {
                if (papp.sessionData.video[firstTarget][papp.videoformat][papp.videospeed].src != null) {
                    _target = firstTarget;
                    break;
                }
            }
        }
        
        this.player = new papp.videotype();
        //TODO: overthink papp.speed ...
        this.player.addVariable("src", papp.sessionData.video[_target][papp.videoformat][papp.videospeed].src);
        this.player.addVariable("width", papp.videoWidth);
        this.player.addVariable("height", papp.videoHeight);
        this.player.addVariable("showPlayerControls", papp.showPlayerControls);
        this.player.addVariable("stateChangeEventListener", player_playStateListener);
        this.player.addVariable("errorEventListener", player_errorListener);
        this.player.addVariable("scriptEventListener", player_scriptEventListener);
        this.player.addVariable("positionChangeEventListener", player_positionChangeEventListener);
        this.player.write(_target, this.sessionType);
		
		/**
		 * 091102_1747_malte hotfix for backend:workprogramme/agenda link compatibility
		 * document.MediaPlayer.SetPosition(0*1000);
		 */
		document.MediaPlayer = this.player;
        
        papp.enablePlayheadPosRetrieval(true);
    }
    
    /**
     * starts / stops the timer that retrieves the playhead position of the player
     * @param {Boolean} b_check: true = enable checking, false = disable
     */
    com.metafusion.PlayerApplication.prototype.enablePlayheadPosRetrieval = function(b_check){
        if (b_check == true) {
            clearInterval(papp.playheadUpdateTimer);
            papp.playheadUpdateTimer = setInterval(positionUpdate, 1000);
        }
        else {
            clearInterval(papp.playheadUpdateTimer);
        }
    }
    
    //-----// private functions //-----//
    
    //special event listener for com.metafusion.WMPlayer ... maybe
    
    /**
     * The Error events when the Windows Media Player control has an error condition.
     * @see http://msdn.microsoft.com/en-us/library/ms909939.aspx
     */
    function player_errorListener(){
        log(papp.player.retrieveErrorDescription());
    }
    
    /**
     * The ScriptCommand event occurs when a synchronized command or URL is received.
     * scType:url will open a new browser tab/window with the adress taken from Param
     * @param {String} scType: url, text, ...
     * @param {String} Param: value
     * @see http://msdn.microsoft.com/en-us/library/ms909953.aspx
     */
    function player_scriptEventListener(scType, Param){
        //evaluate only new events
        if (papp.lastEvent != Param) {
            papp.lastEvent = Param;
            switch (Param) {
                case com.metafusion.PlayerApplication.LIVECOMMAND_REDIRECT:
                    if (papp.refresh_sent == false) {
                        papp.refresh_sent = true;
                        if (papp.player != null) {
                            papp.player.stop();
							//set invisible: in IE WMPlayer is topmost and interferes with thickbox
							papp.player.setVisible(false);
							setTimeout('tb_show("This live session has ended!", "refresh.php?thisURL=" + papp.congressData.overviewURL + "?id_kongressmain=" + papp.congressData.congress_id + "&KeepThis=true&TB_iframe=true&modal=true&width=400&height=270", false)', 2*1000);
                        }
                    }
                    break;
                case com.metafusion.PlayerApplication.LIVECOMMAND_RELOAD:
                    // [malte] 30 seconds randomized page-reload
                    // @TODO this should reload text elements only
                    if (papp.refresh_sent == false) {
                        papp.refresh_sent = true;
                        var raw_random_number = Math.random();
                        var random_number = Math.round(raw_random_number * (30000));
                        setTimeout('window.location.reload()', random_number);
                    }
                    break;
                default: // must be a slide then, right? :-)
                    papp.refresh_sent = false;
                    
                    if (Param.indexOf('.jpg') == -1) {
                        Param += ".jpg";
                    }
                    $('#slide').html('<img src="' + papp.congressData.slideBase + Param + '" onerror="imageNotFound(this, \'' + papp.congressData.slideBase + '404image.jpg\');" width="500" height="375" alt="live-chart" />');
                    debug(scType + " : " + Param);
                    break;
            }
        }
    }
    
    /**
     * The PositionChange event occurs when the current playback position within the media item has been changed.
     * @param {Number} oldPosition
     * @param {Number} newPosition
     * @see http://msdn.microsoft.com/en-us/library/ms909951.aspx
     */
    function player_positionChangeEventListener(oldPosition, newPosition){
        //debug(oldPosition + " : " + newPosition);
    }
    
    /**
     * The PlayStateChange event occurs when the play state changes.
     * @param {Number} oldstate
     * @param {Number} newstate (undefined for WMP)
     */
    function player_playStateListener(oldstate, newstate){
        var state = -1;
        if (typeof newstate == "undefined") {
            state = oldstate;
        }
        else {
            state = newstate;
        }
        if (state != 3) {
            papp.enablePlayheadPosRetrieval(false);
            papp.player.showControls(true);
        }
        else {
            papp.enablePlayheadPosRetrieval(true);
            papp.player.showControls(false);
        }
    }
    
    /**
     * called by playheadUpdateTimer
     * get slideObject from slides at the given position
     */
    function positionUpdate(){
        if (papp.player) {
            var newPosition = papp.player.getPosition();
            var pos = 0;
            if (newPosition) { // && slides
                if (papp.player) { // shouldn't be neccessary but just in case... //malte asks: mystic code jumping? :-)
                    log(this.classname + ": player_positionChangeEventListener(oldPosition, newPosition)");
                    if (papp.sessionData.hasSlides) {
                        var SlideObject = null;
                        if (papp.currentSlideID == null) {
                            SlideObject = papp.sessionData.getSlideByTime(newPosition);
                            papp.currentSlideID = SlideObject.slideID;
                        }
                        else {
                            SlideObject = papp.sessionData.getSlideByTime(newPosition);
                            if (papp.currentSlideID != SlideObject.slideID) {
                                papp.currentSlideID = SlideObject.slideID;
                            }
                        }
                        if (SlideObject != null && papp.currentSlideSrc != SlideObject.src) {
                            papp.currentSlideSrc = SlideObject.src
                            var errorslide = "'" + papp.congressData.slideBase + '404image.jpg' + "'";
                            //$('#slide').html('<img src="' + SlideObject.src + '" width="' + papp.slideWidth + '" onerror="imageNotFound(this,'+errorslide+')" height="' + papp.slideHeight + '" alt="' + SlideObject.descr + '" />');
                            // [malte] did not work in IE
                            //document.slideimage.src = SlideObject.src;
                            $$('slideimage').src = SlideObject.src;
                            $('#slideText').html(SlideObject.descr);
                        }
                    }
                    if (papp.sessionData.hasTextFields) {
                        var TextfieldObject = papp.sessionData.getTextfieldByTime(newPosition);
                        if ($('#subtitleText').html() != TextfieldObject.tftext) {
                            $('#subtitleText').html(TextfieldObject.tftext);
                        }
                    }
                }
            }
            updateSlider(newPosition);
        }
        else {
            error(this.classname + ": positionUpdate couldn't access a valid player");
            
        }
    }
    
    /**
     * updates the Sliderposition and displaytime
     * @param {number} pos the new position of the slider
     */
    function updateSlider(pos){
        var videoLength = papp.player.getLength();
        var posSlider = (pos * papp.sliderMax) / videoLength;
        if ($('#slider')) {
            if (!posSlider) {
                posSlider = 0;
            }
            $('#slider').slider('option', 'value', posSlider);
            $('#position').val(timeString(pos));
        }
    }
}

papp = new com.metafusion.PlayerApplication();

