# modules/dragElement.js

    import { addClass, hasClass, isiOSDevice, isMobileTablet, removeClass } from '../utils';

    // var scrollObj2 = null;
    let movementInterval;

    const dragElement = function (elmnt, draggableEl, overlayContainer, container, dragging, finishDragging, mobileTouch) {
      var pos1 = 0;
      var pos2 = 0;
      var pos3 = 0;
      var pos4 = 0;
      var isMobile = isMobileTablet();
      var isiOS = isiOSDevice();
      var isParentWindow = elmnt.parentNode.nodeName === 'BODY';
      var maxLeft = (isParentWindow ? window.innerWidth : container.offsetWidth);
      var maxTop = (isParentWindow ? window.innerHeight : container.offsetHeight);
      var touchStart; var moving = null;
      // scrollObj2 = query(".scroll-res");

      if (movementInterval) {
        clearTimeout(movementInterval);
      }

      var onWindowChange = function () {
        var isVertical = hasClass(elmnt, 'cl-vertical-mini');
        var maxLeft = (isParentWindow ? window.innerWidth : container.offsetWidth);
        var maxTop = (isParentWindow ? window.innerHeight : container.offsetHeight);
        var offsetMaxLeft = maxLeft - parseInt(elmnt.offsetWidth + (isVertical ? draggableEl.offsetWidth / 7 : draggableEl.offsetWidth / 1.6));
        var offsetMaxTop = maxTop - parseInt(elmnt.offsetHeight + (isVertical ? draggableEl.offsetHeight / 1.2 : draggableEl.offsetHeight / 4));
        var elTop = parseInt(elmnt.style.top);
        var elLeft = parseInt(elmnt.style.left);

        if (elTop > offsetMaxTop && offsetMaxTop > 5) {
          elmnt.style.top = offsetMaxTop + 'px';
        }
        if (elLeft > offsetMaxLeft && offsetMaxLeft > 5) {
          elmnt.style.left = offsetMaxLeft + 'px';
        }
      };

      if (isMobile) {
        /* listen to the touchMove event,
          every time it fires, grab the location
          of touch and assign it to box */

        var justATouch = false;
        draggableEl.addEventListener('touchstart', function (e) {
          justATouch = true;

          if (touchStart) clearTimeout(touchStart);

          maxLeft = (isParentWindow ? window.innerWidth : container.offsetWidth);
          maxTop = (isParentWindow ? window.innerHeight : container.offsetHeight);

          touchStart = setTimeout(function () {
            justATouch = false;
          }, 100);
        }, { passive: isiOS });

        draggableEl.addEventListener('touchmove', function (e) {
          e.preventDefault();
          pos3 = e.targetTouches[0].pageX;
          pos4 = e.targetTouches[0].pageY;
          // moving = new Date().getTime();

          elementDrag(e);
        }, { passive: isiOS });

        draggableEl.addEventListener('touchend', function (e) {
          // e.preventDefault();
          // current box position.
          closeDragElement(e);
          moving = null;

          if (justATouch && typeof mobileTouch === 'function') {
            mobileTouch();
          }
        }, { passive: isiOS });

        window.addEventListener('orientationchange', function (e) {
          onWindowChange();
        }, true);
      } else {
        // if present, the header is where you move the DIV from:
        draggableEl.onmousedown = dragMouseDown;

        window.addEventListener('resize', function (e) {
          onWindowChange();
        }, true);
      }

      function dragMouseDown (e) {
        e = e || window.event;
        e.preventDefault();

        maxLeft = (isParentWindow ? window.innerWidth : container.offsetWidth);
        maxTop = (isParentWindow ? window.innerHeight : container.offsetHeight);

        overlayContainer.style.display = 'block';

        // get the mouse cursor position at startup:
        pos3 = e.clientX;
        pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        // call a function whenever the cursor moves:
        document.onmousemove = elementDrag;
      }

      /**
       * Adds additional offset to max left and top based on orientation and container width (will be affected by CSS styling so needs to be adjusted accordingly)
       * - elmnt => is the main container that has the positioning applied to
       * - draggableEl => key element that is mean for dragging
       */
      var checkMaxMinRestraints = function (newTop, newLeft, offsetMaxLeft, offsetMaxTop) {
        var // minLeft = (isVertical ? elmnt.offsetWidth/4 : 0 ), // attempt to restrict the container to go out of bounds by a few pixels, needs some work
          minLeft = 0;
        var top = (newTop <= 0 ? 0 : newTop);
        var left = (newLeft <= minLeft ? minLeft : newLeft);

        if (left >= offsetMaxLeft) {
          left = offsetMaxLeft;
        }
        if (top >= offsetMaxTop) {
          top = offsetMaxTop;
        }

        return {
          top: top,
          left: left
        };
      };

      function elementDrag (e) {
        e = e || window.event;
        e.preventDefault();
        // calculate the new cursor position:
        var posX = (isMobile) ? e.targetTouches[0].pageX : e.clientX;
        var posY = (isMobile) ? e.targetTouches[0].pageY : e.clientY;
        var isVertical = hasClass(elmnt, 'cl-vertical-mini');
        var offsetMaxLeft = maxLeft - parseInt(elmnt.offsetWidth + (isVertical ? draggableEl.offsetWidth / 7 : draggableEl.offsetWidth / 1.6));
        var offsetMaxTop = maxTop - parseInt(elmnt.offsetHeight + (isVertical ? draggableEl.offsetHeight / 1.2 : draggableEl.offsetHeight / 4));

        pos1 = pos3 - posX;
        pos2 = pos4 - posY;
        pos3 = parseInt(posX);
        pos4 = parseInt(posY);
        moving = new Date().getTime();

        checkMovement();

        if (!hasClass(elmnt, 'cl-being-moved')) addClass(elmnt, 'cl-being-moved');

        var newTop = (isMobile) ? (posY - parseInt(draggableEl.offsetHeight / 2)) : (elmnt.offsetTop - pos2);
        var newLeft = (isMobile) ? (posX - parseInt(draggableEl.offsetWidth / 2)) : (elmnt.offsetLeft - pos1);
        var leftTopCheck = checkMaxMinRestraints(newTop, newLeft, offsetMaxLeft, offsetMaxTop); // set the element's new position:

        // scrollObj2.innerHTML = leftTopCheck.top + "-" + leftTopCheck.left + " : "+ newTop + "-" + newLeft + " : " + (posX < 0 || posY < 0 || posX > maxLeft || posY > maxTop) + "-" + (newTop > offsetMaxTop || newLeft > offsetMaxLeft);
        // scrollObj2.innerHTML = leftTopCheck.top + "-" + leftTopCheck.left + " : "+ newTop +"-"+ newLeft + " : " + (posX < 0 || posY < 0 || posX > maxLeft || posY > maxTop) + "-" + (newTop > offsetMaxTop || newLeft > offsetMaxLeft);

        if (posX < 0 || posY < 0 || posX > maxLeft || posY > maxTop) {
          closeDragElement(e);
        } else if (newTop > offsetMaxTop || newLeft > offsetMaxLeft) {
          closeDragElement(e);
        } else if (leftTopCheck.top > offsetMaxTop || leftTopCheck.left > offsetMaxLeft) {
          closeDragElement(e);
        } else {
          elmnt.style.top = leftTopCheck.top + 'px';
          elmnt.style.left = leftTopCheck.left + 'px';
        }

        if (typeof dragging === 'function') dragging(newTop, newLeft);
      }

      function closeDragElement (e) {
        overlayContainer.style.display = 'none';
        if (isMobile) {
          e.preventDefault();
        } else {
          // stop moving when mouse button is released:
          document.onmouseup = null;
          document.onmousemove = null;
        }
        moving = null;

        removeClass(elmnt, 'cl-being-moved');

        if (typeof finishDragging === 'function') finishDragging();
      }

      function checkMovement () {
        if (movementInterval) {
          clearTimeout(movementInterval);
        }

        movementInterval = setTimeout(function () {
          if (moving !== null && moving + 3000 < new Date().getTime() && !isMobile) {
            closeDragElement();
          } else if (moving !== null) {
            checkMovement();
          }
        }, 3000);
      }
    };

    export default dragElement;