'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _font = require('../font');

var _font2 = _interopRequireDefault(_font);

var _emoji = require('../utils/emoji');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Document = function () {
  function Document(root, props) {
    _classCallCheck(this, Document);

    this.root = root;
    this.props = props;
    this.children = [];
  }

  _createClass(Document, [{
    key: 'appendChild',
    value: function appendChild(child) {
      child.parent = this;
      child.previousPage = this.children[this.children.length - 1];
      this.children.push(child);
    }
  }, {
    key: 'removeChild',
    value: function removeChild(child) {
      var i = this.children.indexOf(child);
      child.parent = null;

      if (this.children[i + 1]) {
        this.children[i + 1].previousPage = this.children[i].previousPage;
      }

      this.children.slice(i, 1);
    }
  }, {
    key: 'addMetaData',
    value: function addMetaData() {
      var _props = this.props,
          title = _props.title,
          author = _props.author,
          subject = _props.subject,
          keywords = _props.keywords,
          creator = _props.creator,
          producer = _props.producer;

      // The object keys need to start with a capital letter by the PDF spec

      if (title) {
        this.root.info.Title = title;
      }
      if (author) {
        this.root.info.Author = author;
      }
      if (subject) {
        this.root.info.Subject = subject;
      }
      if (keywords) {
        this.root.info.Keywords = keywords;
      }

      this.root.info.Creator = creator || 'react-pdf';
      this.root.info.Producer = producer || 'react-pdf';
    }
  }, {
    key: 'loadFonts',
    value: function () {
      var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
        var promises, listToExplore, node;
        return regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                promises = [];
                listToExplore = this.children.slice(0);


                while (listToExplore.length > 0) {
                  node = listToExplore.shift();


                  if (node.style && node.style.fontFamily) {
                    promises.push(_font2.default.load(node.style.fontFamily, this.root));
                  }

                  if (node.children) {
                    node.children.forEach(function (childNode) {
                      listToExplore.push(childNode);
                    });
                  }
                }

                _context.next = 5;
                return Promise.all(promises);

              case 5:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function loadFonts() {
        return _ref.apply(this, arguments);
      }

      return loadFonts;
    }()
  }, {
    key: 'loadEmojis',
    value: function () {
      var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
        var promises, listToExplore, node;
        return regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                promises = [];
                listToExplore = this.children.slice(0);


                while (listToExplore.length > 0) {
                  node = listToExplore.shift();


                  if (typeof node === 'string') {
                    promises.push.apply(promises, _toConsumableArray((0, _emoji.fetchEmojis)(node)));
                  } else if (node.children) {
                    node.children.forEach(function (childNode) {
                      listToExplore.push(childNode);
                    });
                  }
                }

                _context2.next = 5;
                return Promise.all(promises);

              case 5:
              case 'end':
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      function loadEmojis() {
        return _ref2.apply(this, arguments);
      }

      return loadEmojis;
    }()
  }, {
    key: 'loadImages',
    value: function () {
      var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
        var promises, listToExplore, node;
        return regeneratorRuntime.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                promises = [];
                listToExplore = this.children.slice(0);


                while (listToExplore.length > 0) {
                  node = listToExplore.shift();


                  if (node.constructor.name === 'Image') {
                    promises.push(node.fetch());
                  }

                  if (node.children) {
                    node.children.forEach(function (childNode) {
                      listToExplore.push(childNode);
                    });
                  }
                }

                _context3.next = 5;
                return Promise.all(promises);

              case 5:
              case 'end':
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      function loadImages() {
        return _ref3.apply(this, arguments);
      }

      return loadImages;
    }()
  }, {
    key: 'loadAssets',
    value: function () {
      var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
        return regeneratorRuntime.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                _context4.next = 2;
                return Promise.all([this.loadFonts(), this.loadImages()]);

              case 2:
              case 'end':
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      function loadAssets() {
        return _ref4.apply(this, arguments);
      }

      return loadAssets;
    }()
  }, {
    key: 'applyProps',
    value: function applyProps() {
      for (var i = 0; i < this.children.length; i++) {
        this.children[i].applyProps();
      }
    }
  }, {
    key: 'wrapChildren',
    value: function () {
      var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
        var i;
        return regeneratorRuntime.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                i = 0;

              case 1:
                if (!(i < this.children.length)) {
                  _context5.next = 7;
                  break;
                }

                _context5.next = 4;
                return this.children[i].wrapPage();

              case 4:
                i++;
                _context5.next = 1;
                break;

              case 7:
              case 'end':
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      function wrapChildren() {
        return _ref5.apply(this, arguments);
      }

      return wrapChildren;
    }()
  }, {
    key: 'renderChildren',
    value: function () {
      var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
        var i;
        return regeneratorRuntime.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                i = 0;

              case 1:
                if (!(i < this.children.length)) {
                  _context6.next = 7;
                  break;
                }

                _context6.next = 4;
                return this.children[i].render();

              case 4:
                i++;
                _context6.next = 1;
                break;

              case 7:
              case 'end':
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      function renderChildren() {
        return _ref6.apply(this, arguments);
      }

      return renderChildren;
    }()
  }, {
    key: 'render',
    value: function () {
      var _ref7 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {
        return regeneratorRuntime.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                _context7.prev = 0;

                this.addMetaData();
                this.applyProps();
                _context7.next = 5;
                return this.loadEmojis();

              case 5:
                _context7.next = 7;
                return this.loadAssets();

              case 7:
                _context7.next = 9;
                return this.wrapChildren();

              case 9:
                _context7.next = 11;
                return this.renderChildren();

              case 11:
                this.root.end();
                _font2.default.reset();
                _context7.next = 18;
                break;

              case 15:
                _context7.prev = 15;
                _context7.t0 = _context7['catch'](0);
                throw _context7.t0;

              case 18:
              case 'end':
                return _context7.stop();
            }
          }
        }, _callee7, this, [[0, 15]]);
      }));

      function render() {
        return _ref7.apply(this, arguments);
      }

      return render;
    }()
  }, {
    key: 'pageCount',
    get: function get() {
      return this.children.reduce(function (acc, page) {
        return acc + page.subpagesCount;
      }, 0);
    }
  }]);

  return Document;
}();

Document.defaultProps = {
  author: null,
  keywords: null,
  subject: null,
  title: null
};
exports.default = Document;