import ol_ext_element from '../element.js';
import ol_ext_input_Base from './Base.js'

/** Base class for input popup
 * @constructor
 * @extends {ol_ext_input_Base}
 * @fires change:color
 * @fires color
 * @param {*} options
 *  @param {string} [options.className]
 *  @param {ol.colorLike} [options.color] default color
 *  @param {Element} [options.input] input element, if non create one
 *  @param {Element} [options.parent] parent element, if create an input
 *  @param {string} [options.position='popup'] fixed | static | popup | inline (no popup)
 *  @param {boolean} [options.autoClose=true] close when click on color
 *  @param {boolean} [options.hidden=false] display the input
 */
var ol_ext_input_PopupBase = class olextinputPopupBase extends ol_ext_input_Base {
  constructor(options) {
    options = options || {};

    options.hidden = options.hidden !== false;
    super(options);

    this.set('autoClose', options.autoClose !== false);

    this.element = ol_ext_element.create('DIV', {
      className: ('ol-ext-popup-input ' + (options.className || '')).trim(),
      tabindex: 0,
      on: {
        keydown: function(e) {
          this._handleKey(e)
        }.bind(this)
      }
    });
    switch (options.position) {
      case 'inline': break;
      case 'static':
      case 'fixed': {
        this.element.classList.add('ol-popup');
        this.element.classList.add('ol-popup-fixed');
        this._fixed = (options.position === 'fixed');
        break;
      }
      default: {
        this.element.classList.add('ol-popup');
        break;
      }
    }

    var input = this.input;
    if (input.parentNode)
      input.parentNode.insertBefore(this.element, input);

    // Show on element click
    this.element.addEventListener('click', function () {
      if (this.isCollapsed())
        setTimeout(function () { this.collapse(false); }.bind(this));
    }.bind(this));

    this._elt = {};
    // Popup container
    this._elt.popup = ol_ext_element.create('DIV', { className: 'ol-popup', parent: this.element });
    this._elt.popup.addEventListener('click', function (e) { e.stopPropagation(); });

    // Hide on click outside
    var down = false;
    this._elt.popup.addEventListener('pointerdown', function () {
      down = true;
    });
    this._elt.popup.addEventListener('click', function () {
      down = false;
    });
    document.addEventListener('click', function () {
      if (!this.moving && !down)
        this.collapse(true);
      down = false;
    }.bind(this));
    // Hide on window resize
    window.addEventListener('resize', function () {
      this.collapse(true);
    }.bind(this));
  }
  /** Handle key pressed on input
   * @private
   */
  _handleKey(e) {
    switch (e.key) {
      case 'Enter':
      case ' ': 
      case 'Space': {
        e.stopPropagation();
        e.preventDefault();
        this.toggle();
        break;
      }
      case 'Escape': {
        e.stopPropagation();
        e.preventDefault();
        this.collapse(true);
        break;
      }
    }
  }
  /** show/hide color picker
   * @param {boolean} [b=false]
   */
  collapse(b) {
    if (b != this.isCollapsed()) {
      this.dispatchEvent({
        type: 'change:visible',
        visible: !this.isCollapsed()
      });
    }
    this.dispatchEvent({
      type: 'collapse',
      visible: !b
    });
    if (b) {
      this._elt.popup.classList.remove('ol-visible');
    } else {
      this._elt.popup.classList.add('ol-visible');
      if (this._fixed) {
        // Get fixed position
        var pos = this.element.getBoundingClientRect();
        var offset = ol_ext_element.getFixedOffset(this.element);
        pos = {
          bottom: pos.bottom - offset.top,
          left: pos.left - offset.left
        };
        // Test window overflow + recenter
        var dh = pos.bottom + this._elt.popup.offsetHeight + offset.top;
        if (dh > document.documentElement.clientHeight) {
          this._elt.popup.style.top = Math.max(document.documentElement.clientHeight - this._elt.popup.offsetHeight - offset.top, 0) + 'px';
        } else {
          this._elt.popup.style.top = pos.bottom + 'px';
        }
        var dw = pos.left + this._elt.popup.offsetWidth + offset.left;
        if (dw > document.documentElement.clientWidth) {
          this._elt.popup.style.left = Math.max(document.documentElement.clientWidth - this._elt.popup.offsetWidth - offset.left, 0) + 'px';
        } else {
          this._elt.popup.style.left = pos.left + 'px';
        }
      }
    }
  }
  /** Is the popup collapsed ?
   * @returns {boolean}
   */
  isCollapsed() {
    return !this._elt.popup.classList.contains('ol-visible');
  }
  /** Toggle the popup
   */
  toggle() {
    this.collapse(!this.isCollapsed());
  }
}

export default ol_ext_input_PopupBase
