/** @odoo-module */

import publicWidget from 'web.public.widget';

export const SurveyImageZoomer = publicWidget.Widget.extend({
    template: 'survey.survey_image_zoomer',
    events: {
        'wheel .o_survey_img_zoom_image': '_onImgScroll',
        'click': '_onZoomerClick',
        'click .o_survey_img_zoom_in_btn': '_onZoomInClick',
        'click .o_survey_img_zoom_out_btn': '_onZoomOutClick',
    },
    /**
     * @override
     */
    init(params) {
        this.zoomImageScale = 1;
        // The image is needed to render the template survey_image_zoom.
        this.sourceImage = params.sourceImage;
        this._super(... arguments);
    },
    /**
     * Open a transparent modal displaying the survey choice image.
     * @override
     */
    async start() {
        const superResult = await this._super(...arguments);
        // Prevent having hidden modal in the view.
        this.$el.on('hidden.bs.modal', () => this.destroy());
        this.$el.modal('show');
        return superResult;
    },

    //--------------------------------------------------------------------------
    // Handlers
    //--------------------------------------------------------------------------

    /**
     * Zoom in/out image on scrolling
     *
     * @private
     * @param {WheelEvent} e
     */
    _onImgScroll(e) {
        e.preventDefault();
        if (e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
            this._addZoomSteps(1);
        } else {
            this._addZoomSteps(-1);
        }
    },
    /**
     * Allow user to close by clicking anywhere (mobile...). Destroying the modal
     * without using 'hide' would leave a modal-open in the view.
     * @private
     * @param {Event} e
     */
     _onZoomerClick(e) {
        e.preventDefault();
        this.$el.modal('hide');
    },
    /**
     * @private
     * @param {Event} e
     */
    _onZoomInClick(e) {
        e.stopPropagation();
        this._addZoomSteps(1);
    },
    /**
     * @private
     * @param {Event} e
     */
    _onZoomOutClick(e) {
        e.stopPropagation();
        this._addZoomSteps(-1);
    },

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * Zoom in / out the image by changing the scale by the given number of steps.
     *
     * @private
     * @param {integer} zoomStepNumber - Number of zoom steps applied to the scale of
     * the image. It can be negative, in order to zoom out. Step is set to 0.1.
     */
     _addZoomSteps(zoomStepNumber) {
        const image = this.el.querySelector('.o_survey_img_zoom_image');
        const body = this.el.querySelector('.o_survey_img_zoom_body');
        const imageWidth = image.clientWidth;
        const imageHeight = image.clientHeight;
        const bodyWidth = body.clientWidth;
        const bodyHeight = body.clientHeight;
        const newZoomImageScale = this.zoomImageScale + zoomStepNumber * 0.1;
        if (newZoomImageScale <= 0.2) {
            // Prevent the user from de-zooming too much
            return;
        }
        if (zoomStepNumber > 0 && (imageWidth * newZoomImageScale > bodyWidth || imageHeight * newZoomImageScale > bodyHeight)) {
            // Prevent to user to further zoom in as the new image would becomes too large or too high for the screen.
            // Dezooming is still allowed to bring back image into frame (use case: resizing screen).
            return;
        }
        // !important is needed to prevent default 'no-transform' on smaller screens.
        image.setAttribute('style', 'transform: scale(' + newZoomImageScale + ') !important');
        this.zoomImageScale = newZoomImageScale;
    },
});
