;(function($){

	//panoramaView
	jQuery.fn.panoramaViewer=function(prmUser){

		///////////////////////////////////////////////////////////////////////////////////////////
		// Var
		///////////////////////////////////////////////////////////////////////////////////////////

		//parameter
		const prmDef={
			src             : "",
			autoRotate      : false,
			autoRotateSpeed : 0.2,
			rotationX       : 0,
			rotationY       : 0,
			enableRotate    : true,
			enableGyro      : true,
			camera          : {
				fov  : 45,
				near : 1,
				far  : 2000
			}
		};
		const prm=$.extend(prmDef,prmUser);

		//canvas
		const myCanvas=$(this);
		var cv=new Canvas();
		function Canvas(){
			this._id  =myCanvas.attr("id");
			this._box =myCanvas.closest("#canvas_box");
			this._w   =this._box.width();
			this._h   =this._box.height();
		}
		myCanvas.attr({
			'width'  : cv._w,
			'height' : cv._h
		});

		//操作イベント
		var _start ='touchstart mousedown';
		var _move  ='touchmove mousemove';
		var _end   ='touchend mouseup';

		var isTap=false;
		var isDrag=false;
		var isTouch=('ontouchstart' in window);
		var isGyro=false;
		if((prm.enableGyro)&&(window.DeviceOrientationEvent)&&('ontouchstart' in window)){
			isGyro=true;
		}

		//回転用
		var onMouseDownMouseX;
		var onMouseDownMouseY;
		var lon=0;
		var lat=0;
		var onMouseDownLon;
		var onMouseDownLat;

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


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

		setCanvas();
		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();
			group=new THREE.Group();

			if(isGyro){
				camera=new THREE.PerspectiveCamera(prm.camera.fov,cv._w/cv._h,prm.camera.near,prm.camera.far);
				camera.position.set(0,0,0);
				controls=new THREE.DeviceOrientationControls(camera,true);
				controls.connect();

				if(prm.enableRotate){
					myCanvas.on(_start,function(e){
						e.preventDefault();
						isTap=true;
					});
					myCanvas.on(_move,function(e){
						e.preventDefault();
						if(isTap){
							isTap=false;
							isDrag=true;

							onMouseDownMouseX=(isTouch ? event.changedTouches[0].clientX : e.clientX);
							onMouseDownMouseY=(isTouch ? event.changedTouches[0].clientY : e.clientY);
							onMouseDownLon=lon;
							onMouseDownLat=lat;
						}else if(isDrag){
							var move_x=(isTouch ? event.changedTouches[0].clientX : e.clientX);
							var move_y=(isTouch ? event.changedTouches[0].clientY : e.clientY);
							lon=(move_x-onMouseDownMouseX)*0.005+onMouseDownLon;
							lat=(move_y-onMouseDownMouseY)*0.005+onMouseDownLat;
						}
					});
					myCanvas.on(_end,function(e){
						e.preventDefault();
						isTap=false;
						isDrag=false;
					});
				}

			}else{
				camera=new THREE.PerspectiveCamera(prm.camera.fov,cv._w/cv._h,prm.camera.near,prm.camera.far);
				camera.translateZ(0.01);
				camera.lookAt(new THREE.Vector3(0,0,0));
				controls=new THREE.OrbitControls(camera,renderer.domElement);
				if(prm.autoRotate){
					controls.autoRotate=true;
					controls.autoRotateSpeed=prm.autoRotateSpeed;
				}else{
					controls.autoRotate=false;
				}
				if(prm.enableRotate){
					controls.enableRotate=true;
					controls.rotateSpeed=0.1;
				}else{
					controls.enableRotate=false;
				}
				controls.enableDamping =true;
				controls.dampingFactor =0.1;
				controls.enableZoom    =false;
				controls.enablePan     =false;
			}

			//Geometry
			group.add(makeGeometry());

			var gmBase;
			var mtrBase;
			if(prm.src==""){
				gmBase=new THREE.SphereBufferGeometry(1000,60,40);
				gmBase.scale(-1,1,1);
				mtrBase=new THREE.MeshNormalMaterial();
			}else{
				gmBase=new THREE.SphereBufferGeometry(1000,60,40);
				gmBase.scale(-1,1,1);
				var texture=new THREE.TextureLoader().load(prm.src);
				mtrBase=new THREE.MeshBasicMaterial({
					map : texture
				});
			}

			var base=new THREE.Mesh(gmBase,mtrBase);
			//base.rotation.x=(prm.rotationX*Math.PI/180)*-1;
			base.rotation.y=(prm.rotationY*Math.PI/180)*-1;
			group.add(base);

			scene.add(group);
			runAnimate();

			function runAnimate(){
				if((isGyro)&&(isDrag)){
					group.rotation.y=lon;
					group.rotation.x=lat;
				}
				controls.update();
				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();
		}

	};

	function makeGeometry(){
		var group=new THREE.Group();

		const stop=1000;
		const start=stop*-1;
		const max=10;
		const move=stop*2/max;

		const mtr_x=new THREE.LineBasicMaterial({color : 0xff0000});
		const mtr_y=new THREE.LineBasicMaterial({color : 0x00ff00});
		const mtr_z=new THREE.LineBasicMaterial({color : 0x0000ff});
		for(i=0;i<=max;i++){
			now1=start+(move*i);
			for(j=0;j<=max;j++){
				now2=start+(move*j);

				var wkgmr_x=new THREE.Geometry();
				wkgmr_x.vertices.push(
					new THREE.Vector3(start,now2,now1),
					new THREE.Vector3(stop,now2,now1)
				);
				var wkline_x=new THREE.Line(wkgmr_x,mtr_x);
				group.add(wkline_x);

				var wkgmr_y=new THREE.Geometry();
				wkgmr_y.vertices.push(
					new THREE.Vector3(now2,start,now1),
					new THREE.Vector3(now2,stop,now1)
				);
				var wkline_y=new THREE.Line(wkgmr_y,mtr_y);
				group.add(wkline_y);

				var wkgmr_z=new THREE.Geometry();
				wkgmr_z.vertices.push(
					new THREE.Vector3(now2,now1,start),
					new THREE.Vector3(now2,now1,stop)
				);
				var wkline_z=new THREE.Line(wkgmr_z,mtr_z);
				group.add(wkline_z);
			}
		}

		return group;
	}

})(jQuery);