"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.convertMarginLeftToIndentValue = convertMarginLeftToIndentValue;
exports.default = exports.getParagraphStyle = exports.getParagraphNodeAttrs = exports.toParagraphDOM = exports.EMPTY_CSS_VALUE = exports.RESERVED_STYLE_NONE_NUMBERING = exports.RESERVED_STYLE_NONE = exports.ATTRIBUTE_STYLE_LEVEL = exports.ATTRIBUTE_INDENT = exports.MAX_INDENT_LEVEL = exports.MIN_INDENT_LEVEL = exports.INDENT_MARGIN_PT_SIZE = void 0;

var _clamp = _interopRequireDefault(require("./ui/clamp"));

var _convertToCSSPTValue = _interopRequireDefault(require("./convertToCSSPTValue"));

var _toCSSLineSpacing = _interopRequireDefault(require("./ui/toCSSLineSpacing"));

var _prosemirrorModel = require("prosemirror-model");

var _customStyle = require("./customStyle");

var _Types = require("./Types");

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

// This assumes that every 36pt maps to one indent level.
const INDENT_MARGIN_PT_SIZE = 36;
exports.INDENT_MARGIN_PT_SIZE = INDENT_MARGIN_PT_SIZE;
const MIN_INDENT_LEVEL = 0;
exports.MIN_INDENT_LEVEL = MIN_INDENT_LEVEL;
const MAX_INDENT_LEVEL = 7;
exports.MAX_INDENT_LEVEL = MAX_INDENT_LEVEL;
const ATTRIBUTE_INDENT = 'data-indent';
exports.ATTRIBUTE_INDENT = ATTRIBUTE_INDENT;
const ATTRIBUTE_STYLE_LEVEL = 'data-style-level';
exports.ATTRIBUTE_STYLE_LEVEL = ATTRIBUTE_STYLE_LEVEL;
const RESERVED_STYLE_NONE = 'None';
exports.RESERVED_STYLE_NONE = RESERVED_STYLE_NONE;
const RESERVED_STYLE_NONE_NUMBERING = RESERVED_STYLE_NONE + '-@#$-';
exports.RESERVED_STYLE_NONE_NUMBERING = RESERVED_STYLE_NONE_NUMBERING;
const cssVal = new Set(['', '0%', '0pt', '0px']);
const EMPTY_CSS_VALUE = cssVal;
exports.EMPTY_CSS_VALUE = EMPTY_CSS_VALUE;
const ALIGN_PATTERN = /(left|right|center|justify)/; // https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js
// :: NodeSpec A plain paragraph textblock. Represented in the DOM
// as a `<p>` element.

const ParagraphNodeSpec = {
  attrs: {
    align: {
      default: null
    },
    color: {
      default: null
    },
    id: {
      default: null
    },
    indent: {
      default: null
    },
    lineSpacing: {
      default: null
    },
    // TODO: Add UI to let user edit / clear padding.
    paddingBottom: {
      default: null
    },
    // TODO: Add UI to let user edit / clear padding.
    paddingTop: {
      default: null
    },
    styleName: {
      default: RESERVED_STYLE_NONE
    }
  },
  content: 'inline*',
  group: 'block',
  parseDOM: [{
    tag: 'p',
    getAttrs
  }],
  toDOM
};

function getAttrs(dom) {
  const {
    lineHeight,
    textAlign,
    marginLeft,
    paddingTop,
    paddingBottom
  } = dom.style;
  let align = dom.getAttribute('align') || textAlign || '';
  align = ALIGN_PATTERN.test(align) ? align : null;
  let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT), 10);

  if (!indent && marginLeft) {
    indent = convertMarginLeftToIndentValue(marginLeft);
  }

  indent = indent || MIN_INDENT_LEVEL;
  const lineSpacing = lineHeight ? (0, _toCSSLineSpacing.default)(lineHeight) : null;
  const id = dom.getAttribute('id') || '';
  const styleName = dom.getAttribute('styleName') || null;
  return {
    align,
    indent,
    lineSpacing,
    paddingTop,
    paddingBottom,
    id,
    styleName
  };
}

function getStyle(attrs) {
  return getStyleEx(attrs.align, attrs.lineSpacing, attrs.paddingTop, attrs.paddingBottom, attrs.styleName);
}

function getStyleEx(align, lineSpacing, paddingTop, paddingBottom, styleName) {
  let style = '';
  let styleLevel = 0;
  let indentOverriden = '';

  if (align && align !== 'left') {
    style += `text-align: ${align};`;
  }

  if (lineSpacing) {
    const cssLineSpacing = (0, _toCSSLineSpacing.default)(lineSpacing);
    style += `line-height: ${cssLineSpacing};` + // This creates the local css variable `--czi-content-line-height`
    // that its children may apply.
    `--czi-content-line-height: ${cssLineSpacing};`;
  } //to get the styles of the corresponding style name


  const styleProps = (0, _customStyle.getCustomStyleByName)(styleName);

  if (null !== styleProps && styleProps.styles) {
    // [FS] IRAD-1100 2020-11-04
    // Add in leading and trailing spacing (before and after a paragraph)
    if (styleProps.styles.paragraphSpacingAfter) {
      style += `margin-bottom: ${styleProps.styles.paragraphSpacingAfter}pt !important;`;
    }

    if (styleProps.styles.paragraphSpacingBefore) {
      style += `margin-top: ${styleProps.styles.paragraphSpacingBefore}pt !important;`;
    }

    if (styleProps.styles.styleLevel) {
      if (styleProps.styles.strong) {
        style += 'font-weight: bold;';
      }

      if (styleProps.styles.boldNumbering) {
        style += ' --czi-counter-bold: bold;';
      }

      if (styleProps.styles.em) {
        style += 'font-style: italic;';
      }

      if (styleProps.styles.color) {
        style += `color: ${styleProps.styles.color};`;
      }

      if (styleProps.styles.fontSize) {
        style += `font-size: ${styleProps.styles.fontSize}pt;`;
      }

      if (styleProps.styles.fontName) {
        style += `font-family: ${styleProps.styles.fontName};`;
      }

      if (styleProps.styles.indent) {
        indentOverriden = styleProps.styles.indent;
      } // [FS] IRAD-1462 2021-06-17
      // FIX:  Numbering applied for paragraph even though the custom style not selected numbering(but set level)


      styleLevel = styleProps.styles.hasNumbering ? parseInt(styleProps.styles.styleLevel) : 0;
      style += refreshCounters(styleLevel);
    }
  } else if (styleName && styleName.includes(RESERVED_STYLE_NONE_NUMBERING)) {
    const indices = styleName.split(RESERVED_STYLE_NONE_NUMBERING);

    if (indices && 2 == indices.length) {
      styleLevel = parseInt(indices[1]);
    }

    if (styleLevel) {
      style += refreshCounters(styleLevel);
    }
  }

  if (paddingTop && !EMPTY_CSS_VALUE.has(paddingTop)) {
    style += `padding-top: ${paddingTop};`;
  }

  if (paddingBottom && !EMPTY_CSS_VALUE.has(paddingBottom)) {
    style += `padding-bottom: ${paddingBottom};`;
  }

  return {
    style,
    styleLevel,
    indentOverriden
  };
} // [FS] IRAD-1202 2021-02-15


function refreshCounters(styleLevel) {
  let latestCounters = '';
  let cssCounterReset = '';
  let setCounterReset = false; // set style counters in window variables,
  // so that it is remapped later to add to document attribute via transaction.

  for (let index = 1; index <= styleLevel; index++) {
    const counterVar = 'set-cust-style-counter-' + index;
    const setCounterVal = window[counterVar];

    if (!setCounterVal) {
      cssCounterReset += `C${index} `;
      setCounterReset = true;
    }

    window[counterVar] = true;
  }

  if (setCounterReset) {
    latestCounters = `counter-increment: ${cssCounterReset};`;
  }

  return latestCounters;
}

function toDOM(node) {
  const {
    indent,
    id,
    styleName
  } = node.attrs;
  const attrs = {};
  const {
    style,
    styleLevel,
    indentOverriden
  } = getStyle(node.attrs);
  style && (attrs.style = style);

  if (styleLevel) {
    attrs[ATTRIBUTE_STYLE_LEVEL] = String(styleLevel);
  }

  if (indent) {
    attrs[ATTRIBUTE_INDENT] = String(indent);
  }

  if ('' !== indentOverriden) {
    attrs[ATTRIBUTE_INDENT] = String(indentOverriden);
  }

  if (id) {
    attrs.id = id;
  }

  attrs.styleName = styleName;
  return ['p', attrs, 0];
}

const toParagraphDOM = toDOM;
exports.toParagraphDOM = toParagraphDOM;
const getParagraphNodeAttrs = getAttrs;
exports.getParagraphNodeAttrs = getParagraphNodeAttrs;
const getParagraphStyle = getStyle;
exports.getParagraphStyle = getParagraphStyle;

function convertMarginLeftToIndentValue(marginLeft) {
  const ptValue = (0, _convertToCSSPTValue.default)(marginLeft);
  return (0, _clamp.default)(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL);
}

var _default = ParagraphNodeSpec;
exports.default = _default;