var sphericalSet = false;

// Place this component the camera to add the focus animation
AFRAME.registerComponent('camera-focus', {
    schema: {
      focustime: {type: 'float', default: 1000},
      focusclass: {type: 'string', default: 'cantap'}
    },
    init: function () {
  
      var camera = this.el;
      var focusClass = this.data.focusclass;
      
      camera.setAttribute('orbit-controls-kitmod', {
        minAzimuthAngle: -Math.PI/2, 
        maxAzimuthAngle: Math.PI/2
      });
      camera.setAttribute('look-controls', {enabled: false, hmdEnabled: false, touchEnabled: true});
      camera.setAttribute('raycaster', {objects: '.'+focusClass});
      camera.setAttribute('cursor', {fuse: false, rayOrigin: 'mouse'});
      
      if(!camera.getAttribute('animation__focus'))
      {
        camera.setAttribute('animation__focus', {
          property: 'orbit-controls-kitmod.target',
          easing: 'easeInOutQuad', 
          autoplay: false, 
          dur: this.data.focustime
        });
      }
      
      var resetButtons = document.getElementsByClassName("reset-view");

      for(let resetButton of resetButtons)
      {
        if(resetButton != null)
        {
          var initFocus = camera.getAttribute('orbit-controls-kitmod').target;
          var initSpherical = new THREE.Spherical();
          // Automatically setting the reset position isn't working, so we're doing it manually for now.
          initSpherical.radius = 15.2;
          initSpherical.phi = 1.571;
          initSpherical.theta = 0;
    
          // This will set the reset position correctly, but it requires moving the camera first.
          // document.addEventListener('mousedown', function setSpherical() {
          //   if(!sphericalSet)
          //   {
          //     initSpherical = camera.getAttribute('orbit-controls-kitmod').spherical.clone();
          //     sphericalSet = true;
          //     document.removeEventListener('mousedown', setSpherical);
          //   }
          // });

          // A timeout is necessary when trying to set the position on load, since the scene 
          // takes a bit to finish loading
          // setTimeout(function setSpherical() {
          //   if(!sphericalSet)
          //   {
          //     var sphericalClone = camera.getAttribute('orbit-controls-kitmod').spherical.clone();
          //     initSpherical.radius = sphericalClone.radius;
          //     initSpherical.phi = sphericalClone.phi;
          //     initSpherical.theta = sphericalClone.theta;
          //     sphericalSet = true;
          //     console.log("Init Spherical Set: r = " + initSpherical.radius + ", phi = " + initSpherical.phi + ", theta = " + initSpherical.theta);
          //   }
          // }, 100);
    
          resetButton.addEventListener('click', function() {
            var currentTarget = camera.getAttribute('orbit-controls-kitmod').internalTarget;
            // console.log("Reset View: r = " + initSpherical.radius + ", phi = " + initSpherical.phi + ", theta = " + initSpherical.theta);
            camera.setAttribute('animation__focus', {
              from: currentTarget.x + " " + currentTarget.y + " " + currentTarget.z,
              to: initFocus,
            });
            camera.components.animation__focus.animation.play();
    
            camera.setAttribute('orbit-controls-kitmod', {
              rotateToSpeed: 0.05,
              // rotateTo: initSpherical.radius + " " + initSpherical.phi + " " + initSpherical.theta,
              rotateToSet: true
            });
            setTimeout(function() {
              camera.setAttribute('orbit-controls-kitmod', {rotateToSet: false});
            }, 1000)
          });
        }
      }
    }
  });

// Place this component on a mesh you want to focus on
AFRAME.registerComponent('focus-point', {
    schema: {
      name: {type: 'string', default: 'tp'},
      // ViewPosition is stored as a vector3 but is used as spherical coordinates: x = radius, y = phi, z = theta
      viewposition: {type: 'vec3'},
      focusposition: {type: 'vec3'},
      hoveranimtime: {type: 'float', default: 200},
      transitionspeed: {type: 'float', default: 0.05},
      visible: {type: 'bool', default: true}
    },
    init: function () {
  
      var focusPoint = this.el;
      var hoverAnimTime = this.data.hoveranimtime;
      var viewPosition = this.data.viewposition;
      var transitionSpeed = this.data.transitionspeed;
      var camera = document.getElementById('camera');
      var focusClass = camera.getAttribute('camera-focus').focusclass;
      var focusPosition = this.data.focusposition;
      var vecSum = focusPosition.x + focusPosition.y + focusPosition.z;
      if(vecSum == 0)
      {
        focusPosition = this.data.focusposition = focusPoint.object3D.position;
      }
      if(this.el.className != focusClass)
      {
        this.el.classList.add(focusClass);
      }
      if(!this.data.visible)
      {
        this.el.setAttribute('material', { transparent: true, opacity: 0.0 })
      }
  
      if(hoverAnimTime != 0)
      {
        // animate scale up on hover over
        focusPoint.setAttribute('animation__mouseenter', {
          property: 'radius',
          to: 0.3,
          startEvents: 'mouseenter',
          dur: hoverAnimTime,
          easing: 'easeOutElastic',
        })
    
        // animate scale down on hover off
        focusPoint.setAttribute('animation__mouseleave', {
          property: 'radius',
          to: 0.2,
          startEvents: 'mouseleave',
          dur: hoverAnimTime,
          easing: 'easeOutElastic',
        })
      }
      
      focusPoint.addEventListener('click', function(e) {
        camera.setAttribute('animation__focus', {
          to: focusPosition.x + " " + focusPosition.y + " " + focusPosition.z, 
        });
        camera.components.animation__focus.animation.play();
  
        camera.setAttribute('orbit-controls-kitmod', {
          rotateToSpeed: transitionSpeed,
          rotateTo: viewPosition.x + " " + viewPosition.y + " " + viewPosition.z,
          rotateToSet: true
        });
  
      })
    }
  });

  AFRAME.registerComponent('dblclick-focus', {
    schema: {
      focustime: {type: 'float', default: 0},
    },
    init: function () {
      var firstClick = false;
      var raycaster = null;
      var self = this.el;
      var camera = document.getElementById('camera');
      var focusTime = this.data.focustime;
      var focusClass = camera.getAttribute('camera-focus').focusclass;
  
      if(this.el.className != focusClass)
      {
        this.el.classList.add(focusClass);
      }
  
      this.el.addEventListener('raycaster-intersected', evt => {
        raycaster = evt.detail.el;
      });
      this.el.addEventListener('raycaster-intersected-cleared', evt => {
        raycaster = null;
      });
  
      this.el.addEventListener('mousedown', function(e) {
        // dblclick event doesn't work so we have to fake it with a bool and a timeout
        if(firstClick == true)
        {
          firstClick = false;
          if(focusTime == 0)
          {
            focusTime = camera.getAttribute('camera-focus').focustime;
          }
          var hitPoint = raycaster.components.raycaster.getIntersection(self).point;
          camera.setAttribute('animation__focus', {
            to: hitPoint.x + " " + hitPoint.y + " " + hitPoint.z, 
          });
          camera.components.animation__focus.animation.play();
        }
        else {
          firstClick = true;
          setTimeout(function() {
            firstClick = false;
          }, 200);
        }
      })
    }
  });