'use strict';

/**
 * @typedef {import('../lib/types').XastChild} XastChild
 * @typedef {import('../lib/types').XastElement} XastElement
 * @typedef {import('../lib/types').XastParent} XastParent
 */

const { cleanupOutData, toFixed } = require('../lib/svgo/tools.js');
const {
  transform2js,
  transformsMultiply,
  matrixToTransform,
} = require('./_transforms.js');

exports.name = 'convertTransform';
exports.description = 'collapses multiple transformations and optimizes it';

/**
 * Convert matrices to the short aliases,
 * convert long translate, scale or rotate transform notations to the shorts ones,
 * convert transforms to the matrices and multiply them all into one,
 * remove useless transforms.
 *
 * @see https://www.w3.org/TR/SVG11/coords.html#TransformMatrixDefined
 *
 * @author Kir Belevich
 *
 * @type {import('./plugins-types').Plugin<'convertTransform'>}
 */
exports.fn = (_root, params) => {
  const {
    convertToShorts = true,
    // degPrecision = 3, // transformPrecision (or matrix precision) - 2 by default
    degPrecision,
    floatPrecision = 3,
    transformPrecision = 5,
    matrixToTransform = true,
    shortTranslate = true,
    shortScale = true,
    shortRotate = true,
    removeUseless = true,
    collapseIntoOne = true,
    leadingZero = true,
    negativeExtraSpace = false,
  } = params;
  const newParams = {
    convertToShorts,
    degPrecision,
    floatPrecision,
    transformPrecision,
    matrixToTransform,
    shortTranslate,
    shortScale,
    shortRotate,
    removeUseless,
    collapseIntoOne,
    leadingZero,
    negativeExtraSpace,
  };
  return {
    element: {
      enter: (node) => {
        if (node.attributes.transform != null) {
          convertTransform(node, 'transform', newParams);
        }

        if (node.attributes.gradientTransform != null) {
          convertTransform(node, 'gradientTransform', newParams);
        }

        if (node.attributes.patternTransform != null) {
          convertTransform(node, 'patternTransform', newParams);
        }
      },
    },
  };
};

/**
 * @typedef {{
 *   convertToShorts: boolean,
 *   degPrecision?: number,
 *   floatPrecision: number,
 *   transformPrecision: number,
 *   matrixToTransform: boolean,
 *   shortTranslate: boolean,
 *   shortScale: boolean,
 *   shortRotate: boolean,
 *   removeUseless: boolean,
 *   collapseIntoOne: boolean,
 *   leadingZero: boolean,
 *   negativeExtraSpace: boolean,
 * }} TransformParams
 */

/**
 * @typedef {{ name: string, data: number[] }} TransformItem
 */

/**
 * @param {XastElement} item
 * @param {string} attrName
 * @param {TransformParams} params
 */
const convertTransform = (item, attrName, params) => {
  let data = transform2js(item.attributes[attrName]);
  params = definePrecision(data, params);

  if (params.collapseIntoOne && data.length > 1) {
    data = [transformsMultiply(data)];
  }

  if (params.convertToShorts) {
    data = convertToShorts(data, params);
  } else {
    data.forEach((item) => roundTransform(item, params));
  }

  if (params.removeUseless) {
    data = removeUseless(data);
  }

  if (data.length) {
    item.attributes[attrName] = js2transform(data, params);
  } else {
    delete item.attributes[attrName];
  }
};

/**
 * Defines precision to work with certain parts.
 * transformPrecision - for scale and four first matrix parameters (needs a better precision due to multiplying),
 * floatPrecision - for translate including two last matrix and rotate parameters,
 * degPrecision - for rotate and skew. By default it's equal to (roughly)
 * transformPrecision - 2 or floatPrecision whichever is lower. Can be set in params.
 *
 * @type {(data: TransformItem[], params: TransformParams) => TransformParams}
 *
 * clone params so it don't affect other elements transformations.
 */
const definePrecision = (data, { ...newParams }) => {
  const matrixData = [];
  for (const item of data) {
    if (item.name == 'matrix') {
      matrixData.push(...item.data.slice(0, 4));
    }
  }
  let numberOfDigits = newParams.transformPrecision;
  // Limit transform precision with matrix one. Calculating with larger precision doesn't add any value.
  if (matrixData.length) {
    newParams.transformPrecision = Math.min(
      newParams.transformPrecision,
      Math.max.apply(Math, matrixData.map(floatDigits)) ||
        newParams.transformPrecision,
    );
    numberOfDigits = Math.max.apply(
      Math,
      matrixData.map(
        (n) => n.toString().replace(/\D+/g, '').length, // Number of digits in a number. 123.45 → 5
      ),
    );
  }
  // No sense in angle precision more then number of significant digits in matrix.
  if (newParams.degPrecision == null) {
    newParams.degPrecision = Math.max(
      0,
      Math.min(newParams.floatPrecision, numberOfDigits - 2),
    );
  }
  return newParams;
};

/**
 * @type {(data: number[], params: TransformParams) => number[]}
 */
const degRound = (data, params) => {
  if (
    params.degPrecision != null &&
    params.degPrecision >= 1 &&
    params.floatPrecision < 20
  ) {
    return smartRound(params.degPrecision, data);
  } else {
    return round(data);
  }
};
/**
 * @type {(data: number[], params: TransformParams) => number[]}
 */
const floatRound = (data, params) => {
  if (params.floatPrecision >= 1 && params.floatPrecision < 20) {
    return smartRound(params.floatPrecision, data);
  } else {
    return round(data);
  }
};

/**
 * @type {(data: number[], params: TransformParams) => number[]}
 */
const transformRound = (data, params) => {
  if (params.transformPrecision >= 1 && params.floatPrecision < 20) {
    return smartRound(params.transformPrecision, data);
  } else {
    return round(data);
  }
};

/**
 * Returns number of digits after the point. 0.125 → 3
 *
 * @type {(n: number) => number}
 */
const floatDigits = (n) => {
  const str = n.toString();
  return str.slice(str.indexOf('.')).length - 1;
};

/**
 * Convert transforms to the shorthand alternatives.
 *
 * @param {TransformItem[]} transforms
 * @param {TransformParams} params
 * @returns {TransformItem[]}
 */
const convertToShorts = (transforms, params) => {
  for (var i = 0; i < transforms.length; i++) {
    let transform = transforms[i];

    // convert matrix to the short aliases
    if (params.matrixToTransform && transform.name === 'matrix') {
      var decomposed = matrixToTransform(transform, params);
      if (
        js2transform(decomposed, params).length <=
        js2transform([transform], params).length
      ) {
        transforms.splice(i, 1, ...decomposed);
      }
      transform = transforms[i];
    }

    // fixed-point numbers
    // 12.754997 → 12.755
    roundTransform(transform, params);

    // convert long translate transform notation to the shorts one
    // translate(10 0) → translate(10)
    if (
      params.shortTranslate &&
      transform.name === 'translate' &&
      transform.data.length === 2 &&
      !transform.data[1]
    ) {
      transform.data.pop();
    }

    // convert long scale transform notation to the shorts one
    // scale(2 2) → scale(2)
    if (
      params.shortScale &&
      transform.name === 'scale' &&
      transform.data.length === 2 &&
      transform.data[0] === transform.data[1]
    ) {
      transform.data.pop();
    }

    // convert long rotate transform notation to the short one
    // translate(cx cy) rotate(a) translate(-cx -cy) → rotate(a cx cy)
    if (
      params.shortRotate &&
      transforms[i - 2]?.name === 'translate' &&
      transforms[i - 1].name === 'rotate' &&
      transforms[i].name === 'translate' &&
      transforms[i - 2].data[0] === -transforms[i].data[0] &&
      transforms[i - 2].data[1] === -transforms[i].data[1]
    ) {
      transforms.splice(i - 2, 3, {
        name: 'rotate',
        data: [
          transforms[i - 1].data[0],
          transforms[i - 2].data[0],
          transforms[i - 2].data[1],
        ],
      });

      // splice compensation
      i -= 2;
    }
  }

  return transforms;
};

/**
 * Remove useless transforms.
 *
 * @type {(transforms: TransformItem[]) => TransformItem[]}
 */
const removeUseless = (transforms) => {
  return transforms.filter((transform) => {
    // translate(0), rotate(0[, cx, cy]), skewX(0), skewY(0)
    if (
      (['translate', 'rotate', 'skewX', 'skewY'].indexOf(transform.name) > -1 &&
        (transform.data.length == 1 || transform.name == 'rotate') &&
        !transform.data[0]) ||
      // translate(0, 0)
      (transform.name == 'translate' &&
        !transform.data[0] &&
        !transform.data[1]) ||
      // scale(1)
      (transform.name == 'scale' &&
        transform.data[0] == 1 &&
        (transform.data.length < 2 || transform.data[1] == 1)) ||
      // matrix(1 0 0 1 0 0)
      (transform.name == 'matrix' &&
        transform.data[0] == 1 &&
        transform.data[3] == 1 &&
        !(
          transform.data[1] ||
          transform.data[2] ||
          transform.data[4] ||
          transform.data[5]
        ))
    ) {
      return false;
    }

    return true;
  });
};

/**
 * Convert transforms JS representation to string.
 *
 * @param {TransformItem[]} transformJS
 * @param {TransformParams} params
 * @returns {string}
 */
const js2transform = (transformJS, params) => {
  const transformString = transformJS
    .map((transform) => {
      roundTransform(transform, params);
      return `${transform.name}(${cleanupOutData(transform.data, params)})`;
    })
    .join('');

  return transformString;
};

/**
 * @type {(transform: TransformItem, params: TransformParams) => TransformItem}
 */
const roundTransform = (transform, params) => {
  switch (transform.name) {
    case 'translate':
      transform.data = floatRound(transform.data, params);
      break;
    case 'rotate':
      transform.data = [
        ...degRound(transform.data.slice(0, 1), params),
        ...floatRound(transform.data.slice(1), params),
      ];
      break;
    case 'skewX':
    case 'skewY':
      transform.data = degRound(transform.data, params);
      break;
    case 'scale':
      transform.data = transformRound(transform.data, params);
      break;
    case 'matrix':
      transform.data = [
        ...transformRound(transform.data.slice(0, 4), params),
        ...floatRound(transform.data.slice(4), params),
      ];
      break;
  }
  return transform;
};

/**
 * Rounds numbers in array.
 *
 * @type {(data: number[]) => number[]}
 */
const round = (data) => {
  return data.map(Math.round);
};

/**
 * Decrease accuracy of floating-point numbers
 * in transforms keeping a specified number of decimals.
 * Smart rounds values like 2.349 to 2.35.
 *
 * @param {number} precision
 * @param {number[]} data
 * @returns {number[]}
 */
const smartRound = (precision, data) => {
  for (
    var i = data.length,
      tolerance = +Math.pow(0.1, precision).toFixed(precision);
    i--;

  ) {
    if (toFixed(data[i], precision) !== data[i]) {
      var rounded = +data[i].toFixed(precision - 1);
      data[i] =
        +Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance
          ? +data[i].toFixed(precision)
          : rounded;
    }
  }

  return data;
};
