"use strict";

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

// Generated by CoffeeScript 2.5.1
var AnsiPainter,
    styles,
    tags,
    tools,
    hasProp = {}.hasOwnProperty;
tools = require('./tools');
tags = require('./ansiPainter/tags');
styles = require('./ansiPainter/styles');

module.exports = AnsiPainter = function () {
  var self;

  var AnsiPainter = /*#__PURE__*/function () {
    function AnsiPainter() {
      _classCallCheck(this, AnsiPainter);
    }

    _createClass(AnsiPainter, [{
      key: "paint",
      value: function paint(s) {
        return this._replaceSpecialStrings(this._renderDom(this._parse(s)));
      }
    }, {
      key: "_replaceSpecialStrings",
      value: function _replaceSpecialStrings(str) {
        return str.replace(/&sp;/g, ' ').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&');
      }
    }, {
      key: "_parse",
      value: function _parse(string) {
        var injectFakeRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

        if (injectFakeRoot) {
          string = '<none>' + string + '</none>';
        }

        return tools.toDom(string);
      }
    }, {
      key: "_renderDom",
      value: function _renderDom(dom) {
        var parentStyles;
        parentStyles = {
          bg: 'none',
          color: 'none'
        };
        return this._renderChildren(dom, parentStyles);
      }
    }, {
      key: "_renderChildren",
      value: function _renderChildren(children, parentStyles) {
        var child, n, ret;
        ret = '';

        for (n in children) {
          if (!hasProp.call(children, n)) continue;
          child = children[n];
          ret += this._renderNode(child, parentStyles);
        }

        return ret;
      }
    }, {
      key: "_renderNode",
      value: function _renderNode(node, parentStyles) {
        if (node.type === 'text') {
          return this._renderTextNode(node, parentStyles);
        } else {
          return this._renderTag(node, parentStyles);
        }
      }
    }, {
      key: "_renderTextNode",
      value: function _renderTextNode(node, parentStyles) {
        return this._wrapInStyle(node.data, parentStyles);
      }
    }, {
      key: "_wrapInStyle",
      value: function _wrapInStyle(str, style) {
        return styles.color(style.color) + styles.bg(style.bg) + str + styles.none();
      }
    }, {
      key: "_renderTag",
      value: function _renderTag(node, parentStyles) {
        var currentStyles, tagStyles;
        tagStyles = this._getStylesForTagName(node.name);
        currentStyles = this._mixStyles(parentStyles, tagStyles);
        return this._renderChildren(node.children, currentStyles);
      }
    }, {
      key: "_mixStyles",
      value: function _mixStyles() {
        var final, i, key, len, style, val;
        final = {};

        for (var _len = arguments.length, styles = new Array(_len), _key = 0; _key < _len; _key++) {
          styles[_key] = arguments[_key];
        }

        for (i = 0, len = styles.length; i < len; i++) {
          style = styles[i];

          for (key in style) {
            if (!hasProp.call(style, key)) continue;
            val = style[key];

            if (final[key] == null || val !== 'inherit') {
              final[key] = val;
            }
          }
        }

        return final;
      }
    }, {
      key: "_getStylesForTagName",
      value: function _getStylesForTagName(name) {
        if (tags[name] == null) {
          throw Error("Unknown tag name `".concat(name, "`"));
        }

        return tags[name];
      }
    }], [{
      key: "getInstance",
      value: function getInstance() {
        if (self._instance == null) {
          self._instance = new self();
        }

        return self._instance;
      }
    }, {
      key: "paint",
      value: function paint(str) {
        return self.getInstance().paint(str);
      }
    }, {
      key: "strip",
      value: function strip(s) {
        return s.replace(/\x1b\[[0-9]+m/g, '');
      }
    }]);

    return AnsiPainter;
  }();

  ;
  AnsiPainter.tags = tags;
  self = AnsiPainter;
  return AnsiPainter;
}.call(void 0);