// com.tts.initial.html5.animated.video
// HTML4 / HTML5: No differences
define( [
	"jquery",
	"./locals",
	"css!./component.css"
],
	function (
		jq,
		uiText
	) {

	"use strict";

	/**
	 * @constructor
	 */
	return function (context, metadata) {

		var videoElement = null,
			instance = null,
			id = metadata.parameters.get( "id", 1 ),
            controlType = metadata.parameters.get("video_control", "html5"),
            userAgent = navigator.userAgent.toLowerCase(),
            isIPad = userAgent.indexOf("ipad") !== -1,
        	isIPhone = userAgent.indexOf("iphone") !== -1,
        	isAndroid = userAgent.indexOf("android") !== -1,
	        canFireTouchstart = "ontouchstart" in document,
			canFireTouchend = "ontouchend" in document,
			canFireTouchmove = "ontouchmove" in document,
			canFireTouchcancel = "ontouchcancel" in document,
			supportsPointerEvents = window && window.PointerEvent,
        	startVideoEvent = canFireTouchstart ? "touchstart" : (supportsPointerEvents ? "pointerdown" : "mousedown"),
			stopVideoEvent = canFireTouchend && canFireTouchcancel ? "touchend touchcancel" : ( supportsPointerEvents ? "pointerup" : "mouseup" ),
			playEvent = "playing",
			pauseEvent = "pause",
			endEvent = "ended",
            moveEvent = canFireTouchmove ? "touchmove" : (supportsPointerEvents ? "pointermove mousemove" : "mousemove"),
            leaveEvent = canFireTouchend ? "touchend" : (supportsPointerEvents ? "pointerout" : "mouseout"),
	        randomizedUrlPostfix = Math.floor(Math.random() * 999999);

        function createVideo() {

			var videoFileUrl = getFileUrl("video_file"),
				shellElement = jq(context.getElement());

			if (isWebAccessPreview()) {
				videoFileUrl = videoFileUrl + "?preview=true&accessLatestReleased=false";
			}

            shellElement.css({
                "width": metadata.getWidth() + "px",
                "height": metadata.getHeight() + "px"
            });

            if( videoFileUrl.length === 0 ){
				return;
			}

			videoElement = createVideoElement();
            shellElement.append(videoElement);
            loadVideo( videoFileUrl );
			setAudioState();

			if(isAndroid) {
                // Create a layer on Android devices so that the user
                // can not start playback as long as not enough content is loaded:
                shellElement.append( createPlaybackShield() );
			}

			if ( controlType === "none" || controlType === "html5_autoplay") {
				getController.oncanplay = function () {
					getController().play();
				}
            }
		}

        function createVideoElement() {

            var videoElement = jq(document.createElement("video"))
                .addClass("sc-video")
				.attr( {
					"preload": "metadata",
					"id": "ttsVideo_" + id
				} );

            addListeners( videoElement );

            if (canFireTouchmove) {
                videoElement.on("touchmove", preventVerticalScrolling);
            }

            videoElement.on(moveEvent, function (e) {
                e.originalEvent.stopPropagation ? e.originalEvent.stopPropagation() : true;
                typeof e.originalEvent.cancelBubble !== "undefined" ? e.originalEvent.cancelBubble = true : true;
            });

            var posterFileUrl = getFileUrl("poster_file");
            if( posterFileUrl.length > 0 ){
                videoElement.attr("poster", posterFileUrl );
			}

			var subtitleFileUrl = getFileUrl( "subtitle_file" ),
				subtitleLanguage = metadata.stage.getContentLanguage(),
				subtitleCaption = getText( "subtitle_caption", "player.animated.video.label" ),
				subtitleInitialState = metadata.parameters.asBool( "subtitle_initial_state", false );

			if ( subtitleFileUrl.length > 0 ) {
				if ( subtitleInitialState ) {
					videoElement.append( '<track src="' + subtitleFileUrl + '" kind="subtitles" scrlang="' + subtitleLanguage + '" label="' + subtitleCaption + '" default>' );
				} else {
					videoElement.append( '<track src="' + subtitleFileUrl + '" kind="subtitles" scrlang="' + subtitleLanguage + '" label="' + subtitleCaption + '">' );
                }
			}

            if (isAndroid) {
                videoElement.attr("preload", "auto");
                videoElement.on("canplay", function() {
                    jq("#video" + randomizedUrlPostfix).remove();
                });
            }

            switch( controlType ) {
                case "none":
                    videoElement.attr("autoplay", "true");
					break;
				case "none_no_autoplay":
					break;
				case "html5":
					videoElement.attr( "controls", "true" );
					break;
				case "html5_autoplay":
                default:
					videoElement.attr( "controls", "true" );
					videoElement.attr( "autoplay", "true" );
			}

			videoElement
				.attr("controlslist", "nodownload")
				.attr("disablepictureinpicture", "true");

            return videoElement;
		}

		function isWebAccessPreview() {
			var currentWindowURL = window.location.href;

			return currentWindowURL.includes("accessLatestReleased=false") && currentWindowURL.includes("preview=true");
		}

		function getText( parameterName, defaultTextName ) {
			var paramValue = (metadata.parameters.get( parameterName, "" ) || "").trim();
			return ( paramValue.length > 0 ) ? paramValue : uiText.get( defaultTextName, metadata.stage.getContentLanguage() );
		}

        function loadVideo( videoFileUrl ) {
            videoElement.attr("src", videoFileUrl);
        }

        function createPlaybackShield(){
            return jq(document.createElement("div"))
                .css({
                    "position": "absolute",
                    "background-color": "#cccccc",
                    "opacity": 0.1,
                    "width": "100%",
                    "height": "100%"
                })
                .attr("id", "video" + randomizedUrlPostfix);
        }

        function getController() {
            var video = videoElement.get(0);
            return (video && video.controller !== undefined && video.controller !== null) ? video.controller : video;
        }

        function getFileUrl( paramName ) {

            var file = metadata.parameters.get( paramName, "" ),
                fileName,
				fileUrl;

            if( !file || typeof file !== "object" ) {
                return "";
            }

            fileName = file.fileName;
            if( !fileName || fileName === "" ) {
                return "";
            }

            fileUrl = context.stage.getSharedPath() + fileName;

            if (isAndroid) {
                fileUrl += "?" + randomizedUrlPostfix;
            }

            return fileUrl;
        }

		function setAudioState() {
			if ( !videoElement || videoElement.length === 0 ) {
				return;
			}
			videoElement.prop("muted", !context.stage.audio.isOn() );
		}

		function preventVerticalScrolling(e) {
			var result = isOnShadowedElement(e);
			if (result.onSlider || result.onTimeline) {
				lockNavigation();
				return true;
			}
			e.originalEvent.preventDefault ? e.originalEvent.preventDefault() : true;
		}

		function exitFullscreen() {
			if (document.fullscreenElement === videoElement.get(0)) {
				document.exitFullscreen();
			}
        }

		function switchPlayMode() {
			if (!videoElement || videoElement.length <= 0) {
				return;
			}

			var controller = getController();
			if (!controller) {
				return;
			}

			switch( controlType ) {
				case "none":
					if (controller.paused === false) {
						controller.pause();
					}
					else {
                        controller.play();
					}
					break;
				case "html5":
				default:
					if (isAndroid) {
						// Show or hide controls on android devices:
						videoElement.removeAttr("controls");
						videoElement.attr("controls", "controls");
					}
			}
		}

		function prepareForAuthoringMode() {
			if (!context.stage.isInAuthoringMode()) {
				return false;
			}
			jq(context.getElement())
				.text("Video")
				.css({
					"opacity": "0.15",
					"background-image": "url(\"" + context.getPath() + "invis.png\")",
					"text-align": "center",
					"line-height": metadata.getHeight() + "px",
					"font-size": "24px"
				});
			return true;
		}

		function removeVideo() {
			unlockNavigation();

			if( !videoElement || videoElement.length === 0 ) {
				return;
			}

			videoElement.each( function() {
				this.pause();
				delete this;
			});
			videoElement.remove();
			videoElement = null;
		}

		function lockNavigation() {
			if (context.stage.isInAuthoringMode() || !context.stage.trigger) {
				return;
			}
			context.stage.trigger.lock(metadata.getId());
		}

		function unlockNavigation() {
			if (context.stage.isInAuthoringMode() || !context.stage.trigger) {
				return;
			}
			context.stage.trigger.unlock(metadata.getId());
		}

		function isOnShadowedElement(e) {
			if (e && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches.length > 0) {
				var changedTouches = e.originalEvent.changedTouches[0],
					pseudoAttribute = changedTouches.target.getAttribute("pseudo"),
					pseudoAttributeLower;
				if (typeof pseudoAttribute === "string") {
					pseudoAttributeLower = pseudoAttribute.toLowerCase();
					if (pseudoAttributeLower.indexOf("webkit-media") !== -1) {
						// Don't lockNavigation if touched on the timeline slider
						return {
							onTimeline: (pseudoAttributeLower.indexOf("timeline") !== -1),
							onSlider: (pseudoAttributeLower.indexOf("slider") !== -1),
							onStartButton: (pseudoAttributeLower.indexOf("start-playback") !== -1),
							onWebkitMedia: true
						};
					}
				}
			}
			return {
				onTimeline: false,
				onSlider: false,
				onStartButton: false,
				onWebkitMedia: false
			};
		}

		function cancelEvent(e) {
			if (e && e.originalEvent.preventDefault) {
				e.originalEvent.preventDefault();
			}
			if (e && e.originalEvent.stopPropagation()) {
				e.originalEvent.stopPropagation();
			}
			return false;
		}

        function addListeners( videoElement ) {
            videoElement
                .on( startVideoEvent, onStartVideoElement )
                .on( stopVideoEvent, onEndVideoElement )
				.on( leaveEvent, onLeaveVideoElement )
				.on( playEvent, onPlay )
				.on( pauseEvent, onPause )
				.on( endEvent, onEnd );
        }

		function removeListeners( videoElement ) {
			if ( !videoElement || videoElement.length === 0 ) {
				return;
			}

			videoElement
				.off( startVideoEvent, onStartVideoElement )
				.off( stopVideoEvent, onEndVideoElement )
				.off( leaveEvent, onLeaveVideoElement )
				.off( playEvent, onPlay )
				.off( pauseEvent, onPause )
				.off( endEvent, onEnd );

			if (isIPad || isIPhone) {
				jq(document.body)
					.off("touchend", onTouchendDocument)
					.off("touchstart", onTouchstartDocument);
			}

			if (canFireTouchmove) {
				videoElement.off("touchmove", preventVerticalScrolling);
			}
		}

		function onStartVideoElement(e) {
			lockNavigation();

			videoElement.trigger("focus");

			if (isOnShadowedElement(e).onWebkitMedia && !(isIPad || isIPhone)) {
				return cancelEvent(e);
			}
		}

		function onEndVideoElement() {
			unlockNavigation();
			switchPlayMode();
		}

		function onLeaveVideoElement() {
			unlockNavigation();
		}

		function onTouchstartDocument() {
			unlockNavigation();
		}

		function onTouchendDocument() {
			unlockNavigation();
		}

		function onPlay( e ) {
			if ( e.target.id == "ttsVideo_" + id ) {
				setTimeout( function () {
					context.page.event.trigger( instance, "on_play" );
				}, 10 );
			}
		}

		function onPause( e ) {
			if ( e.target.id == "ttsVideo_" + id ) {
				var controller = getController();

				if ( controller.currentTime == 0 ) {
					setTimeout( function () {
						context.page.event.trigger( instance, "on_stop" );
					}, 10 );
				} else {
					setTimeout( function () {
						context.page.event.trigger( instance, "on_pause" );
					}, 10 );
				}
			}
		}

		function onEnd( e ) {
			if (e.target.id == "ttsVideo_" + id) {
				exitFullscreen();
				setTimeout( function () {
					context.page.event.trigger( instance, "on_end" );
				}, 10 );
			}
		}

		function onControlButtonPlay( data ) {
			if ( !videoElement || videoElement.length === 0 ) {
				return;
			}
			if ( data == id ) {
				var controller = getController();

				controller.play();
			}
		}

		function onControlButtonPause( data ) {
			if ( !videoElement || videoElement.length === 0 ) {
				return;
			}
			if ( data == id ) {
				var controller = getController();

				controller.pause();
			}
		}

		function onControlButtonStop( data ) {
			if ( !videoElement || videoElement.length === 0 ) {
				return;
			}
			if ( data == id ) {
				var controller = getController();

				if ( controller.paused ) {
					if ( controller.currentTime != 0 ) {
						setTimeout( function () {
							context.page.event.trigger( instance, "on_stop" );
						}, 10 );
					}
				} else {
					controller.pause();
				}
				controller.currentTime = 0;
			}
		}

		// revealing public API
		return {
			onLoading: function () {
				instance = this;

				if (!prepareForAuthoringMode()) {
                    context.stage.event.bindOnAudioControlChanged(this);
					context.page.event.bindOnEnter(this);
					context.page.event.bindOnExit( this );
					context.page.event.bind( this, "onControlButtonPlay" );
					context.page.event.bind( this, "onControlButtonPause" );
					context.page.event.bind( this, "onControlButtonStop" );
				}
			},

			onEnterPage: function () {

				createVideo();

				if (isIPad || isIPhone) {
					jq(document.body)
						.on("touchstart", onTouchstartDocument)
						.on("touchend", onTouchendDocument);
				}
			},

			onExitPage: function () {
				removeListeners( videoElement );
				removeVideo();
			},

			onAudioControlChanged: function () {
				setAudioState();
			},

			onControlButtonPlay: function ( event, id, data ) {
				onControlButtonPlay( data );
			},

			onControlButtonPause: function ( event, id, data ) {
				onControlButtonPause( data );
			},

			onControlButtonStop: function ( event, id, data ) {
				onControlButtonStop( data );
			}
		};
	};
});
