/**
 * @since Last modified: 2024-07-23 11:35:26
 * @constant transformTools
 * @description Collection of operation methods for transform.
 * @see {@link https://codepen.io/axui/pen/abXwOXm|demo @ codepen}
 */
'use strict';
import getEl from "./getEl";
import isEmpty from "./isEmpty";
import isNull from "./isNull";
import style from "./style";
const transformTools = {
    /**
     * @memberof transformTools
     * @description Retrieve the transform object from the style.transform property, including the rotate, scale, translate, and skew attributes.
     * @param {getEl} elem - Target selector.
     * @param {array} [props=['translate', 'scale', 'rotate', 'skew']]  - Collection of properties of the transform object.
     * @param {boolean} [instead=false]  - Whether to use the positioned left and top values instead of x and y values.
     * @returns {object} - Return a object , including the rotate, scale, translate, and skew attributes.
     * @see {@link https://codepen.io/axui/pen/dyEvBMw|demo @ codepen}
     * @example
     * ax.transformTools.get('#demo');
     * <!--return {rotate,scale,translate,skew}-->
     */
    get: (elem, props = ['translate', 'scale', 'rotate', 'skew'], instead = false) => {
        let dom = getEl(elem), styles = style(dom), value = dom?.style?.transform, result = {
            rotate: 0,
            scale: { x: 1, y: 1 },
            translate: { x: 0, y: 0 },
            skew: { x: 0, y: 0 }
        };
        if (value) {
            let getReg = (type) => new RegExp(`${type}\\(([^\\)]+)\\)`), getText = (type) => value.match(getReg(type));
            if (props.includes('translate') && value.includes('translate') && getText('translate')) {
                if (getText('translate')[1].includes(',')) {
                    let arr = getText('translate')[1].split(',').map((k) => parseInt(k));
                    result.translate = { x: arr[0], y: arr[1] };
                }
                else {
                    result.translate = { x: parseInt(getText('translate')[1]), y: 0 };
                }
            }
            if (props.includes('scale') && value.includes('scale') && getText('scale')) {
                if (getText('scale')[1].includes(',')) {
                    let arr = getText('scale')[1].split(',').map((k) => parseFloat(k));
                    result.scale = { x: arr[0], y: arr[1] };
                }
                else {
                    result.scale = { x: parseFloat(getText('scale')[1]), y: parseFloat(getText('scale')[1]) };
                }
            }
            if (props.includes('rotate') && value.includes('rotate') && getText('rotate')) {
                result.rotate = parseFloat(getText('rotate')[1]);
            }
            if (props.includes('skew') && value.includes('skew') && getText('skew')) {
                if (getText('skew')[1].includes(',')) {
                    let arr = getText('skew')[1].split(',').map((k) => parseFloat(k));
                    result.skew = { x: arr[0], y: arr[1] };
                }
                else {
                    result.skew = { x: parseFloat(getText('skew')[1]), y: 0 };
                }
            }
        }
        if (instead) {
            result.translate = { x: parseInt(styles.left), y: parseInt(styles.top) };
        }
        return result;
    },
    /**
    * @memberof transformTools
    * @description Set the node's style.transform property from the transform object.
    * @param {object} opt - Parameters.
    * @param {getEl} opt.el - Target selector.
    * @param {array} opt.data  - The data to be set.
    * @param {boolean} [opt.instead=false]  - Whether to use the positioned left and top values instead of x and y values.
    * @param {boolean} [opt.cb]  - A callback function that accepts a single parameter:transformTxt.
    * @returns {null} - Return null;
    * @see {@link https://codepen.io/axui/pen/ExzmYJw|demo @ codepen}
    * @example
    * ax.transformTools.set({el:'#demo',data:{}});
    * <!--return null-->
    */
    set: function ({ el, data, instead = false, cb }) {
        let dom = getEl(el), now = this.get(dom), transformTxt = dom?.style.transform || '', getReg = (type) => { return new RegExp(`${type}\\(([^\\)]+)\\)`, 'gmi'); }, re = (val, label, prop) => isNull(val[prop]) ? now[label][prop] : val[prop];
        if (!dom && isEmpty(data)) {
            return;
        }
        for (let k in data) {
            if (data.hasOwnProperty(k)) {
                let value = '';
                if (k === 'translate') {
                    if (instead) {
                        !isNaN(data[k]) ?
                            (dom.style.left = `${data[k]}px`) :
                            (dom.style.left = `${re(data[k], 'translate', 'x')}px`, dom.style.top = `${re(data[k], 'translate', 'y')}px`);
                    }
                    else {
                        value = !isNaN(data[k]) ? `${k}(${data[k]}px)` : `${k}(${re(data[k], 'translate', 'x')}px,${re(data[k], 'translate', 'y')}px)`;
                        if (transformTxt.includes(k)) {
                            if (transformTxt.startsWith('translate')) {
                                transformTxt = transformTxt.replace(getReg(k), value);
                            }
                            else {
                                transformTxt = transformTxt.replace(getReg(k), '');
                                transformTxt = `${value} ${transformTxt}`;
                            }
                        }
                        else {
                            transformTxt = `${value} ${transformTxt}`;
                        }
                    }
                }
                else {
                    if (k === 'scale') {
                        value = !isNaN(data[k]) ? `${k}(${data[k]})` : `${k}(${re(data[k], 'scale', 'x')},${re(data[k], 'scale', 'y')})`;
                    }
                    else if (k === 'rotate') {
                        value = `${k}(${data[k]}deg)`;
                    }
                    else if (k === 'skew') {
                        value = !isNaN(data[k]) ? `${k}(${data[k]}deg)` : `${k}(${re(data[k], 'skew', 'x')}deg,${re(data[k], 'skew', 'y')}deg)`;
                    }
                    if (transformTxt.includes(k)) {
                        transformTxt = transformTxt.replace(getReg(k), value);
                    }
                    else {
                        transformTxt += ` ${value}`;
                    }
                }
            }
        }
        dom.style.transform = transformTxt;
        cb && cb(transformTxt);
    },
    /**
    * @memberof transformTools
    * @description Get the transform matrix values from the element's style.
    * @param {getEl} elem - Target selector.
    * @returns {array} - Return matrix values.
    * @see {@link https://codepen.io/axui/pen/rNEeGjx|demo @ codepen}
    * @example
    * ax.transformTools.matrix('#demo');
    * <!--return [1, 0, 0, 1, 0, 0]-->
    */
    matrix: (elem) => {
        let el = getEl(elem);
        if (!el)
            return [];
        let value = style(el).transform;
        return (value === 'none') ? [1, 0, 0, 1, 0, 0] : value.replace(/[^0-9.\-,]/g, '').split(',').map(k => Number(k));
    },
};
export default transformTools;
