text: /**
   * Bitrix UI
   * Social Video Vue component
   *
   * @package bitrix
   * @subpackage ui
   * @copyright 2001-2021 Bitrix
   */
  
  import "./socialvideo.css";
  import 'ui.vue.directives.lazyload';
  import 'main.polyfill.intersectionobserver';
  
  import {BitrixVue} from 'ui.vue';
  import {BaseEvent} from "main.core.events";
  
  const State = Object.freeze({
  	play: 'play',
  	pause: 'pause',
  	stop: 'stop',
  	none: 'none',
  });
  
  BitrixVue.component('bx-socialvideo',
  {
  	props:
  	{
  		id: { default: 0 },
  		src: { default: '' },
  		preview: { default: '' },
  		autoplay: { default: true },
  		containerClass: { default: null },
  		containerStyle: { default: null },
  		elementStyle: { default: null },
  		showControls: { default: true }
  	},
  	data()
  	{
  		return {
  			preload: "none",
  			previewLoaded: false,
  			loaded: false,
  			loading: false,
  			playAfterLoad: false,
  			enterFullscreen: false,
  			playBeforeMute: 2,
  			state: State.none,
  			progress: 0,
  			timeCurrent: 0,
  			timeTotal: 0,
  			muteFlag: true,
  		}
  	},
  	created()
  	{
  		if (!this.preview)
  		{
  			this.previewLoaded = true;
  			this.preload = 'metadata';
  		}
  
  		this.$Bitrix.eventEmitter.subscribe('ui:socialvideo:unmute', this.onUnmute);
  	},
  	mounted()
  	{
  		this.getObserver().observe(this.$refs.body);
  	},
  	beforeDestroy()
  	{
  		this.$Bitrix.eventEmitter.unsubscribe('ui:socialvideo:unmute', this.onUnmute);
  
  		this.getObserver().unobserve(this.$refs.body);
  	},
  	watch:
  	{
  		id(value)
  		{
  			this.registeredId = value;
  		},
  	},
  	methods:
  	{
  		loadFile(play = false)
  		{
  			if (this.loaded)
  			{
  				return true;
  			}
  
  			if (this.loading)
  			{
  				return true;
  			}
  
  			this.preload = 'auto';
  
  			this.loading = true;
  			this.playAfterLoad = play;
  
  			return true;
  		},
  		clickToButton(event)
  		{
  			if (!this.src)
  			{
  				return false;
  			}
  
  			if (this.state === State.play)
  			{
  				this.getObserver().unobserve(this.$refs.body);
  				this.pause();
  			}
  			else
  			{
  				this.play();
  			}
  
  			event.stopPropagation();
  		},
  		clickToMute()
  		{
  			if (!this.src)
  			{
  				return false;
  			}
  
  			if (!this.muteFlag)
  			{
  				this.mute();
  			}
  			else
  			{
  				this.unmute();
  			}
  
  			event.stopPropagation();
  		},
  		click(event)
  		{
  			if (this.autoPlayDisabled)
  			{
  				this.play();
  
  				event.stopPropagation();
  				return false;
  			}
  
  			if (this.isMobile)
  			{
  				if (this.source().webkitEnterFullscreen)
  				{
  					this.unmute();
  					this.enterFullscreen = true;
  					this.source().webkitEnterFullscreen();
  				}
  				else if (this.source().requestFullscreen)
  				{
  					this.unmute();
  					this.enterFullscreen = true;
  					this.source().requestFullscreen();
  				}
  				else
  				{
  					this.$emit('click', event);
  				}
  			}
  			else
  			{
  				this.$emit('click', event);
  			}
  
  			event.stopPropagation();
  		},
  		play(event)
  		{
  			if (!this.loaded)
  			{
  				this.loadFile(true);
  				return false;
  			}
  
  			if (!this.source())
  			{
  				return false;
  			}
  
  			this.source().play();
  		},
  		pause()
  		{
  			if (!this.source())
  			{
  				return false;
  			}
  
  			this.playAfterLoad = false;
  
  			this.source().pause();
  		},
  		stop()
  		{
  			if (!this.source())
  			{
  				return false;
  			}
  
  			this.state = State.stop;
  			this.source().pause();
  		},
  		mute()
  		{
  			if (!this.source())
  			{
  				return false;
  			}
  
  			this.muteFlag = true;
  			this.playBeforeMute = 2;
  			this.source().muted = true;
  		},
  		unmute()
  		{
  			if (!this.source())
  			{
  				return false;
  			}
  
  			this.muteFlag = false;
  			this.source().muted = false;
  
  			if (this.id > 0)
  			{
  				this.$Bitrix.eventEmitter.emit('ui:socialvideo:unmute', {initiator: this.id});
  			}
  		},
  		setProgress(percent, pixel = -1)
  		{
  			this.progress = percent;
  		},
  		formatTime(second)
  		{
  			second = Math.floor(second);
  
  			const hour = Math.floor(second/60/60);
  			if (hour > 0)
  			{
  				second -= hour*60*60;
  			}
  
  			const minute = Math.floor(second/60);
  			if (minute > 0)
  			{
  				second -= minute*60;
  			}
  
  			return (hour > 0? hour+':': '')
  					+ (hour > 0? minute.toString().padStart(2, "0")+':': minute+':')
  					+ second.toString().padStart(2, "0")
  		},
  		onUnmute(event: BaseEvent)
  		{
  			event = event.getData();
  
  			if (event.initiator === this.id)
  			{
  				return false;
  			}
  
  			this.mute();
  		},
  		source()
  		{
  			return this.$refs.source;
  		},
  		videoEventRouter(eventName, event)
  		{
  			if (
  				eventName === 'durationchange'
  				|| eventName === 'loadeddata'
  			)
  			{
  				if (!this.source())
  				{
  					return false;
  				}
  				this.timeTotal = this.source().duration;
  			}
  			else if (eventName === 'loadedmetadata')
  			{
  				if (!this.source())
  				{
  					return false;
  				}
  				this.timeTotal = this.source().duration;
  				this.loaded = true;
  
  				if (this.playAfterLoad)
  				{
  					this.play();
  				}
  			}
  			else if (
  				eventName === 'abort'
  				|| eventName === 'error'
  			)
  			{
  				console.error('BxSocialVideo: load failed', this.id, event);
  
  				this.loading = false;
  				this.state = State.none;
  				this.timeTotal = 0;
  				this.preload = 'none';
  			}
  			else if (
  				eventName === 'canplaythrough'
  			)
  			{
  				this.loading = false;
  				this.loaded = true;
  
  				if (this.playAfterLoad)
  				{
  					this.play();
  				}
  			}
  			else if (eventName === 'volumechange')
  			{
  				if (!this.source())
  				{
  					return false;
  				}
  				if (this.source().muted)
  				{
  					this.mute();
  				}
  				else
  				{
  					this.unmute();
  				}
  			}
  			else if (eventName === 'timeupdate')
  			{
  				if (!this.source())
  				{
  					return false;
  				}
  
  				this.timeCurrent = this.source().currentTime;
  
  				if (!this.muteFlag && !this.enterFullscreen && this.timeCurrent === 0)
  				{
  					if (this.playBeforeMute <= 0)
  					{
  						this.mute();
  					}
  
  					this.playBeforeMute -= 1;
  				}
  
  				this.setProgress(Math.round(100/this.timeTotal*this.timeCurrent));
  			}
  			else if (eventName === 'pause')
  			{
  				if (this.state !== State.stop)
  				{
  					this.state = State.pause;
  				}
  
  				if (this.enterFullscreen)
  				{
  					this.enterFullscreen = false;
  					this.mute();
  					this.play();
  				}
  			}
  			else if (eventName === 'play')
  			{
  				this.state = State.play;
  
  				if (this.state === State.stop)
  				{
  					this.progress = 0;
  					this.timeCurrent = 0;
  				}
  
  				if (this.enterFullscreen)
  				{
  					this.enterFullscreen = false;
  				}
  			}
  		},
  		getObserver()
  		{
  			if (this.observer)
  			{
  				return this.observer;
  			}
  
  			this.observer = new IntersectionObserver((entries, observer) =>
  			{
  				if (this.autoPlayDisabled)
  				{
  					return false;
  				}
  
  				entries.forEach((entry) =>
  				{
  					if (entry.isIntersecting)
  					{
  						this.play();
  					}
  					else
  					{
  						this.pause();
  					}
  				});
  			},{
  				threshold: [0, 1]
  			});
  
  			return this.observer;
  		},
  		lazyLoadCallback(element)
  		{
  			this.previewLoaded = element.state === 'success';
  		}
  	},
  	computed:
  	{
  		State: () => State,
  		autoPlayDisabled()
  		{
  			return !this.autoplay && this.state === State.none;
  		},
  		showStartButton()
  		{
  			return this.autoPlayDisabled && this.previewLoaded;
  		},
  		showInterface()
  		{
  			return this.previewLoaded && !this.showStartButton;
  		},
  		labelTime()
  		{
  			if (!this.loaded && !this.timeTotal)
  			{
  				return '--:--';
  			}
  
  			let time;
  			if (this.state === State.play)
  			{
  				time = this.timeTotal - this.timeCurrent;
  			}
  			else
  			{
  				time = this.timeTotal;
  			}
  
  			return this.formatTime(time);
  		},
  		isMobile()
  		{
  			const UA = navigator.userAgent.toLowerCase();
  
  			return (
  				UA.includes('android')
  				|| UA.includes('iphone')
  				|| UA.includes('ipad')
  				|| UA.includes('bitrixmobile')
  			)
  		},
  	},
  	template: `
  		<div :class="['ui-vue-socialvideo', containerClass, {
  				'ui-vue-socialvideo-mobile': isMobile,
  			}]" :style="containerStyle" @click="click">
  			<transition name="ui-vue-socialvideo-animation-fade">
  				<div v-if="showStartButton && showControls" class="ui-vue-socialvideo-button-start">
  					<span class="ui-vue-socialvideo-button-start-icon"></span>
  				</div>
  			</transition>
  			<transition name="ui-vue-socialvideo-animation-fade">
  				<div v-if="showInterface && showControls" class="ui-vue-socialvideo-overlay-container">
  					<div class="ui-vue-socialvideo-controls-container" @click="clickToButton">
  						<button :class="['ui-vue-socialvideo-control', {
  							'ui-vue-socialvideo-control-loader': loading,
  							'ui-vue-socialvideo-control-play': !loading && state !== State.play,
  							'ui-vue-socialvideo-control-pause': !loading && state === State.play,
  						}]"></button>
  					</div>
  					<div class="ui-vue-socialvideo-info-container" @click="clickToMute">
  						<span class="ui-vue-socialvideo-time-current">{{labelTime}}</span>
  						<span :class="['ui-vue-socialvideo-sound', {
  							'ui-vue-socialvideo-sound-on': state !== State.none && !muteFlag,
  							'ui-vue-socialvideo-sound-off': state !== State.none && muteFlag
  						}]"></span>
  					</div>
  				</div>
  			</transition>
  			<div v-if="!preview" class="ui-vue-socialvideo-background" :style="{position: (src? 'absolute': 'relative')}"></div>
  			<div class="ui-vue-socialvideo-container" ref="body">
  				<img 
  					v-bx-lazyload="{callback: lazyLoadCallback}"
  					data-lazyload-dont-hide
  					v-if="preview"
  					class="ui-vue-socialvideo-image-source"
  					:data-lazyload-src="preview"
  					:style="{position: (src? 'absolute': 'relative'), ...elementStyle}"
  				/>
  				<video 
  					v-if="src" :src="src" 
  					class="ui-vue-socialvideo-source" 
  					ref="source"
  					:preload="preload" 
  					playsinline
  					loop 
  					muted
  					:style="{opacity: (loaded? 1: 0), ...elementStyle}"
  					@abort="videoEventRouter('abort', $event)"
  					@error="videoEventRouter('error', $event)"
  					@suspend="videoEventRouter('suspend', $event)"
  					@canplay="videoEventRouter('canplay', $event)"
  					@canplaythrough="videoEventRouter('canplaythrough', $event)"
  					@durationchange="videoEventRouter('durationchange', $event)"
  					@loadeddata="videoEventRouter('loadeddata', $event)"
  					@loadedmetadata="videoEventRouter('loadedmetadata', $event)"
  					@volumechange="videoEventRouter('volumechange', $event)"
  					@timeupdate="videoEventRouter('timeupdate', $event)"
  					@play="videoEventRouter('play', $event)"
  					@playing="videoEventRouter('playing', $event)"
  					@pause="videoEventRouter('pause', $event)"
  				></video>
  			</div>
  		</div>	
  	`
  });
  