"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVValue = void 0;
exports.reactToFrameSize = reactToFrameSize;
exports.applyDynamicStyle = applyDynamicStyle;
exports.removeStyle = removeStyle;
exports.applyStyle = applyStyle;
exports.getStyleObj = getStyleObj;
exports.mergeStyle = mergeStyle;
const NOOP_1 = require("../NOOP");
const callAll_1 = require("../util/call/callAll");
const addListener_1 = require("./addListener");
const custom_1 = require("./event/custom");
const resize_1 = require("./event/resize");
const id_1 = require("./id");
const rawExtractStyle_1 = require("./rawExtractStyle");
const isVValue = (value) => {
    return value.endsWith('vh') || value.endsWith('vw');
};
exports.isVValue = isVValue;
function reactToFrameSize(value, component, setValue) {
    let unlistenComponent = NOOP_1.NOOP;
    let unlistenContext = NOOP_1.NOOP;
    const vh = value.endsWith('vh');
    const vw = value.endsWith('vw');
    if (vw || vh) {
        const percent = parseFloat(value.replace('vh', '').replace('vw', '')) / 100;
        const resize = ({ width, height }) => {
            setValue(vw ? width * percent : height * percent);
        };
        const resizeListener = (0, resize_1.makeResizeListener)(resize);
        const immediateResize = () => {
            const { $width: width, $height: height } = component.$context;
            resize({ width, height });
        };
        const addContextListener = () => {
            const { $context } = component;
            unlistenContext = (0, addListener_1.addListener)($context, resizeListener);
        };
        const removeContextListener = () => {
            unlistenContext();
            unlistenContext = NOOP_1.NOOP;
        };
        if (component.$mounted) {
            addContextListener();
            immediateResize();
        }
        unlistenComponent = component.addEventListeners([
            (0, custom_1.makeCustomListener)('mount', () => {
                immediateResize();
                if (unlistenContext) {
                    unlistenContext();
                }
                addContextListener();
            }),
            (0, custom_1.makeCustomListener)('unmount', removeContextListener),
        ]);
        return (0, callAll_1.callAll)([removeContextListener, unlistenComponent]);
    }
    return NOOP_1.NOOP;
}
function applyDynamicStyle(component, $element, style) {
    let { fontSize, width, height } = style;
    let styleUnlisten = component.$propUnlisten['style'];
    if (styleUnlisten) {
        styleUnlisten();
        delete component.$propUnlisten['style'];
    }
    const unlistenAll = [];
    if (typeof fontSize === 'number') {
        fontSize = `${fontSize}px`;
    }
    const set = (name, value) => {
        if (component.$moving) {
            return;
        }
        const px = value + 'px';
        style[name] = px;
        component.$element.style[name] = px;
    };
    if (fontSize && (0, exports.isVValue)(fontSize)) {
        delete style.fontSize;
        unlistenAll.push(reactToFrameSize(fontSize, component, (value) => {
            set('fontSize', value);
        }));
    }
    if (width && (0, exports.isVValue)(width)) {
        delete style.width;
        unlistenAll.push(reactToFrameSize(width, component, (value) => {
            set('width', value);
        }));
    }
    if (height && (0, exports.isVValue)(height)) {
        delete style.height;
        unlistenAll.push(reactToFrameSize(height, component, (value) => {
            set('height', value);
        }));
    }
    applyStyle($element, style);
    styleUnlisten = (0, callAll_1.callAll)(unlistenAll);
    component.$propUnlisten['style'] = styleUnlisten;
    return styleUnlisten;
}
function removeStyle(element) {
    element.style.cssText = '';
}
function applyStyle(element, style) {
    element.style.cssText = (0, rawExtractStyle_1.objToCssText)(style);
}
function getStyleObj(element) {
    return (0, rawExtractStyle_1.cssTextToObj)(element.style.cssText);
}
function mergeStyle(element, style) {
    const current = getStyleObj(element);
    for (const key in style) {
        const value = style[key];
        current[(0, id_1.camelToDashed)(key)] = value;
    }
    applyStyle(element, current);
}
//# sourceMappingURL=style.js.map