/**
 * MES Videoconsole
 * Copyright (c) 2007, MediaEvent Services GmbH & Co. KG
 * http://mediaeventservices.com
 */
 
/* Parameter */
var debug = false;
var forcePlayer; // = 'sl', = 'wm';
var enableSL = true;
var enableWM = true;
var offerSL = true;
var offerWM = true;
var enableLightboxFade = false;
var updateInterval = 200; /* in ms */

/* Controls */
var seekSlider;
var volSlider;
var slideFlowSlider;
var slideFlow;
var myLightbox;

var httpReq;
var xmlDoc;
var charts;

var numSlides;
var slideDragStartPos;
var numSlides;
var prevVol = 0.5;
var currentChart;
var updateTimer = 0;
var clipIdentifier;

var chartBoxPreloader;
var cfTarget;

var isPlaying;
var isStopped = true;

var scrollHandler = new ScrollHandler(handleWheel);

var enableSlideflow = true; /* per XML überschreibbar */
var enableCharts = true; /* per XML überschreibbar */

/* Templates */
var SEEK_TPL = {
	'b_vertical' : false, 'b_watch': false,	/* true für update während drag */ 'n_controlWidth': 150,
	'n_controlHeight': 7, 'n_sliderWidth': 14, 'n_sliderHeight': 7, 'n_pathLeft' : 0, 'n_pathTop' : 0,
	'n_pathLength' : 136, 'n_zIndex': 1
}

var SEEK_INIT = {
	'n_minValue' : 0, 'n_maxValue' : 100, 'n_value' : 0, 'n_step' : 1
}

var VOL_TPL = {
	'b_vertical' : false, 'b_watch': true,	/* update während drag */ 'n_controlWidth': 25, 'n_controlHeight': 7,
	'n_sliderWidth': 5, 'n_sliderHeight': 7, 'n_pathLeft' : 0, 'n_pathTop' : 0, 'n_pathLength' : 18, 'n_zIndex': 1
}

var VOL_INIT = {
	'n_minValue' : 0, 'n_maxValue' : 100, 'n_value' : 50, 'n_step' : 1
}

var SLIDEFLOW_TPL = {
	'b_vertical' : false, 'b_watch': true	/* update während drag */, 'n_controlWidth': 300, 'n_controlHeight': 7,
	'n_sliderWidth': 14, 'n_sliderHeight': 7, 'n_pathLeft' : 0, 'n_pathTop' : 0, 'n_pathLength' : 300-14, 'n_zIndex': 1
}

var SLIDEFLOW_INIT = {
	'n_minValue' : 0, 'n_maxValue' : 100, 'n_value' : 0, 'n_step' : 1
}

var SLIDEFLOW_DATA = {
	'imgWidthNormal': 100, 'imgWidthTilted': 75, 'imgHeight': 90, 'onCenterClick': handleSlideClick,
	'handleSlideMove': handleSlideMove, 'containerElement': null, 'numImages': null,
	'transparentImg': 'images/spacer.gif', 'cursorOpenHand': 'images/controls/openhand.cur', 'cursorClosedHand': 'images/controls/closedhand.cur'
}

function readXML(xmlDoc) {
	document.title = xmlDoc.getElementsByTagName("pagetitle")[0].childNodes[0].nodeValue;
	document.getElementById("title").innerHTML=xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
	document.getElementById("speaker").innerHTML=xmlDoc.getElementsByTagName("speaker")[0].childNodes[0].nodeValue;
	document.getElementById("company").innerHTML=xmlDoc.getElementsByTagName("company")[0].childNodes[0].nodeValue;

	numSlides = xmlDoc.getElementsByTagName("chart").length;
	charts = xmlDoc.getElementsByTagName("chart");
	mediaURL = xmlDoc.getElementsByTagName("url")[0].childNodes[0].nodeValue;

	if (xmlDoc.getElementsByTagName("identifier").length > 0)
		clipIdentifier = xmlDoc.getElementsByTagName("identifier")[0].childNodes[0].nodeValue;
	
	if (xmlDoc.getElementsByTagName("enableSlideflow").length > 0)
		enableSlideflow = ('true' == xmlDoc.getElementsByTagName("enableSlideflow")[0].childNodes[0].nodeValue);

	if (xmlDoc.getElementsByTagName("enableCharts").length > 0)
		enableCharts = ('true' == xmlDoc.getElementsByTagName("enableCharts")[0].childNodes[0].nodeValue);
		
	if (xmlDoc.getElementsByTagName("videoPosition").length > 0)
		videoPosition = xmlDoc.getElementsByTagName("videoPosition")[0].childNodes[0].nodeValue;
	else
		videoPosition = "right";

}

function initSlideFlow() {
	if (enableSlideflow) {
			SLIDEFLOW_DATA['containerElement'] = $('slideflow');
			SLIDEFLOW_DATA['numImages'] = numSlides;
			SLIDEFLOW_DATA['clipIdentifier'] = clipIdentifier;
			SLIDEFLOW_DATA['pathLeft'] = 'charts/' + clipIdentifier + '/left';
			SLIDEFLOW_DATA['pathCenter'] = 'charts/' + clipIdentifier + '/center';
			SLIDEFLOW_DATA['pathRight'] = 'charts/' + clipIdentifier + '/right';
			
			SLIDEFLOW_DATA['images'] = new Array();
		
							
			for (var i=0; i < numSlides; i++) {
				SLIDEFLOW_DATA['images'][i] = (i+1) + ".jpg";
			}
				
			slideFlow = new Slideflow(SLIDEFLOW_DATA);
		}
}

/* Initialization */
function playerInit() {

	/* Links mit target="_blank" umschreiben */
	createPopupLinks();
	
	/* Hover fix für IE5+6 */
	if (window.ieFixHover) {
		 $$('.button').each(ieFixHover);
		 $$('.sliderbutton').each(ieFixHover);
		 $$('input').each(ieFixHover);
	}

	/* Preload */
	preloadControls();
	
	/* XML */
	if (!httpReq) {
		$('installStatusUnsupported').setStyle({display: 'inline'});
		return;
	}
	
	if (!xmlDoc) {
		$('clipStatusNotFound').setStyle({display: 'inline'});
		return;
	}
	
	/* Left/right alignment */
	if (videoPosition == 'left') {
		$('media').className = 'leftBox';
		$('chart').className = 'rightBox';
		$('helpoverlay').className = 'videoLeft';
	}
	
	/* Controls */
	document.onkeydown = handleKeys;

	/* Slideflow */
	if (enableSlideflow) {
		slideFlowSlider.f_show();
		preloadImage(videoPosition == 'left' ? "images/controls/help-overlay-videoleft.png" : "images/controls/help-overlay.png");
	} else {
		$('container').addClassName('noslideflow');
		preloadImage(videoPosition == 'left' ? "images/controls/help-overlay-videoleft-noslideflow.png" : "images/controls/help-overlay-noslideflow.png");
	}

	/* Charts */
	showChart(1, false);

	/* Media Player */
	if (forcePlayer) {
		setupPlayer(forcePlayer);
		return;
	}

	var canSL = canHasSilverlightPlayer();

	if (enableSL && canSL && hasSilverlightPlayer()) {
		setupPlayer('sl');
		return;
	}

	var canWM = canHasWindowsMediaPlayer();

	if (enableWM && canWM && hasWindowsMediaPlayer()) {
		setupPlayer('wm');
		return;
	}

	if (offerSL && canSL) {
		$('installStatusChoiceSl').setStyle({display: 'inline'});
		SilverlightInplaceInstaller($('silverlightInplacePlaceholder'));
		$('installOptionAlternativeWmIe').setStyle({display: (canWM && isIE() ? 'inline' : 'none')});
		$('installOptionAlternativeWmFf').setStyle({display: (canWM && isFF() ? 'inline' : 'none')});
		$('installOptionAlternativeNoWm').setStyle({display: (canWM && (isIE() || isFF()) ? 'none' : 'inline')});
	}
	else if (offerWM && canWM) {
		$('installStatusChoiceWm').setStyle({display: 'inline'});
		$('installOptionWmIe').setStyle({display: (isIE() ? 'block' : 'none')});
		$('installOptionWmFf').setStyle({display: (isFF() ? 'block' : 'none')});
	}
	else {
		$('installStatusUnsupported').setStyle({display: 'inline'});
	}
}

function setupPlayer(mode) {
	if (mode == 'wm') {
		player = new WindowsMediaPlayer($('videowindow'));
	}
	else if (mode == 'sl') {
		player = new SilverlightPlayer($('videowindow'));
	}

	player.onPlayStateChanged = handlePlayStateChanged;

	swapPlayPause(false);
	swapMuted(false);
	$('videowindow').setStyle({display: 'block'});

	seekSlider.f_show();
    volSlider.f_show();

	if (!player.hasInitializationCallback)
		setupMovie();

	return false;
}

function setupMovie() {
	debugLog("Loading " + mediaURL);
	player.loadMovie(mediaURL);
}

var preloadImages = new Array();

function preloadImage(src) {
		var img = new Image; img.src = src;
		preloadImages.push(img);
}

function preloadControls() {
	var preloadSources =   ['play-hover.gif', 'pause-hover.gif', 'prev-hover.gif', 'next-hover.gif',
				'stop-hover.gif', 'magnifier-hover.gif', 'seekslider-hover.gif', 'volslider-hover.gif',
				'speaker-hover.gif', 'speaker_muted.gif', 'speaker_muted-hover.gif', 
				'lb-close.gif', 'lb-close-hover.gif', 'closedhand.cur', 'openhand.cur'];

	for (var i=0; i < preloadSources.length; i++)
		preloadImage('images/controls/' + preloadSources[i]);
}

function handlePlayStateChanged(newState) {
	debugLog("Player: " + newState);

	if (newState == 'Initialized') {
		setupMovie();
	} else if(newState == 'Playing') {
		isStopped = false;
	  	swapPlayPause(true);

	 	if (updateTimer == 0)
	 		updateTimer = window.setInterval("update()", updateInterval);
	} else if (newState == 'Stopped' && !isStopped /* SL fires twice */) {
		isStopped = true;
	    swapPlayPause(false);

		/* Falls Player gestoppt, stoppe Timer und setze Folie zurück */
	    window.clearInterval(updateTimer); updateTimer = 0;

	    /* Charts und Slideflow */
	    showChart(1, false);

		/* Seekslider */
		seekSlider.f_setValue(0, false, true /* non-user update */);
	} else if (newState == 'Paused') {
	   	/* Falls Player pausiert wird */
		swapPlayPause(false);

	   	/* Timer pausieren */
		window.clearInterval(updateTimer); updateTimer = 0;
	}
}

function swapPlayPause(playing) {
	if (isPlaying == playing)
		return;
		
	isPlaying = playing;

	$('playbutton').setStyle({display: playing ? 'none' : 'inline'});
	$('pausebutton').setStyle({display: playing ? 'inline' : 'none'});

	// lightbox controls
	if($('lb-play-button'))
    		$('lb-play-button').setStyle({display: playing ? 'none' : 'inline'});

  	if($('lb-pause-button'))
    		$('lb-pause-button').setStyle({display: playing ? 'inline' : 'none'});
}

function swapMuted(mute) {
	$('loudspeaker').setStyle({display: mute ? 'none' : 'inline'});
	$('loudspeakermuted').setStyle({display: mute ? 'inline' : 'none'});
}

function speakerClick(mute) {
	if (mute) {
		prevVol = player.getVolume();
		volSlider.f_setValue(0, false, false /* user update simulieren => setzt auch player volume */);
	} else
	{
		volSlider.f_setValue(prevVol * 100, false, false /* user update simulieren => setzt auch player volume */);
	}
}

function handlePositionSeek(pos) {
	if (slideFlowSlider)
		slideFlowSlider.clearActivityTimeout();
	if (slideFlow)
		slideFlow.clearActivityTimeout();

	player.pauseVideo();
	player.setPosition(pos * player.getDuration() / 100);
	player.startVideo();
}

function handleVolumeSeek(pos) {
	player.setVolume(pos / 100);
	if (pos < 5) {
		swapMuted(true);
	} else
	{
		swapMuted(false);
	}
}

function handleSlideSeek(pos) {
	slideFlow.disableMoveUpdate();
	slideFlow.glideToPerc(pos);
}

function handleSlideMove(pos) {
	if (slideFlowSlider)
		slideFlowSlider.f_setValue(pos, false, true /* kein update */);
}

function handleSlideClick(chartNumber) {
	showChart(chartNumber, true);
}

/* Slide control */

function getChartTime(chartNumber) {
	return tcToSec(charts[chartNumber-1].getElementsByTagName("timecode")[0].firstChild.nodeValue);
}

function chartBoxSwap(chartNumber) {
    /* Preload */
    var imgSrc = 'charts/'+ clipIdentifier + "/medium/" + chartNumber +'.jpg';
    var wasPreloading = (chartBoxPreloader != undefined);
    chartBoxPreloader = new Image;
    chartBoxPreloader.src = imgSrc;

    /* Aktuellen Chart ausblenden und neuen Chart anzeigen */
    if (!wasPreloading)
    	new Effect.Fade($('chartImg'), { duration:0.4, afterFinish: chartBoxFadeIn });
}

function chartBoxFadeIn() {
	fadeInTimeout = null;

	if (!chartBoxPreloader)
		return;
	else if (chartBoxPreloader.complete) {
	      new Effect.Appear($('chartImg'), {beforeSetup: function(effect) {
		effect.element.setOpacity(effect.options.from).show(); 	      
		effect.element.src = chartBoxPreloader.src;
		chartBoxPreloader = undefined;
	      }});
	} else if (!fadeInTimeout) {
		fadeInTimeout = window.setTimeout("chartBoxFadeIn()", 100);
	}
}

function lightboxSwap(chartNumber) {
	if (enableLightboxFade) {
		new Effect.Fade('lightboxImage', { duration:0.2, afterFinish: function() {
				new Effect.Appear('lightboxImage', {beforeStart: function() {
					document.getElementById("lightboxImage").setAttribute("src","charts/" + clipIdentifier + "/large/"+ chartNumber +".jpg");
				}});
			}});
	} else
		document.getElementById("lightboxImage").setAttribute("src","charts/" + clipIdentifier + "/large/"+ chartNumber +".jpg");
}

/**
 * Setzt Slides im Slideflow unter Berücksichtigung von Nutzeraktionen
 *
 * @param	newTarget	Neue Slide; optional. Ansonsten wird versucht, die aktuelle Slide zu setzen, falls dies
 * 						noch nicht geschehen ist.
 */
function slideFlowUpdate() {
	if (cfTarget == undefined)
		return;

    /* Slideflow: Nur aktualisieren, wenn Nutzer weder Slideflow-Slider noch Slideflow bedient */
    if (slideFlow && ((!slideFlowSlider.isActive() && !slideFlow.isActive()) || isStopped)) {
    	slideFlow.glideToSlide(cfTarget);
    	cfTarget = undefined;
    }
}

function showChart(chartNumber, seekVideo) {
	if (!enableCharts)
		return;

    chartNumber = parseDecimal(chartNumber);

    debugLog('showChart(' + chartNumber + ')');

    if (isNaN(chartNumber) || chartNumber <= 0 || chartNumber > charts.length)
	return;

    currentChart = chartNumber;

    // lightbox links erzeugen bzw. updaten
    lightbox_link = $("lightbox-link");
    lightbox_link.setAttribute("href","charts/" + clipIdentifier + "/large/" + currentChart +".jpg");
    lightbox_button = $("magnifierbutton");
		lightbox_button.setAttribute("href","charts/" + clipIdentifier + "/large/"+ currentChart +".jpg");

    /* Chart austauschen */
    chartBoxSwap(chartNumber);

    /* Slideflow target setzen */
    cfTarget = chartNumber;

    /* Und versuchen, darauf zu springen */
    slideFlowUpdate();

    /* Bilder in Lightbox wechseln, wenn Lightbox sichtbar */
    if($('lightbox')){
		if($('lightbox').style.display != "none"){
			lightboxSwap(chartNumber);
		}
    }

    /* Springe zu Position im Video */
    if (seekVideo && player) {
    	debugLog("Seeking to " + getChartTime(chartNumber));

		player.setPosition(getChartTime(chartNumber));
		player.startVideo();
    }

    // Nummer des aktuellen Charts ausgeben
    $('input_act_chart').value = currentChart;
		document.chart.act_chart.blur();
		
    // Anzahl Slides gesamt
    $('max_charts').innerHTML = numSlides;
}

/**
 * function update()
 *
 * Timer
 */
function update() {
    if(debug == 1) {
			document.debug.pos.value = player.getPosition();
			document.debug.actualchart.value = currentChart;
	}

	// Timecode überprüfen und ggf. aktuellen Chart ändern
	checkTime(player.getSafePosition());

    /* Slideflow immer aktualisieren */
    slideFlowUpdate();

    // Slider weiterbewegen
    seekSlider.f_setValue(player.getSafePosition() / player.getDuration() * 100, false, true /* non-user update */);
}

/**
 * function checkTime
 *
 * Vergleicht die aktuelle Position des Players (current_pos) mit
 * mit den Werten aus dem Timecode-Array und schaltet
 * die entsprechende Folie
 *
 */
function checkTime(current_pos) {
if (!enableCharts)
	return;

 	// aktuelle Position in Integer umwandeln
	var cur_pos = parseDecimal(current_pos);

	// Alle Elemente des XML-Objekts iterieren
	for (i = 1; i <= charts.length; i++) {
			// Vergleiche aktuelle Position des Videos mit Chart
			if (cur_pos >= getChartTime(i) && (i == charts.length || cur_pos < getChartTime(i+1))) {
					if (i != currentChart) {
						debugLog((current_pos) + "=>" + (cur_pos) + "==> changing to " + i);
						showChart(i, false);
					}
					break;
			}
  	}
}

function skipSlides(offset) {
	showChart(currentChart + parseInt(offset), true);
}

function prevSlide() {
if (!enableCharts)
	return;

	if (!player) {
		skipSlides(-1);
		return;
	}

	var current_pos = Math.floor(player.getSafePosition());
	var chartPos = getChartTime(currentChart);
	var tolerance = 5;

	if(current_pos >= chartPos + tolerance)
		skipSlides(0);
	else
		skipSlides(-1);
}

function debugBox() {
	if (debug) {
		document.write('<div id="debugbox">'
			+ '<h1>debug</h1>'
			+ '<form name="debug">'
			+ '<label>Position des Videos:</label><input name="pos" readonly="readonly" /><br />'
			+ '<label>Aktueller Chart:</label><input name="actualchart" readonly="readonly" /><br />'
			+ '<textarea name="log" readonly="readonly" cols="50" rows="5"></textarea><br />'
			+ '</form>'
			+ '</div>');

		new Draggable('debugbox',{snap:false,revert:false});
	}
}

function debugLog(message) {
	if (debug)
		document.debug.log.value = message + "\n" + document.debug.log.value;
}

function handleWheel(delta) {
	debugLog("glide " + delta);
	if (slideFlow)
		slideFlow.scroll(delta);
}

function handleKeys(evt) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (evt) {
    	debugLog("key " + evt.keyCode);
		switch (evt.keyCode) {
			case 40: /* down */
			case 39: /* right */
				skipSlides(1);
				return false;
				break;
			case 38: /* up */
			case 37: /* left */
				prevSlide();
				return false;
				break;
			case 32: /* space */
				var previousState = isPlaying;
				
				if (isPlaying)
					player.pauseVideo();
				else
					player.startVideo();
				
				/* Manually swap play & pause as player events are lagging when SL is hidden on Mac OS */
				swapPlayPause(!previousState);
				
				return false;
				break;
			break;
			case 27: /* escape */
				if (myLightbox)
					myLightbox.end();
				return false;
			break;
		 }
    }
}

function showHelp(show) {
	if (show) {
		$('helpoverlay').setOpacity(0);
		new Effect.Appear($('helpoverlay'), {beforeSetup: function(effect) {
			effect.element.setOpacity(0).show();
			hideFlash(); /* from lightbox */
			  }});
	} else {
		new Effect.Fade($('helpoverlay'), {afterFinish: function(effect) {
			showFlash(); /* from lightbox */
			  }});
	}
}
