import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
// https://github.com/JakeGinnivan/react-popout
// Same as node_modules/react-popout/lib/ReactPopout.jsx
// (Move here to build with react@0.15.x bacause react includes twice)

/*
The MIT License (MIT)

Copyright (c) 2015 Jake Ginnivan
*/
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { style } from 'typestyle';

var _CONTAINER_ID = Symbol('container_id');
/**
 * @class PopoutWindow
 */


var PopoutWindow =
/*#__PURE__*/
function (_React$Component) {
  _inherits(PopoutWindow, _React$Component);

  /**
   * @type {{title: *, url: *, onClosing: *, options: *, window: *, containerId: *}}
   */

  /**
   * @constructs PoppoutWindow
   * @param props
   */
  function PopoutWindow(props) {
    var _this;

    _classCallCheck(this, PopoutWindow);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(PopoutWindow).call(this, props));

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", {
      openedWindow: null
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "defaultOptions", {
      toolbar: 'no',
      location: 'no',
      directories: 'no',
      status: 'no',
      menubar: 'no',
      scrollbars: 'yes',
      resizable: 'yes',
      width: 500,
      height: 400,
      top: function top(o, w) {
        return (w.innerHeight - o.height) / 2 + w.screenY;
      },
      left: function left(o, w) {
        return (w.innerWidth - o.width) / 2 + w.screenX;
      }
    });

    _this[_CONTAINER_ID] = props.containerId || 'popout-content-container';
    _this.closeWindow = _this.closeWindow.bind(_assertThisInitialized(_assertThisInitialized(_this)));
    return _this;
  }
  /**
   * Override default id if we get given one
   * @param props
   */


  _createClass(PopoutWindow, [{
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(props) {
      props.containerId && (this[_CONTAINER_ID] = props.containerId);
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.closeWindow();
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this2 = this;

      var popoutWindow, container;
      var options = Object.assign({}, this.defaultOptions, this.props.options),
          ownerWindow = this.props.window || window,
          openedWindow = {
        update: function update(newComponent) {
          container && ReactDOM.render(newComponent, container);
        },
        close: function close() {
          popoutWindow && popoutWindow.close();
        }
      };

      if (!ownerWindow) {
        // If we have no owner windows, bail. Likely server side render
        return;
      }

      var createOptions = function createOptions() {
        var ret = [];

        for (var key in options) {
          options.hasOwnProperty(key) && ret.push(key + '=' + (typeof options[key] === 'function' ? options[key].call(_this2, options, ownerWindow) : options[key]));
        }

        return ret.join(',');
      };

      popoutWindow = ownerWindow.open(this.props.url || 'about:blank', this.props.title, createOptions());

      popoutWindow.onbeforeunload = function () {
        container && ReactDOM.unmountComponentAtNode(container);

        _this2.windowClosing();
      }; // Close any open popouts when page unloads/refeshes


      ownerWindow.addEventListener('unload', this.closeWindow);

      var onloadHandler = function onloadHandler() {
        if (container) {
          if (popoutWindow.document.getElementById(_this2[_CONTAINER_ID])) return;
          ReactDOM.unmountComponentAtNode(container);
          container = null;
        }

        popoutWindow.document.title = _this2.props.title;
        container = popoutWindow.document.createElement('div');
        container.id = _this2[_CONTAINER_ID];
        popoutWindow.document.body.appendChild(container);
        ReactDOM.render(_this2.props.children, container);
      };

      popoutWindow.onload = onloadHandler; // Just in case that onload doesn't fire / has fired already, we call it manually if it's ready.

      popoutWindow.document.readyState === 'complete' && onloadHandler();
      this.setState({
        openedWindow: openedWindow
      });
    }
  }, {
    key: "closeWindow",
    value: function closeWindow() {
      this.state.openedWindow && this.state.openedWindow.close();
      (this.props.window || window).removeEventListener('unload', this.closeWindow);
    }
  }, {
    key: "windowClosing",
    value: function windowClosing() {
      this.props.onClosing && this.props.onClosing();
    }
    /**
     * Bubble changes
     */

  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate() {
      // For SSR we might get updated but there will be no openedWindow. Make sure openedWIndow exists before calling
      this.state.openedWindow && this.state.openedWindow.update(this.props.children);
    }
  }, {
    key: "render",
    value: function render() {
      return React.createElement("div", null);
    }
  }]);

  return PopoutWindow;
}(React.Component);

_defineProperty(PopoutWindow, "propTypes", {
  title: PropTypes.string.isRequired,
  url: PropTypes.string,
  onClosing: PropTypes.func,
  options: PropTypes.object,
  window: PropTypes.object,
  containerId: PropTypes.string,
  children: PropTypes.element
});

export { PopoutWindow as default };