import Viewport from '../viewports/viewport';
import { parsePosition, getPosition } from '../utils/positions';
import { deepEqual } from '../utils/deep-equal';
import assert from '../utils/assert';
export default class View {
  constructor(props) {
    this.id = void 0;
    this.viewportInstance = void 0;
    this._x = void 0;
    this._y = void 0;
    this._width = void 0;
    this._height = void 0;
    this._padding = void 0;
    this.props = void 0;
    const {
      id,
      x = 0,
      y = 0,
      width = '100%',
      height = '100%',
      padding = null,
      viewportInstance
    } = props || {};
    assert(!viewportInstance || viewportInstance instanceof Viewport);
    this.viewportInstance = viewportInstance;
    this.id = id || this.constructor.displayName || 'view';
    this.props = { ...props,
      id: this.id
    };
    this._x = parsePosition(x);
    this._y = parsePosition(y);
    this._width = parsePosition(width);
    this._height = parsePosition(height);
    this._padding = padding && {
      left: parsePosition(padding.left || 0),
      right: parsePosition(padding.right || 0),
      top: parsePosition(padding.top || 0),
      bottom: parsePosition(padding.bottom || 0)
    };
    this.equals = this.equals.bind(this);
    Object.seal(this);
  }

  equals(view) {
    if (this === view) {
      return true;
    }

    if (this.viewportInstance) {
      return view.viewportInstance ? this.viewportInstance.equals(view.viewportInstance) : false;
    }

    return this.ViewportType === view.ViewportType && deepEqual(this.props, view.props, 2);
  }

  makeViewport({
    width,
    height,
    viewState
  }) {
    if (this.viewportInstance) {
      return this.viewportInstance;
    }

    viewState = this.filterViewState(viewState);
    const viewportDimensions = this.getDimensions({
      width,
      height
    });

    if (!viewportDimensions.height || !viewportDimensions.width) {
      return null;
    }

    return new this.ViewportType({ ...viewState,
      ...this.props,
      ...viewportDimensions
    });
  }

  getViewStateId() {
    const {
      viewState
    } = this.props;

    if (typeof viewState === 'string') {
      return viewState;
    }

    return (viewState === null || viewState === void 0 ? void 0 : viewState.id) || this.id;
  }

  filterViewState(viewState) {
    if (this.props.viewState && typeof this.props.viewState === 'object') {
      if (!this.props.viewState.id) {
        return this.props.viewState;
      }

      const newViewState = { ...viewState
      };

      for (const key in this.props.viewState) {
        if (key !== 'id') {
          newViewState[key] = this.props.viewState[key];
        }
      }

      return newViewState;
    }

    return viewState;
  }

  getDimensions({
    width,
    height
  }) {
    const dimensions = {
      x: getPosition(this._x, width),
      y: getPosition(this._y, height),
      width: getPosition(this._width, width),
      height: getPosition(this._height, height)
    };

    if (this._padding) {
      dimensions.padding = {
        left: getPosition(this._padding.left, width),
        top: getPosition(this._padding.top, height),
        right: getPosition(this._padding.right, width),
        bottom: getPosition(this._padding.bottom, height)
      };
    }

    return dimensions;
  }

  get controller() {
    const opts = this.props.controller;

    if (!opts) {
      return null;
    }

    if (opts === true) {
      return {
        type: this.ControllerType
      };
    }

    if (typeof opts === 'function') {
      return {
        type: opts
      };
    }

    return {
      type: this.ControllerType,
      ...opts
    };
  }

}
//# sourceMappingURL=view.js.map