;(function($){

	//vrbk
	jQuery.fn.vrmvViewer=function(optUser){

		//options
		const optDef={
			src		: "",
			rotationY	: 0
		};
		const opt=$.extend(optDef,optUser);

		//canvas
		const myCanvas=$(this);
		var cv=new Canvas();
		function Canvas(){
			this._id		=myCanvas.attr("id");
			this._box		=myCanvas.closest(".canvas_box");
			this._loader	=myCanvas.closest(".canvas_box").find(".canvas_loader");
			this._start		=myCanvas.closest(".canvas_box").find(".canvas_start");

			this._w			=this._box.width();
			this._h			=this._box.height();
		}
		myCanvas.attr({
			'width'  : cv._w,
			'height' : cv._h
		});

		//three.js
		var renderer;
		var scene;
		var camera;
		var controls;

		//group
		var grpWorld;
		var grpBase;

		//video
		var video;
		var flag_video=false;
		var flag_loader=false;
		var video_totaltime="--:--:--";

		//ジャイロセンサー確認
		var isGyro=false;
		if((window.DeviceOrientationEvent)&&('ontouchstart' in window)){
			isGyro=true;
		}

		//PCなど非ジャイロ
		if(!isGyro){
			setCanvas();

		//一応ジャイロ持ちデバイス
		}else{
			//ジャイロ動作確認
			var resGyro=false;
			window.addEventListener("deviceorientation",doGyro,false);
			function doGyro(){
				resGyro=true;
				window.removeEventListener("deviceorientation",doGyro,false);
			}

			//数秒後に判定
			setTimeout(function(){
				//ジャイロが動いた
				if(resGyro){
					setCanvas();

				//ジャイロ持ってるくせに動かなかった
				}else{
					//iOS13+方式ならクリックイベントを要求
					if(typeof DeviceOrientationEvent.requestPermission==="function"){
						//ユーザアクションを得るための要素を表示
						cv._start.show();
						cv._start.on("click",function(){
							cv._start.hide();
							DeviceOrientationEvent.requestPermission().then(res => {
								//「動作と方向」が許可された
								if(res==="granted"){
									setCanvas();
								//「動作と方向」が許可されなかった
								}else{
									isGyro=false;
									setCanvas();
								}
							});
						});

					//iOS13+じゃない
					}else{
						//早くアップデートしてもらうのを祈りながら諦める
						isGyro=false;
						setCanvas();
					}
				}
			},300);
		}


		///////////////////////////////////////////////////////////////////////////////////////////
		// Canvas
		///////////////////////////////////////////////////////////////////////////////////////////

		function setCanvas(){
			if(!Detector.webgl){Detector.addGetWebGLMessage();}

			renderer=new THREE.WebGLRenderer({
				canvas    : document.querySelector('#'+cv._id),
				antialias : true,
				alpha     : true
			});

			renderer.setPixelRatio(window.devicePixelRatio);
			renderer.setSize(cv._w,cv._h);

			scene=new THREE.Scene();
			grpWorld=new THREE.Group();
			grpBase=new THREE.Group();

			//スマホなどジャイロセンサーが有効なときはDeviceOrientationControls
			if(isGyro){
				camera=new THREE.PerspectiveCamera(60,cv._w/cv._h,1,20000);
				camera.position.set(0,0,0.01);
				camera.lookAt(new THREE.Vector3(0,0,0));

				controls=new THREE.DeviceOrientationControls(camera);
				controls.connect();
				controls.update();

			//PCなどジャイロセンサーがない場合はOrbitControlsのみ
			}else{
				camera=new THREE.PerspectiveCamera(60,cv._w/cv._h,1,20000);
				camera.position.set(0,0,0.01);
				camera.lookAt(new THREE.Vector3(0,0,0));
				controls=new THREE.OrbitControls(camera,renderer.domElement);

				controls.autoRotate		=false;
				controls.enableRotate	=true;
				controls.rotateSpeed	=-0.05;
				controls.enableDamping	=true;
				controls.dampingFactor	=0.1;
				controls.enableZoom		=false;
				controls.enablePan		=false;
			}


			///////////////////////////////////////////////////////////////////////
			// 3Dオブジェクト配置
			///////////////////////////////////////////////////////////////////////

			//base
			var gmBase=new THREE.SphereBufferGeometry(1000,60,40);
			gmBase.scale(-1,1,1);
			var mtrBase;
			if(opt.src==""){
				mtrBase=new THREE.MeshNormalMaterial();
			}else{
				flag_video=true;
				video=document.createElement("video");

				if(Hls.isSupported()){
					var hls=new Hls();
					hls.loadSource(opt.src);
					hls.attachMedia(video);
					hls.on(Hls.Events.MANIFEST_PARSED,function(){
						video.play();
					});
				}else if(video.canPlayType("application/vnd.apple.mpegurl")){
					video.src=opt.src;
					video.addEventListener("canplay",function(){
						video.play();
					});
				}else{
					flag_video=false;
					mtrBase=new THREE.MeshNormalMaterial();
					alert("Failed to play video.");
				}

				if(flag_video){
					flag_loader=true;
					cv._loader.show();

					video.loop=true;
					video.muted=true;
					video.setAttribute("webkit-playsinline","webkit-playsinline");
					video.setAttribute("playsinline","playsinline");
					video.setAttribute("muted","muted");
					video.play();

					texture=new THREE.Texture(video);
					texture.minFilter=texture.magFilter=THREE.LinearFilter;
					texture.format=THREE.RGBFormat;
					texture.mapping=THREE.UVMapping;

					mtrBase=new THREE.MeshBasicMaterial({
						map : texture
					});

					var tm_totaltime=setInterval(function(){
						if(video.readyState>0){
							$("#btn_start").show();
							$("#btn_stop").show();
							video_totaltime=sec2timestr(video.duration);
							clearInterval(tm_totaltime);
						}
					},300);
				}
			}
			var base=new THREE.Mesh(gmBase,mtrBase);
			base.rotation.y=(opt.rotationY*Math.PI/180);
			grpBase.add(base);

			grpWorld.add(grpBase);
			scene.add(grpWorld);

			//runAnimate
			runAnimate();
			function runAnimate(){
				controls.update();

				if(flag_video){
					if(video.readyState>=video.HAVE_CURRENT_DATA){
						texture.needsUpdate=true;
					}

					//再生中
					if(!video.paused){
						if(flag_loader){
							if(video.currentTime>0){
								flag_loader=false;
								cv._loader.hide();
								$("#btn_start").text("PAUSE");
							}
						}

						set_playtime();
					}
				}

				renderer.render(scene,camera);
				requestAnimationFrame(runAnimate);
			}
		}


		///////////////////////////////////////////////////////////////////////////////////////////
		// Window Resize
		///////////////////////////////////////////////////////////////////////////////////////////

		var timerResize=false;
		$(window).on("resize",function(){
			if(timerResize!==false){
				clearTimeout(timerResize);
			}
			timerResize=setTimeout(function(){
				resizeCanvas();
			},500);
		});

		function resizeCanvas(){
			cv._w=cv._box.width();
			cv._h=cv._box.height();
			myCanvas.attr({
				'width'  : cv._w,
				'height' : cv._h
			});

			renderer.setPixelRatio(window.devicePixelRatio);
			renderer.setSize(cv._w,cv._h);
			camera.aspect=cv._w/cv._h;
			camera.updateProjectionMatrix();
		}


		///////////////////////////////////////////////////////////////////////////////////////////
		// 操作イベント
		///////////////////////////////////////////////////////////////////////////////////////////

		$("#btn_start").on("click",function(){
			if(flag_video){
				if(video.paused){
					video.play();
					$(this).text("PAUSE");
				}else{
					video.pause();
					$(this).text("PLAY");
				}
				set_playtime();
			}
		});

		$("#btn_stop").on("click",function(){
			if(flag_video){
				video.pause();
				video.currentTime=0;
				$("#btn_start").text("PLAY");
				set_playtime();
			}
		});

		function set_playtime(){
			if(flag_video){
				var playtime=sec2timestr(video.currentTime);
				$("#time_ctrl").text(playtime+"/"+video_totaltime);
			}
		}

	};

	function sec2timestr(sec){
		var time=Math.floor(sec);
		var s=time;
		var m=Math.floor((time/(1000*60))%60);
		var h=Math.floor((time/(1000*60*60))%24);

		if(s<10){
			s="0"+s;
		}
		if(m<10){
			m="0"+m;
		}
		if(h<10){
			h="0"+h;
		}

		return h+":"+m+":"+s;
	}

})(jQuery);