export function setScale(scale) {
    const zoom = scale / 100.0;

    document.body.style.zoom = zoom;

    const needsPatch = getScaleAffectsPixels(scale);

    if (needsPatch) {
        if (!HTMLElement.prototype._getBoundingClientRectOriginal) {
            HTMLElement.prototype._getBoundingClientRectOriginal =
                HTMLElement.prototype.getBoundingClientRect;
        }

        HTMLElement.prototype.getBoundingClientRect = function () {
            const rect = HTMLElement.prototype._getBoundingClientRectOriginal.call(this);
            const z = parseFloat(document.body.style.zoom) || 1;
            if (z === 1) return rect;
            return new DOMRect(rect.x / z, rect.y / z, rect.width / z, rect.height / z);
        };
    } else if (HTMLElement.prototype._getBoundingClientRectOriginal) {
        // Restore if previously patched (e.g. scale changed between platforms)
        HTMLElement.prototype.getBoundingClientRect =
            HTMLElement.prototype._getBoundingClientRectOriginal;
        delete HTMLElement.prototype._getBoundingClientRectOriginal;
    }
};

export function clearScale() {
    document.body.style.zoom = '';
    if (HTMLElement.prototype._getBoundingClientRectOriginal) {
        HTMLElement.prototype.getBoundingClientRect =
            HTMLElement.prototype._getBoundingClientRectOriginal;
        delete HTMLElement.prototype._getBoundingClientRectOriginal;
    }
};

export function getScaleAffectsPixels(scale) {
    const zoom = scale / 100.0;
    const testEl = document.createElement('div');
    testEl.style.cssText = 'position:fixed;top:0;left:0;width:100px;height:100px;pointer-events:none;margin:0;padding:0;';
    document.body.appendChild(testEl);

    const getRaw = HTMLElement.prototype._getBoundingClientRectOriginal ||
        HTMLElement.prototype.getBoundingClientRect;
    const rawRect = getRaw.call(testEl);
    document.body.removeChild(testEl);

    // width should be 100 if unscaled, or 100*zoom if browser scales it
    const factor = rawRect.width / 100;
    return Math.abs(factor - zoom) < Math.abs(factor - 1.0);
}