import {Activator} from './activator';
import {App} from '../app/app';
import {Coordinates, CSS, hasPointerMoved, nativeRaf, pointerCoord, rafFrames} from '../../util/dom';
import {Config} from '../../config/config';


/**
 * @private
 */
export class RippleActivator extends Activator {

  constructor(app: App, config: Config) {
    super(app, config);
  }

  downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
    let self = this;
    if (self.disableActivated(ev)) {
      return;
    }

    // queue to have this element activated
    self._queue.push(activatableEle);

    nativeRaf(function() {
      for (var i = 0; i < self._queue.length; i++) {
        var queuedEle = self._queue[i];
        if (queuedEle && queuedEle.parentNode) {
          self._active.push(queuedEle);

          // DOM WRITE
          queuedEle.classList.add(self._css);

          var j = queuedEle.childElementCount;
          while (j--) {
            var rippleEle: any = queuedEle.children[j];
            if (rippleEle.tagName === 'ION-BUTTON-EFFECT') {
              // DOM WRITE
              rippleEle.style.left = '-9999px';
              rippleEle.style.opacity = '';
              rippleEle.style[CSS.transform] = 'scale(0.001) translateZ(0px)';
              rippleEle.style[CSS.transition] = '';

              // DOM READ
              var clientRect = activatableEle.getBoundingClientRect();
              rippleEle.$top = clientRect.top;
              rippleEle.$left = clientRect.left;
              rippleEle.$width = clientRect.width;
              rippleEle.$height = clientRect.height;
              break;
            }
          }
        }
      }
      self._queue = [];
    });
  }

  upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
    let self = this;

    if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
      let i = activatableEle.childElementCount;

      while (i--) {
        var rippleEle: any = activatableEle.children[i];
        if (rippleEle.tagName === 'ION-BUTTON-EFFECT') {
          var clientPointerX = (startCoord.x - rippleEle.$left);
          var clientPointerY = (startCoord.y - rippleEle.$top);

          var x = Math.max(Math.abs(rippleEle.$width - clientPointerX), clientPointerX) * 2;
          var y = Math.max(Math.abs(rippleEle.$height - clientPointerY), clientPointerY) * 2;
          var diameter = Math.min(Math.max(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), 64), 240);

          if (activatableEle.hasAttribute('ion-item')) {
            diameter = Math.min(diameter, 140);
          }

          var radius = Math.sqrt(rippleEle.$width + rippleEle.$height);

          var scaleTransitionDuration = Math.max(1600 * Math.sqrt(radius / TOUCH_DOWN_ACCEL) + 0.5, 260);
          var opacityTransitionDuration = scaleTransitionDuration * 0.7;
          var opacityTransitionDelay = scaleTransitionDuration - opacityTransitionDuration;

          // DOM WRITE
          rippleEle.style.width = rippleEle.style.height = diameter + 'px';
          rippleEle.style.marginTop = rippleEle.style.marginLeft = -(diameter / 2) + 'px';
          rippleEle.style.left = clientPointerX + 'px';
          rippleEle.style.top = clientPointerY + 'px';
          rippleEle.style.opacity = '0';
          rippleEle.style[CSS.transform] = 'scale(1) translateZ(0px)';
          rippleEle.style[CSS.transition] = 'transform ' +
                                            scaleTransitionDuration +
                                            'ms,opacity ' +
                                            opacityTransitionDuration +
                                            'ms ' +
                                            opacityTransitionDelay + 'ms';
        }
      }
    }

    super.upAction(ev, activatableEle, startCoord);
  }

  deactivate() {
    // remove the active class from all active elements
    let self = this;
    self._queue = [];

    rafFrames(2, function() {
      for (var i = 0; i < self._active.length; i++) {
        self._active[i].classList.remove(self._css);
      }
      self._active = [];
    });
  }

}

const TOUCH_DOWN_ACCEL = 300;

