(function () {

	"use strict";

	var debug = false;

	document.addEventListener('DOMContentLoaded', function () {
		var media = document.getElementById('media'),
			extrasOptions = {
				swfUri: '../js/FlashMediaElement.swf',
				debug: debug
			}

		// Initialisation du media principal
		if (media.getAttribute('data-sequencer') == 'true') {
			var childMediaCount = media.querySelectorAll('audio,video').length;
			mediaExtraSources(media.children, extrasOptions, function(mediaChild) {
				childMediaCount--;
				if (!childMediaCount) {
					var sources = { };
					for (var child = media.firstElementChild; child; child = child.nextElementSibling) {
						if (sources[child.currentSrc]) child = mediaWrapper(sources[child.currentSrc], child);
						else {
							sources[child.currentSrc] = child;
						}
					}
					// Tout les médias fils sont prêts, initialisation du sequenceur
					mediaSequencer(media, { debug: debug }, function() {
						webMedia(media);
					});

				}
			});
		}
		else {
			mediaExtraSources(media, extrasOptions, webMedia);
		}
	}, false);

	function webMedia (media) {
		altMediaMgr.initMedias();

		if(media.fSubs && media.fSubs.fBtnDisplayLangSub) {
			altMediaMgr.xSwitchClass(media.fSubs.fBtnDisplayLangSub,"display_off","display_on",true);
		}
		if(media.fTranscriptBtn) {
			altMediaMgr.xSwitchClass(media.fTranscriptBtn,"display_off","display_on",true);
		}
		if(media.fAltVideoBtn) {
			altMediaMgr.xSwitchClass(media.fAltVideoBtn,"display_off","display_on",true);
		}
		if(media.fAudioDescBtn) {
			altMediaMgr.xSwitchClass(media.fAudioDescBtn,"display_off","display_on",true);
		}

		// Variables pour les éléments HTML
		var segmentDataElement = document.getElementById('segmentsData'),
			timeRangesDataElement = document.getElementById('timeRangesData'),
			navDataElement = document.getElementById('navData'),
			rootDiv = document.getElementById('webMedia'),
			contentDiv = document.getElementById('content'),
			margin = document.getElementById('margin'),
			controller = document.getElementById('controller'),
			currentTimeLabel = document.getElementById('currentTimeLabel'),
			totalTimeLabel =  document.getElementById('totalTimeLabel'),
			timeCursor = document.getElementById('timeCursor'),
			seekBtn = document.getElementById('seekBtn'),
			tocDisplay = document.getElementById('tocDisplay'),
			tagsDisplay = document.getElementById('tagsDisplay'),
			timelineToc = document.getElementById('timelineToc'),
			timelineTags = document.getElementById('timelineTags'),
			nonContinuousPlayBtn = document.getElementById('nonContinuousPlayBtn'),
			playPauseBtn = document.getElementById('playPauseBtn'),
			muteBtn = document.getElementById('muteBtn'),
			volumeBtn = document.getElementById('volumeBtn'),
			volumeValue = document.getElementById('volumeValue'),
			previousBtn = document.getElementById('previousBtn'),
			nextBtn = document.getElementById('nextBtn'),
			mediaFull = document.getElementById('mediafull'),
		segmentLinks = document.querySelectorAll('#toc li.tocSegment > a, #timeline li.timeSegment > a'),
		videoPlayPauseBtn = document.getElementById('videoPlayPause');

		// Variables fonctionnelles
		var segmentsData = JSON.parse(segmentDataElement.text),
			timeRangesData = timeRangesDataElement && JSON.parse(timeRangesDataElement.text),
			navData = JSON.parse(navDataElement.text),
			lastUpdate = NaN,
			nonContinuousPlay = false,
			timeUpdateFromHash = false,
			currentTag = '',
			seekDragging = false,
			lastActive = null;

		// Initialisation des états
		segmentsData.forEach(updateState);
		if (timeRangesData) {
			timeRangesData.forEach(updateState);
			timeRangesData.some(updateContentState);
		}
	if (segmentsData.length == 1) {
		rootDiv.setAttribute('data-oneSegment', true);
		var timeSegment = controller.querySelector('li.timeSegment > a');
		timeSegment.tabIndex = -1;
	}
		updatePlayState();

		// Listeners de changement d'états
		media.addEventListener('timeupdate', timeupdate, false);
		media.addEventListener('volumechange', volumechange, false);
		[ 'loadedmetadata', 'playing', 'pause', 'ended', 'seeking', 'seeked' ].forEach (function(event) {
			media.addEventListener(event, updatePlayState, false);
		});
		media.addEventListener('durationchange', function() {
			totalTimeLabel.textContent = formatTime(media.duration);
		}, false);

		// Gestion du seekBtn si focus
		seekBtn.addEventListener('mousedown', function() {
			seekDragging = true;
		}, false);
		seekBtn.addEventListener('mouseup', function() {
			seekDragging = false;
			media.currentTime = seekBtn.value;
		}, false);
		seekBtn.addEventListener(navigator.userAgent.match(/Trident/) ? 'change' : 'input', function() {
			if (!seekDragging) media.currentTime = seekBtn.value;
		}, false);

		// Changement du currentTime
		function timeupdate(event) {
			if (event && event.target != media) return;
			if (lastActive) {
				lastActive.focus();
				lastActive = null;
			}

			var currentTime = media.currentTime,
				fromHash = timeUpdateFromHash;
			timeUpdateFromHash = false;

			// Mise à jour des états
			segmentsData.forEach(updateState);
			if (timeRangesData) {
				timeRangesData.forEach(updateState);
				timeRangesData.some(updateContentState);
			}

			// Mise à jour du temps courant et du curseur de lecture
			var formattedTime = formatTime(currentTime);
			currentTimeLabel.textContent = formattedTime;
			if (!seekDragging) {
				seekBtn.value = parseInt(currentTime, 10);
				seekBtn.setAttribute("aria-valuenow", currentTime);
				seekBtn.setAttribute("aria-valuetext", formattedTime);
			}

			for (var i=0; i<segmentsData.length; i++) {
				var segmentData = segmentsData[i];

				if (currentTime >= segmentData.start && currentTime < segmentData.end) {
					if (!fromHash && (lastUpdate < segmentData.start || lastUpdate > segmentData.end)) {
						// Arrivé sur un nouveau segment (ni par changement de hash, ni par drag du curseur de lecture)
						if (nonContinuousPlay && currentTag && segmentData.tags.indexOf(currentTag) == -1) {
							for (var j=i+1; j<segmentsData.length; j++) {
								if (segmentsData[j].tags.indexOf(currentTag) != -1) {
									lastUpdate = segmentsData[j].start;
									media.currentTime = lastUpdate;
									return;
								}
							}
							media.pause();
						}
					}

					// Mise à jour du hash
					if (window.location.hash.substr(1) != segmentData.target) {
						window.removeEventListener('hashchange', hashChanged, true);
						lastActive = document.activeElement;
						window.location.hash = '#' + segmentData.target;
						if (segmentsData.length != 1) Array.prototype.forEach.call(segmentLinks, function(link) {
							if (link.hash == '#' + segmentData.target) link.setAttribute('data-active', true);
							else link.removeAttribute('data-active');
						});
						window.setTimeout(function() {
							window.addEventListener('hashchange', hashChanged, true);
						}, 200)
					}

					break;
				}
			}
			lastUpdate = currentTime;
		}

		// Format le time en heures minutes secondes
		function formatTime(pTime) {
			pTime = Number(pTime);
			var h = Math.floor(pTime / 3600);
			var m = Math.floor(pTime % 3600 / 60);
			var s = Math.floor(pTime % 3600 % 60);
			return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
		}

		// Volumechange
		function volumechange(event) {
			volumeBtn.value = media.volume;
			volumeBtn.setAttribute("aria-valuenow", media.volume*100);
			volumeBtn.setAttribute("aria-valuetext", media.volume*100 + "%");
			volumeValue.style.width = media.volume*100+"%";
		}

		// Gestion du hash
		window.addEventListener('hashchange', hashChanged, true);
		media.addEventListener('loadeddata', function(event) {
			if (event.target == media) hashChanged()
		}, false);

		function hashChanged() {
			var target = window.location.hash.substr(1);
			if (target) {
				var targetParts = target.split(',');
				var state = null, time;
				targetParts.forEach(function(targetPart) {
					if (targetPart.indexOf('=') > 0) {
						var param = targetPart.split('=');
						if (param[0] == 'state') {
							state = param[1];
						} else if (param[0] == 't') {
							var timeParts = param[1].split(':');
							time = parseInt(timeParts[timeParts.length - 1]);
							if (timeParts.length > 1) {
								time += parseInt(timeParts[timeParts.length - 2]) * 60;
								if (targetParts.length > 2) {
									time += parseInt(timeParts[0]) * 3600;
								}
							}
						}
					} else {
						segmentsData.some(function (segmentData) {
							// TODO déplacer ce traitement sur le handler de timeupdate ?
							if (segmentData.target == targetPart) {
								Array.prototype.forEach.call(segmentLinks, function(link) {
									if (link.hash == '#' + targetPart) link.setAttribute('data-active', true);
									else link.removeAttribute('data-active');
								});
								time = segmentData.start;
								return true;
							}
						});
					}
				});

				if (time !== undefined) media.currentTime = time;

				if (state == 'play') media.play();
				else if (state == 'pause') media.pause();
			}
		}

		// Changement d'état
		function updateState (data) {
			var currentTime = media.currentTime;
			var div = document.getElementById(data.target);
			if (!div) return;
			if (currentTime < data.start) div.setAttribute("data-state", "idle");
			else if (currentTime >= data.start && currentTime < data.end) div.setAttribute("data-state", "active");
			else div.setAttribute("data-state", "done");
		}

		// Changement d'état de l'élément content (hasIllustr & notes & imgSolo)
		function updateContentState(data) {
			var currentTime = media.currentTime;
			if (currentTime >= data.start && currentTime < data.end) {
				if (data.hasContent) contentDiv.setAttribute('data-hasContent', true);
				else contentDiv.removeAttribute('data-hasContent');
				if (data.hasCplt) contentDiv.setAttribute('data-hasCplt', true);
				else contentDiv.removeAttribute('data-hasCplt');

				return true;
			}
			return false;
		}

		var seekingTimeout;
		// Changement d'état de lecture
		function updatePlayState (event) {
			if (event && event.target != media) return;
			seekBtn.max = media.duration;
			seekBtn.setAttribute("aria-valuemax", media.duration);
			if (media.seeking) {
				clearTimeout(seekingTimeout);
				var state = controller.getAttribute('data-state');
				if (!state) setSeekState();
				else if (state != 'seeking') {
					seekingTimeout = setTimeout(setSeekState, 500);
				}
			} else {
				clearTimeout(seekingTimeout);
				if (media.paused || media.ended) {
				rootDiv.setAttribute('data-state', 'paused');
					controller.setAttribute('data-state', 'paused');
					playPauseBtn.title = playPauseBtn.firstElementChild.textContent = "Lecture";
				videoPlayPauseBtn.title = videoPlayPauseBtn.firstElementChild.textContent = "Lecture";
				} else {
				rootDiv.setAttribute('data-state', 'playing');
					controller.setAttribute('data-state', 'playing');
					playPauseBtn.title = playPauseBtn.firstElementChild.textContent = "Pause";
				videoPlayPauseBtn.title = videoPlayPauseBtn.firstElementChild.textContent = "Pause";
				}
				previousBtn.disabled = false;
				nextBtn.disabled = false;
			}
		}

		function setSeekState() {
		rootDiv.setAttribute('data-state', 'seeking');
			controller.setAttribute('data-state', 'seeking');
			previousBtn.disabled = true;
			nextBtn.disabled = true;
		}

		function playPause() {
		videoPlayPauseBtn.setAttribute('hidden', 'true');
			if (media.paused || media.ended) media.play();
			else media.pause();
		}

		// Bouton de lecture
		playPauseBtn.addEventListener('click', playPause, false);

			// Lecture / pause si clic sur la video
	function videoPlayPause() {
		videoPlayPauseBtn.className = media.paused || media.ended ? 'play' : 'pause';
		if (!videoPlayPauseBtn.hasAttribute('hidden')) videoPlayPauseBtn.setAttribute('hidden', 'true');
		else videoPlayPauseBtn.removeAttribute('hidden');

		if (media.paused || media.ended) media.play();
		else media.pause();

		playPauseBtn.focus();
	}

	videoPlayPauseBtn.addEventListener('transitionend', function() {
		videoPlayPauseBtn.setAttribute('hidden', 'true');
	}, true);

	media.addEventListener('click', videoPlayPause, false);
			media.addEventListener('keydown', function(event) {
		if (event.keyCode == 13) videoPlayPause();
			}, false);
	videoPlayPauseBtn.addEventListener('click', videoPlayPause, false);



		// Bouton de mute
		muteBtn.addEventListener('click', function() {
			if (media.muted) {
				media.volume = 1;
				media.muted = false;
				this.removeAttribute('data-checked');
				this.title = this.firstElementChild.textContent = "Désactiver le son";
			} else {
				media.volume = 0;
				media.muted = true;
				this.setAttribute('data-checked', 'true');
				this.title = this.firstElementChild.textContent = "Activer le son";
			}
		}, false);

		// Bouton de volume
		volumeBtn.addEventListener('change', function() {
			media.volume = this.value;
			if(media.volume != 0) {
				media.muted = false;
				muteBtn.removeAttribute('data-checked');
				muteBtn.title = muteBtn.firstElementChild.textContent = "Désactiver le son";
			} else {
				media.muted = true;
				muteBtn.setAttribute('data-checked', 'true');
				muteBtn.title = muteBtn.firstElementChild.textContent = "Activer le son";
			}
		}, false);
		volumechange(this);

		// Boutons suivant/précédent
		if (navData.navLevel == 'timeRange') {
			previousBtn.addEventListener('click', goToPreviousTimeRange, false);
			nextBtn.addEventListener('click', goToNextTimeRange, false);
		} else {
			previousBtn.addEventListener('click', goToPreviousSegment, false);
			nextBtn.addEventListener('click', goToNextSegment, false);
		}

		function goToPreviousSegment () {
			var currentTime = media.currentTime;
			for (var i=0; i<segmentsData.length; i++) {
				var segmentData = segmentsData[i];
				if (currentTime >= segmentData.start && currentTime < segmentData.end)  {
					if (currentTime < segmentData.start + 0.5 && i > 0) media.currentTime = segmentsData[i-1].start;
					else media.currentTime = segmentData.start;
					break;
				}
			}
		}

		function goToPreviousTimeRange () {
			var currentTime = media.currentTime;
			for (var i=0; i<timeRangesData.length; i++) {
				var timeRangeData = timeRangesData[i];
				if (currentTime >= timeRangeData.start && currentTime < timeRangeData.end)  {
					if (currentTime < timeRangeData.start + 0.5 && i > 0) media.currentTime = timeRangesData[i-1].start;
					else media.currentTime = timeRangeData.start;
					break;
				}
			}
		}


		function goToNextSegment () {
			var currentTime = media.currentTime;
			for (var i=0; i<segmentsData.length; i++) {
				var segmentData = segmentsData[i];
				if (currentTime >= segmentData.start && currentTime < segmentData.end && i<segmentsData.length-1)  {
					if (currentTime > segmentData.end - 0.5 && i > 0) media.currentTime = segmentsData[i+1].end;
					else media.currentTime = segmentData.end;
					break;
				}
			}
		}

		function goToNextTimeRange () {
			var currentTime = media.currentTime;
			for (var i=0; i<timeRangesData.length; i++) {
				var timeRangeData = timeRangesData[i];
				if (currentTime >= timeRangeData.start && currentTime < timeRangeData.end && i<timeRangesData.length-1)  {
					if (currentTime > timeRangeData.end - 0.5 && i > 0) media.currentTime = timeRangesData[i+1].end;
					else media.currentTime = timeRangeData.end;
					break;
				}
			}
		}


		// Listeners clavier
		window.addEventListener('keydown', function(event) {
			// 	switch (event.keyCode) {
			// 	case 32: /* espace */
			// 	if (media.paused()) media.play();
			// 		else media.pause();
			// 	break;
			// case 37: /* gauche */
			// 	if (!media.seeking) {
			// 		if (event.shiftKey && !media.seeking) goToPreviousSegment();
			// 		else media.currentTime = media.currentTime - 20;
			// 	}
			// 	break;
			// case 39: /* droite */
			// 	if (!media.seeking) {
			// 		if (event.shiftKey) goToNextSegment();
			// 		else media.currentTime = media.currentTime + 20;
			// 	}
			// 	break;
			// 	}
		}, false);

		// Gestion des tags
		forEachQuerySelector('.tag', function (tagElement) {
			var tag = tagElement.getAttribute('data-tags');
			tagElement.addEventListener('click', function() {
				currentTag = currentTag == tag ? '' : tag;

				// Un attribut highlighted est posé sur tout les elements possédant un attribut data-tags contenant le tag séléctionné
				forEachQuerySelector('*[data-tags]', function (element) {
					var tags = (element.getAttribute('data-tags') || '').split(',');
					var hasTag = currentTag && tags.some(function(tag) { return tag == currentTag; });
					if (hasTag) element.setAttribute('data-highlighted', true);
					else element.removeAttribute('data-highlighted');
				});
			}, false);
		});

		// Bouton d'ouverture du sommaire à partir de la timeline
		if (tocDisplay && timelineToc) {
			var tocTagsClose = timelineToc.querySelector('button.tocTagsClose'),
				focusOut = timelineToc.querySelector('.focusOut'),
				focusOnCloseBtn = timelineToc.querySelector('.focusOnCloseBtn');
			/*
			 timelineToc.addEventListener('click', function(event) {
			 if(event.target.tagName.toLowerCase() != 'button') event.stopPropagation();
			 }, false);*/
			window.addEventListener('click', function (event) {
				if (event.button != 0) return;
				if (tocDisplay.contains(event.target) && !timelineToc.className) {
					timelineToc.className = 'active';
					setTimeout(function() {
						tocTagsClose.focus();
					}, 200);
					tocDisplay.title = tocDisplay.firstElementChild.textContent = "Cacher la table des matières";
				} else if (!timelineToc.contains(event.target) || event.target == tocTagsClose || event.target.tagName.toLowerCase() == 'a') {
					timelineToc.className = '';
					tocDisplay.title = tocDisplay.firstElementChild.textContent = "Afficher la table des matières";
				}
			}, true);
			// Boucle sur le focus
			focusOnCloseBtn.onfocus = function() { tocTagsClose.focus(); }
			focusOut.onclick = function() { tocDisplay.focus(); }
		}

		// Bouton d'ouverture des tags à partir de la timeline
		if (tagsDisplay && timelineTags) {
			var tocTagsClose = timelineTags.querySelector('button.tocTagsClose'),
				focusOut = timelineTags.querySelector('.focusOut'),
				focusOnCloseBtn = timelineTags.querySelector('.focusOnCloseBtn');
			timelineTags.addEventListener('click', function(event) {
				if (event.target.tagName.toLowerCase() != 'button') event.stopPropagation();
			}, false);
			window.addEventListener('click', function (event) {
				if (event.button != 0) return;
				if (tagsDisplay.contains(event.target) && !timelineTags.className) {
					timelineTags.className = 'active';
					setTimeout(function() {
						tocTagsClose.focus();
					}, 200);
					tagsDisplay.title = tagsDisplay.firstElementChild.textContent = "Cacher les mots clés";
				} else if (!timelineTags.contains(event.target) || event.target == tocTagsClose || event.target.tagName.toLowerCase() == 'a') {
					timelineTags.className = '';
					tagsDisplay.title = tagsDisplay.firstElementChild.textContent = "Afficher les mots clés";
				}
			});
			// Boucle sur le focus
			focusOnCloseBtn.onfocus = function() { tocTagsClose.focus(); }
			focusOut.onclick = function() { tocDisplay.focus(); }
		}

		document.addEventListener('keypress', function(event) {
			if (event.keyCode == 27 /* Escape */) {
				if (timelineToc) timelineToc.className = '';
				if (timelineTags) timelineTags.className = '';
			}
		}, false);

		// Bouton d'activation de la lecture bout à bout
		if (nonContinuousPlayBtn) {
			nonContinuousPlay = nonContinuousPlayBtn.hasAttribute('data-checked');
			nonContinuousPlayBtn.addEventListener('click', function () {
				nonContinuousPlay = !nonContinuousPlay;
				if (nonContinuousPlay) nonContinuousPlayBtn.setAttribute('data-checked', true);
				else nonContinuousPlayBtn.removeAttribute('data-checked');
			}, false);
		}

		// Gestion des buttons complement on
		forEachQuerySelector('button.compltOn', function (btnElement) {
			var btnTarget = btnElement.getAttribute('data-target');
			btnElement.addEventListener('click', function() {
				var divComplt = document.getElementById(btnTarget);
				divComplt.setAttribute('data-display', true);
			}, false);
		});

		// Gestion des buttons complement off
		forEachQuerySelector('button.compltOff', function (btnElement) {
			var btnTarget = btnElement.getAttribute('data-target');
			btnElement.addEventListener('click', function() {
				var divComplt = document.getElementById(btnTarget);
				divComplt.setAttribute('data-display', false);
			}, false);
		});

		var touchStart, tap;
		contentDiv.addEventListener('touchstart', function(event) {
			touchStart = event.changedTouches[0];
			touchStart.time = Date.now();
			document.body.removeEventListener('mousemove', activeMouse, false);
			document.body.removeEventListener('mousedown', activeMouse, false);
		}, false);

		contentDiv.addEventListener('touchend', function(event) {
			var touchEnd = event.changedTouches[0],
			distanceX = touchEnd.pageX - touchStart.pageX,
			distanceY = touchEnd.pageY - touchStart.pageY,
			elapsedTime = Date.now() - touchStart.time;
			if (Math.abs(distanceX) < 50 && Math.abs(distanceY) < 50) {
				// Tap
				var element = event.target;
				while (element && element.nodeType == 1) {
					if (element == controller || element == margin || element.localName == 'a' || element.localName == 'button' || element.localName == 'video') return;
					element = element.parentNode;
				}
				if (!document.body.hasAttribute('data-active')) {
					document.body.setAttribute('data-active', "true");
				} else {
					document.body.removeAttribute('data-active');
				}
			} else if (Math.abs(distanceX) >= 150 && elapsedTime <= 500 && Math.abs(distanceY) <= 100) {
				// Swipe
				if (navData.navLevel == 'timeRange') {
					if (distanceX > 0) goToPreviousTimeRange();
					else goToNextTimeRange();
				} else {
					if (distanceX > 0) goToPreviousSegment();
					else goToNextSegment();
				}

			}
		}, false);


		document.body.addEventListener('mousemove', activeMouse, false);
		document.body.addEventListener('mousedown', activeMouse, false);
		document.body.addEventListener('mouseleave', function(event) {
			document.body.removeAttribute('data-active');
		}, false);

		var activeMouseTimeout = 0;
		function activeMouse (event) {
			if (activeMouseTimeout) clearTimeout(activeMouseTimeout);
			document.body.setAttribute('data-active', "true");
			activeMouseTimeout = setTimeout(function() {
				document.body.removeAttribute('data-active');
			}, 2000);
		}

	}

	function forEachQuerySelector (selector, fn) {
		Array.prototype.forEach.call(document.querySelectorAll(selector), fn);
	}

// https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
	function toggleFullScreen(element) {
		if (!document.fullscreenElement &&
			!document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {
			if (element.requestFullscreen) {
				element.requestFullscreen();
			} else if (element.msRequestFullscreen) {
				element.msRequestFullscreen();
			} else if (element.mozRequestFullScreen) {
				element.mozRequestFullScreen();
			} else if (element.webkitRequestFullscreen) {
				element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
			}
		} else {
			if (document.exitFullscreen) {
				document.exitFullscreen();
			} else if (document.msExitFullscreen) {
				document.msExitFullscreen();
			} else if (document.mozCancelFullScreen) {
				document.mozCancelFullScreen();
			} else if (document.webkitExitFullscreen) {
				document.webkitExitFullscreen();
			}
		}
	}

})();
