import { getScreenHeight, setStyle, getImageComputedProperties, getImageSrc, imageIsAnimated, } from './utils';
const MOBILE_SAFE_ADDRESSBAR_HEIGHT = 80;
function getHeightOverride(height, mediaHeightOverrideType) {
    // on mobile, documentElement.clientHeight changes when scrolling, because of address bar collapsing.
    // avoiding re-fetching image by returning the same height
    return mediaHeightOverrideType === 'fixed' ||
        mediaHeightOverrideType === 'viewport'
        ? document.documentElement.clientHeight + MOBILE_SAFE_ADDRESSBAR_HEIGHT
        : height;
}
function computeScaleOverrides(imageStyle, targetScale = 1) {
    return targetScale !== 1
        ? {
            ...imageStyle,
            width: '100%',
            height: '100%',
        }
        : imageStyle;
}
/**
 * compute specific overrides
 */
function computeStyleOverrides(mediaHeightOverrideType, imageStyle, displayMode, targetScale, isResponsive) {
    // image scaling override
    const styleWithScale = computeScaleOverrides(imageStyle, targetScale);
    if (isResponsive) {
        delete styleWithScale.height;
        styleWithScale.width = '100%';
    }
    if (!mediaHeightOverrideType) {
        return styleWithScale;
    }
    // siteBackground on mobile
    const style = { ...styleWithScale };
    if (displayMode === 'fill') {
        style.position = 'absolute';
        style.top = '0';
    }
    else if (displayMode === 'fit') {
        style.height = '100%';
    }
    if (mediaHeightOverrideType === 'fixed') {
        // eliminates white gap when address bar is collapsing
        style['will-change'] = 'transform';
    }
    // force image alignment to include top
    if (style.objectPosition) {
        style.objectPosition = imageStyle.objectPosition.replace(/(center|bottom)$/, 'top');
    }
    return style;
}
function getSourceSetsTargetHeightByEffect(sourceSets, offsetWidth, offsetHeight, screenHeight, services) {
    const sourceSetsTargetHeights = {};
    sourceSets.forEach(({ mediaQuery, scrollEffect }) => {
        sourceSetsTargetHeights[mediaQuery] =
            services.getMediaDimensionsByEffect?.(scrollEffect, offsetWidth, offsetHeight, screenHeight).height || offsetHeight;
    });
    return sourceSetsTargetHeights;
}
function computeSrcSets(measures, imageInfo, envConsts) {
    const { sourceSets } = imageInfo;
    if (!sourceSets || !sourceSets.length) {
        return;
    }
    const mediaToUri = {};
    sourceSets.forEach(({ mediaQuery, crop, focalPoint }) => {
        const imageInfoClone = {
            ...imageInfo,
            targetHeight: (measures.sourceSetsTargetHeights || {})[mediaQuery] || 0,
            imageData: {
                ...imageInfo.imageData,
                crop,
                focalPoint,
            },
        };
        const imageComputedProperties = getImageComputedProperties(imageInfoClone, envConsts, 'img');
        mediaToUri[mediaQuery] = imageComputedProperties.uri || '';
    });
    return mediaToUri;
}
function measure(id, measures, domNodes, { containerElm, bgEffect = 'none', sourceSets, }, services) {
    const innerImage = domNodes.image;
    const wixImage = domNodes[id];
    const screenHeight = getScreenHeight(services.getScreenHeightOverride?.());
    // override positioning and scaling of image (SiteBackground mobile override behaviour)
    const mediaHeightOverrideType = containerElm?.dataset
        .mediaHeightOverrideType;
    const hasBgEffect = (bgEffect && bgEffect !== 'none') ||
        (sourceSets && sourceSets.some((srcset) => srcset.scrollEffect));
    const sourceOfDimensions = (containerElm && hasBgEffect ? containerElm : wixImage); // default to self
    const cssBgEffect = window
        .getComputedStyle(wixImage)
        .getPropertyValue('--bg-scrub-effect');
    const { width, height } = services.getMediaDimensionsByEffect?.(cssBgEffect || bgEffect, sourceOfDimensions.offsetWidth, sourceOfDimensions.offsetHeight, screenHeight) || {
        width: wixImage.offsetWidth,
        height: wixImage.offsetHeight,
    };
    if (sourceSets) {
        measures.sourceSetsTargetHeights = getSourceSetsTargetHeightByEffect(sourceSets, sourceOfDimensions.offsetWidth, sourceOfDimensions.offsetHeight, screenHeight, services);
    }
    if (!innerImage) {
        return;
    }
    const imgSrc = getImageSrc(innerImage);
    if (cssBgEffect) {
        measures.top = 0.5 * (wixImage.offsetHeight - height);
        measures.left = 0.5 * (wixImage.offsetWidth - width);
    }
    measures.width = width;
    measures.height = getHeightOverride(height, mediaHeightOverrideType);
    measures.screenHeight = screenHeight;
    measures.imgSrc = imgSrc;
    measures.boundingRect = wixImage.getBoundingClientRect();
    measures.mediaHeightOverrideType = mediaHeightOverrideType;
    measures.srcset = innerImage.srcset;
}
function patch(id, measures, domNodes, imageInfo, services, envConsts, loadImage, isResponsive, bgEffect, loadImageImmediately) {
    if (!Object.keys(measures).length) {
        return;
    }
    const { imageData } = imageInfo;
    const wixImageNode = domNodes[id];
    const image = domNodes.image;
    // no retina scaling for background scroll effects
    if (bgEffect) {
        imageData.devicePixelRatio = 1;
    }
    const targetScale = imageInfo.targetScale || 1;
    const allowFullGIFTransformation = services.isExperimentOpen?.('specs.thunderbolt.allowFullGIFTransformation');
    const extendedImageInfo = {
        ...imageInfo,
        ...(!imageInfo.skipMeasure && {
            targetWidth: (measures.width || 0) * targetScale,
            targetHeight: (measures.height || 0) * targetScale,
        }),
        displayMode: imageData.displayMode,
        allowFullGIFTransformation,
    };
    const imageComputedProperties = getImageComputedProperties(extendedImageInfo, envConsts, 'img');
    const computedStyle = imageComputedProperties?.css?.img || {};
    const imageStyle = computeStyleOverrides(measures.mediaHeightOverrideType, computedStyle, imageData.displayMode, targetScale, isResponsive);
    setStyle(image, imageStyle);
    if (measures.top || measures.left) {
        setStyle(wixImageNode, {
            top: `${measures.top}px`,
            left: `${measures.left}px`,
        });
    }
    const src = imageComputedProperties?.uri || '';
    const hasAnimation = imageData?.hasAnimation || imageInfo?.hasAnimation;
    const mediaToUri = computeSrcSets(measures, extendedImageInfo, envConsts);
    if (loadImageImmediately) {
        // flag that this image has been processed
        image.dataset.ssrSrcDone = 'true';
    }
    if (imageInfo.isLQIP &&
        imageInfo.lqipTransition &&
        !('transitioned' in wixImageNode.dataset)) {
        wixImageNode.dataset.transitioned = '';
        if (image.complete) {
            image.onload = function () {
                image.dataset.loadDone = '';
            };
        }
        else {
            image.onload = function () {
                if (image.complete) {
                    image.dataset.loadDone = '';
                }
                else {
                    image.onload = function () {
                        image.dataset.loadDone = '';
                    };
                }
            };
        }
    }
    if (loadImage) {
        if (imageIsAnimated(imageData.uri, hasAnimation)) {
            image.setAttribute('fetchpriority', 'low');
            image.setAttribute('loading', 'lazy');
            image.setAttribute('decoding', 'async');
        }
        else {
            image.setAttribute('fetchpriority', 'high');
        }
        image.currentSrc !== src && image.setAttribute('src', src);
        const srcIsMissingFromSrcset = measures.srcset &&
            !measures.srcset
                .split(', ')
                .some((source) => source.split(' ')[0] === src);
        if (srcIsMissingFromSrcset) {
            image.setAttribute('srcset', src);
        }
        if (domNodes.picture && extendedImageInfo.sourceSets) {
            Array.from(domNodes.picture.querySelectorAll('source')).forEach((sourceNode) => {
                const mediaQuery = sourceNode.media || '';
                const uri = mediaToUri?.[mediaQuery];
                if (sourceNode.srcset !== uri) {
                    sourceNode.setAttribute('srcset', uri || '');
                }
            });
        }
    }
}
export default {
    measure,
    patch,
};
//# sourceMappingURL=imageLayout.js.map