text: import $ from '../core/renderer';
  import Widget from './widget/ui.widget';
  import domAdapter from '../core/dom_adapter';
  import eventsEngine from '../events/core/events_engine';
  import pointerEvents from '../events/pointer';
  import { getWindow } from '../core/utils/window';
  import { addNamespace } from '../events/utils';
  import { isString } from '../core/utils/type';
  
  const window = getWindow();
  
  const SPLITTER_CLASS = 'dx-splitter';
  const SPLITTER_WRAPPER_CLASS = `${SPLITTER_CLASS}-wrapper`;
  const SPLITTER_INACTIVE_CLASS = `${SPLITTER_CLASS}-inactive`;
  const SPLITTER_BORDER_CLASS = `${SPLITTER_CLASS}-border`;
  const SPLITTER_INITIAL_STATE_CLASS = `${SPLITTER_CLASS}-initial`;
  
  const STATE_DISABLED_CLASS = 'dx-state-disabled';
  
  const SPLITTER_MODULE_NAMESPACE = 'dxSplitterResizing';
  const SPLITTER_POINTER_DOWN_EVENT_NAME = addNamespace(pointerEvents.down, SPLITTER_MODULE_NAMESPACE);
  const SPLITTER_POINTER_MOVE_EVENT_NAME = addNamespace(pointerEvents.move, SPLITTER_MODULE_NAMESPACE);
  const SPLITTER_POINTER_UP_EVENT_NAME = addNamespace(pointerEvents.up, SPLITTER_MODULE_NAMESPACE);
  
  export default class SplitterControl extends Widget {
      _initMarkup() {
          this._$container = this.option('container');
          this._$leftElement = this.option('leftElement');
          this._$rightElement = this.option('rightElement');
          this._onApplyPanelSize = this._createActionByOption('onApplyPanelSize');
  
          this.$element()
              .addClass(SPLITTER_WRAPPER_CLASS)
              .addClass(SPLITTER_INITIAL_STATE_CLASS);
          this._$splitterBorder = $('<div>')
              .addClass(SPLITTER_BORDER_CLASS)
              .appendTo(this.$element());
          this._$splitter = $('<div>')
              .addClass(SPLITTER_CLASS)
              .addClass(SPLITTER_INACTIVE_CLASS)
              .appendTo(this._$splitterBorder);
      }
  
      _render() {
          super._render();
  
          this._detachEventHandlers();
          this._attachEventHandlers();
      }
  
      _clean() {
          this._detachEventHandlers();
          super._clean();
      }
  
      _attachEventHandlers() {
          const document = domAdapter.getDocument();
          eventsEngine.on(this._$splitterBorder, SPLITTER_POINTER_DOWN_EVENT_NAME, this._onMouseDownHandler.bind(this));
          eventsEngine.on(document, SPLITTER_POINTER_MOVE_EVENT_NAME, this._onMouseMoveHandler.bind(this));
          eventsEngine.on(document, SPLITTER_POINTER_UP_EVENT_NAME, this._onMouseUpHandler.bind(this));
      }
  
      _detachEventHandlers() {
          const document = domAdapter.getDocument();
          eventsEngine.off(this._$splitterBorder, SPLITTER_POINTER_DOWN_EVENT_NAME);
          eventsEngine.off(document, SPLITTER_POINTER_MOVE_EVENT_NAME);
          eventsEngine.off(document, SPLITTER_POINTER_UP_EVENT_NAME);
      }
  
      _dimensionChanged() {
          if(this._leftPanelPercentageWidth === undefined) {
              const leftElementWidth = this._$leftElement.get(0).clientWidth + this.getSplitterOffset();
              this._leftPanelPercentageWidth = this._convertLeftPanelWidthToPercentage(leftElementWidth);
          }
  
          const rightPanelWidth = 100 - this._leftPanelPercentageWidth;
          this._onApplyPanelSize({
              leftPanelWidth: this._leftPanelPercentageWidth + '%',
              rightPanelWidth: rightPanelWidth + '%'
          });
          this.setSplitterPositionLeft(this._$leftElement.get(0).clientWidth - this.getSplitterOffset());
      }
  
      _onMouseDownHandler(e) {
          e.preventDefault();
          this._offsetX = e.pageX - this._$splitterBorder.offset().left <= this._getSplitterBorderWidth()
              ? e.pageX - this._$splitterBorder.offset().left
              : 0;
          this._isSplitterActive = true;
          this._containerWidth = this._$container.get(0).clientWidth;
  
          this.$element().removeClass(SPLITTER_INITIAL_STATE_CLASS);
          this._$splitter.removeClass(SPLITTER_INACTIVE_CLASS);
  
          this.setSplitterPositionLeft(null, true);
      }
  
      _onMouseMoveHandler(e) {
          if(!this._isSplitterActive) {
              return;
          }
          this.setSplitterPositionLeft(this._getNewSplitterPositionLeft(e), true);
      }
  
      _onMouseUpHandler() {
          if(this._isSplitterActive) {
              this._$splitter.addClass(SPLITTER_INACTIVE_CLASS);
              this._isSplitterActive = false;
          }
      }
  
      _getNewSplitterPositionLeft(e) {
          let newSplitterPositionLeft = e.pageX - this._getContainerLeftOffset() - this._offsetX;
          newSplitterPositionLeft = Math.max(0 - this.getSplitterOffset(), newSplitterPositionLeft);
          newSplitterPositionLeft = Math.min(this._containerWidth - this.getSplitterOffset() - this._getSplitterWidth(), newSplitterPositionLeft);
          return newSplitterPositionLeft;
      }
  
      _getContainerLeftOffset() {
          let offsetLeft = this._$container.offset().left;
  
          if(window) {
              const style = window.getComputedStyle(this._$container.get(0));
              const paddingLeft = parseFloat(style['paddingLeft']) || 0;
              const borderLeft = parseFloat(style['borderLeftWidth']) || 0;
              offsetLeft += paddingLeft + borderLeft;
          }
  
          return offsetLeft;
      }
  
      _isDomElement(element) {
          return element && element.nodeType && element.nodeType === 1;
      }
  
      _isPercentValue(value) {
          return isString(value) && value.slice(-1) === '%';
      }
  
      getSplitterOffset() {
          return (this._getSplitterBorderWidth() - this._getSplitterWidth()) / 2;
      }
  
      _getSplitterWidth() {
          return this._$splitter.get(0).clientWidth;
      }
  
      _getSplitterBorderWidth() {
          return this._$splitterBorder.get(0).clientWidth;
      }
  
      toggleState(isActive) {
          const classAction = isActive ? 'removeClass' : 'addClass';
          this.$element()[classAction](STATE_DISABLED_CLASS);
          this._$splitter[classAction](STATE_DISABLED_CLASS);
      }
  
      isSplitterMoved() {
          return !this.$element().hasClass(SPLITTER_INITIAL_STATE_CLASS);
      }
  
      setSplitterPositionLeft(splitterPositionLeft, needUpdatePanels) {
          splitterPositionLeft = splitterPositionLeft || this._$leftElement.get(0).clientWidth - this.getSplitterOffset();
          this.$element().css('left', splitterPositionLeft);
          if(!needUpdatePanels) {
              return;
          }
          const leftPanelWidth = splitterPositionLeft + this.getSplitterOffset();
          const rightPanelWidth = this._containerWidth - leftPanelWidth;
          this._onApplyPanelSize({
              leftPanelWidth: leftPanelWidth,
              rightPanelWidth: rightPanelWidth
          });
          this._leftPanelPercentageWidth = this._convertLeftPanelWidthToPercentage(leftPanelWidth);
      }
  
      _optionChanged(args) {
          switch(args.name) {
              case 'initialLeftPanelWidth':
                  this._leftPanelPercentageWidth = this._convertLeftPanelWidthToPercentage(args.value);
                  this._dimensionChanged();
                  break;
              case 'leftElement':
                  this.repaint();
                  break;
              default:
                  super._optionChanged(args);
          }
      }
  
      _convertLeftPanelWidthToPercentage(leftPanelWidth) {
          return leftPanelWidth / this._$container.get(0).clientWidth * 100;
      }
  }
  