<!DOCTYPE html>
<html>
	<body>

		<div class="player">
			<canvas></canvas>
			<video src="https://threejs.org/examples/textures/MaryOculus.webm" loop autoplay crossOrigin="" controls="false" style="display: none;"></video>
		</div>
		<canvas id="texture-canvas" width="500" height="100" style="display: none;"></canvas>

		<label>Bug enabled: <input id="toggle-bug" type="checkbox"></label>

		<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>

		<script type="module">
			import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.module.js';
			import { WEBVR } from 'https://threejs.org/examples/jsm/vr/WebVR.js';

			// Just a hello world canvas that will be used as a texture
			const textureCanvas = $('#texture-canvas').get(0);
			const ctx = textureCanvas.getContext('2d');
			ctx.fillStyle = 'white';
			ctx.fillRect(0, 0, textureCanvas.width, textureCanvas.height);
			ctx.fillStyle = 'black';
			ctx.font = '30px Arial';
			ctx.fillText('Hello world', 20, 60);

			// Listen change on the checkbox to enable/disable the bug
			let bugEnabled = false;
			$('#toggle-bug').on('change', e => {
				bugEnabled = $(e.target).prop('checked');
			}).click();
			const _update = THREE.VideoTexture.prototype.update;
			THREE.VideoTexture.prototype.update = function() {
				if (bugEnabled)
					_update.call(this);
			};

			// The player class that contain a video and an "UI" from a canvas texture
			class Player {
				constructor() {
					const $player = $('div.player');
					const videoElement	= $player.find('video').get(0);

					this.scene		= new THREE.Scene();
					this.camera		= new THREE.PerspectiveCamera( 70, 0.5, .1, 1000 );
					this.renderer	= new THREE.WebGLRenderer({ canvas: $player.find('canvas').get(0) });

					this.scene.add(this.camera);
					this.scene.background = new THREE.Color( 'green' );

					this.renderer.setPixelRatio( window.devicePixelRatio );
					this.renderer.vr.enabled = true;

					this.addUI(textureCanvas);

					this.addEnterVRButton(videoElement);
					this.addVideo(videoElement);

					window.addEventListener('vrdisplayconnect', () => this.renderer.vr.setDevice(e.display));
					this.renderer.setAnimationLoop(() => this.renderer.render(this.scene, this.camera));
				}

				addEnterVRButton(videoElement) {
					const enterVRButton = $(document.body.appendChild(WEBVR.createButton(this.renderer)));
					console.log(videoElement, videoElement.play);
					enterVRButton.on('click', () => videoElement.play());
				}

				addVideo(videoElement) {
					const geometry		= new THREE.SphereGeometry(1000, 32, 32);
					const texture		= new THREE.VideoTexture(videoElement);

					geometry.scale( -1, 1, 1 );

					texture.minFilter	= THREE.LinearFilter;
					texture.magFilter	= THREE.LinearFilter;
					texture.wrapS		= THREE.ClampToEdgeWrapping;
					texture.wrapT		= THREE.ClampToEdgeWrapping;
					texture.format		= THREE.RGBFormat;

					this.scene.add(new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({map: texture})));
				}

				addUI(canvas) {
					const geometry = new THREE.PlaneGeometry(50,  10);
					const texture = new THREE.CanvasTexture(canvas);
					const material = new THREE.MeshBasicMaterial({ map: texture });
					const mesh = new THREE.Mesh(geometry, material);

					mesh.position.set(0, 0, -100);

					texture.minFilter = THREE.LinearFilter;
					texture.magFilter = THREE.LinearFilter;
					texture.wrapS = THREE.ClampToEdgeWrapping;
					texture.wrapT = THREE.ClampToEdgeWrapping;
					texture.format = THREE.RGBFormat;
					texture.generateMipmaps = false;

					this.scene.add(mesh);
				}
			}

			new Player();

		</script>
	</body>
</html>