import {Dom, Util} from './util.js';

const dom = new Dom();

export class Image {

    constructor(builder) {

        // Set the libraries
        this.builder = builder;
        this.util = new Util(builder);
        this.builderStuff = this.util.builderStuff();

        // Set the active image
        this.activeImage = this.builder.activeImage;

        // If the image tool has not already been instantiated, then create it
        if (! this.builderStuff.querySelector('#divImageTool')) {

            // Create the dom object
            let html = ``;
            html += this.getImageToolHtml();
            html += this.getImageProgressHtml();
            html += this.getImageManagerHtml();
            html += this.getImageSelectHtml();
            dom.appendHtml(this.builderStuff, html);

            // Set the elements
            this.imageTool = this.builderStuff.querySelector('#divImageTool');
            this.imageManagerModal = this.builderStuff.querySelector('.imagelink');
            this.elementTool = this.builderStuff.querySelector('.is-element-tool');
            this.columnTool = this.builderStuff.querySelector('.is-column-tool')

            // Register the image manager functionality
            this.handleOpenImageManager();
            this.handleMode();
            this.handlePreset();
            this.handleLightBox();
            this.handleCta();
            this.handleImageManagerSelectExisting();
            this.handleImageManagerUpload();
            this.handleCloseImageManager();
            this.handleSaveImageManager();
        }
    }

    getImageToolHtml() {
        return `
            <div id="divImageTool" class="is-tool" style="background:rgba(0, 0, 0, 0.15); border:transparent 1px solid;">
                <button
                    title="Image Manager"
                    data-title="Image Manager"
                    class="image-link"
                    style="width:40px; height:40px; background:none; color:#fff;"
                >
                    <svg class="is-icon-flex" style="fill:rgb(255,255,255); width:14px; height:14px;">
                        <use xlink: href="#ion-android-create"></use>
                    </svg>
                </button>
            </div>
        `;
    }

    getImageProgressHtml() {
        return `
            <div id="divImageProgress">
                <div>
                    <div class="dot"></div>
                    <div class="dot"></div>
                    <div class="dot"></div>
                </div>
            </div>
        `;
    }

    getImageManagerHtml() {
        return `
            <div class="is-modal imagelink">
                <div style="max-width:526px;">

                    <div class="is-modal-bar" style="padding: 1rem;">
                        Image Manager
                    </div>

                    <div class="is-modal-body" style="padding: 1rem;">

                        <div class="form-group">
                            <label>Image Src</label>
                            <div style="display: flex;">

                                <input class="input-src" type="text" placeholder="Source"/>

                                <button title="Choose from image library" class="input-select" style="flex:none; width:50px; height:50px;">
                                    <svg class="is-icon-flex">
                                        <use xlink:href="#ion-more"></use>
                                    </svg>
                                </button>

                                <div class="image-larger1" style="position:relative; flex:none; width:50px; height:50px; box-shadow: 0 3px 6px -6px rgba(0, 0, 0, 0.32);">
                                    <form class="form-upload-larger"
                                          target="frameTargetImageUpload"
                                          method="post"
                                          action="${this.builder.opts.largerImageHandler}"
                                          enctype="multipart/form-data"
                                          style="position:absolute; top:0; left:0; width:100%; height:100%;"
                                    >
                                        <input id="hidRefId1" name="hidRefId" type="hidden" value="" />
                                        <input class="validation" name="_token" type="hidden" value="">

                                        <svg class="is-icon-flex" style="position: absolute; top: 16px; left: 15px; width: 18px; height: 18px; fill:rgb(53, 53, 53);">
                                            <use xlink:href="#ion-image"></use>
                                        </svg>

                                        <input title="Upload new image"
                                               id="fileImage1"
                                               name="fileImage"
                                               type="file"
                                               accept="image/*"
                                               style="position:absolute; top:-30px; left:0; width:100%; height:80px; opacity: 0; cursor: pointer;"
                                        >
                                    </form>

                                    <iframe id="frameTargetImageUpload"
                                            name="frameTargetImageUpload"
                                            src="about:blank"
                                            style="width:1px; height:1px; position:absolute; top:0; right:-100000px"
                                    ></iframe>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <label>Mode</label>
                            <select class="input-mode form-control custom-select" style="min-height: 48px; border-radius: 0;">
                                <option value="original">Use Original</option>
                                <option value="resize">Resize</option>
                                <option value="crop">Crop</option>
                                <option value="fit">Fit</option>
                                <option value="resizeCrop">Resize & Crop</option>
                                <option value="resizeFit">Resize & Fit</option>
                            </select>
                        </div>

                        <div class="form-group manipulation" style="display: none; align-items: center;">
                            <div style="margin-right: 1rem; width: 100%">
                                <label>Preset</label>
                                <select class="input-preset form-control custom-select" style="min-height: 48px; border-radius: 0;">
                                    <option value="thumb">Thumbnail - 150px</option>
                                    <option value="small">Small - 480px</option>
                                    <option value="medium">Medium - 720px</option>
                                    <option value="large">Large - 1600px</option>
                                    <option value="full">Full - 1920px</option>
                                    <option value="custom">Custom</option>
                                </select>
                            </div>
                            <div style="width: 100%">
                                <label>Quality</label>
                                <input class="input-quality" type="text" placeholder="80" style="width:100%;"/>
                            </div>
                        </div>

                        <div class="form-group dimensions" style="display: none; align-items: center; min-height: 45px;">
                            <div style="margin-right: 1rem; width: 100%;">
                                <label>Width</label>
                                <input class="input-width" type="text" placeholder="700" style="width:100%;"/>
                            </div>
                            <div style="width: 100%;">
                                <label>Height</label>
                                <input class="input-height" type="text" placeholder="500" style="width:100%;"/>
                            </div>
                        </div>

                        <div class="form-group">
                            <label>Alt Text</label>
                            <input class="input-title" type="text" placeholder="Alt text for image" style="width:100%;"/>
                        </div>

                        <div class="form-group" style="display: flex; align-items: center;">
                            <div id="lazy-block" style="margin-right: 1rem">
                                <label>
                                    <input class="input-lazy" type="checkbox" />
                                    Lazy Load
                                </label>
                            </div>
                            <div id="lightbox-block" style="margin-right: 1rem">
                                <label>
                                    <input class="input-lightbox" type="checkbox" />
                                    LightBox
                                </label>
                            </div>
                            <div id="cta-toggle" style="margin-right: 1rem">
                                <label>
                                    <input class="input-cta" type="checkbox" />
                                    Image Link
                                </label>
                            </div>
                        </div>

                        <div class="lightbox-group">
                            <div class="form-group">
                                <label>LightBox Group Id</label>
                                <input class="input-group-id"
                                        style="width:40px; height:40px;"
                                        type="text"
                                        placeholder="1"
                                        maxlength="2"
                                    />
                            </div>
                        </div>

                        <div class="cta-block" style="display: none;">
                            <div class="form-group">
                                <label>Link Title</label>
                                <input class="input-cta-title"
                                    type="text"
                                    placeholder="Click here to find out more"
                                />
                            </div>
                            <div class="form-group">
                                <label>Link URL</label>
                                <input class="input-cta-url"
                                    type="text"
                                    placeholder="/contact-us"
                                />
                            </div>
                            <div class="form-group">
                                <label>Link Target</label>
                                <select class="input-cta-target form-control custom-select" style="min-height: 45px;">
                                    <option value="_self">_self</option>
                                    <option value="_blank">_blank</option>
                                </select>
                            </div>
                        </div>
                    </div>

                    <div class="is-modal-actions" style="text-align:right">
                        <button title="Cancel" class="input-cancel classic-secondary">
                            Cancel
                        </button>
                        <button title="Ok" class="input-ok classic-primary">
                            Ok
                        </button>
                    </div>

                </div>
            </div>
        `;
    }

    getImageSelectHtml() {
        return `
            <div class="is-modal imageselect" style="z-index:10005">
                <div style="max-width:800px; height:80%; padding:0;">
                    <iframe style="width:100%; height:100%; border: none; display: block;" src="about:blank"></iframe>
                </div>
            </div>
        `;
    }

    resetActiveImage() {
        this.builder.activeImage = null;
        this.activeImage = null;
    }

    showColumnTool() {
        dom.addClass(this.columnTool, 'active');
    }
    hideColumnTool() {
        dom.removeClass(this.columnTool, 'active');
    }

    showImageTool() {
        this.imageTool.style.display = 'flex';
    }
    hideImageTool() {
        this.imageTool.style.display = '';
    }

    setImageToolPosition() {

        // to get value, element must not hidden (display:none).
        // So set display:flex before this.
        let imageToolWidth = this.imageTool.offsetWidth;

        // Get the width, top and left dimensions of the active image
        let w = this.activeImage.offsetWidth;
        let top = this.activeImage.getBoundingClientRect().top + window.pageYOffset;
        let left = this.activeImage.getBoundingClientRect().left;
        left = left + (w / 2 - imageToolWidth / 2);

        // Adjust left in case an element is outside the screen
        const screenWidth = window.innerWidth;
        if (imageToolWidth + left > screenWidth) {
            left = this.activeImage.getBoundingClientRect().left;
        }

        // Set the positioning on the image tool
        this.imageTool.style.top = top + 'px';
        this.imageTool.style.left = left + 'px';
    }

    hideElementTool() {
        this.elementTool.style.display = '';
    }

    handleOpenImageManager() {

        let imageLinkButton = this.imageTool.querySelector('.image-link');

        dom.addEventListener(imageLinkButton, 'click', () => {

            // If the upload image function has not been registered on the content builder then hide the field
            if (this.builder.opts.largerImageHandler === '') {
                this.imageManagerModal.querySelector('.image-larger1').style.display = 'none';
            }

            // If the select from existing images function has not been registered on the content builder then hide the field
            if (! this.builder.opts.onImageSelectClick && this.builder.opts.imageselect === '') {
                this.imageManagerModal.querySelector('.input-select').style.display = 'none';
            }

            // Fire the manual event to anyone who is listening
            if (this.builder.opts.onImageSettingClick) {
                this.builder.opts.onImageSettingClick();
                return false;
            }

            // Restore the modal options
            this.restoreImageSrc();
            this.restoreAltText();
            this.restoreMode();
            this.restoreQuality();
            this.restoreWidth();
            this.restoreHeight();
            this.restoreLazyLoad();
            this.restoreLightBox();
            this.restoreLightBoxGroup();
            this.restoreCta();

            // Show the modal window & focus on the src box
            this.util.showModal(this.imageManagerModal, true, null, true);
            this.imageManagerModal.querySelector('.input-src').focus();
        });
    }

    getImageSrcParams() {
        return new URLSearchParams(this.activeImage.getAttribute('src'));
    }
    getImageModes() {
        return [
            'original',
            'resize',
            'crop',
            'fit',
            'resizeCrop',
            'resizeFit'
        ]
    }
    getImageMode() {
        let mode = this.imageManagerModal.querySelector('.input-mode').value;

        let modes = this.getImageModes();
        if (mode && modes.indexOf(mode) !== -1) {
            return `mode=${mode}`;
        }

        return null;
    }
    getImageQuality() {
        let lazy = this.imageManagerModal.querySelector('.input-lazy');
        if ((lazy && lazy.checked) || dom.hasClass(this.activeImage, 'is-lazy')) {
            return '&q=5';
        }

        let quality = this.imageManagerModal.querySelector('.input-quality').value;
        if (quality) {
            return `&q=${quality}`;
        }

        return null;
    }
    getImagePresets() {
        return [
            'thumb',
            'small',
            'medium',
            'large',
            'full',
        ]
    }
    getImageDimensions() {
        let preset = this.imageManagerModal.querySelector('.input-preset').value;
        let width = this.imageManagerModal.querySelector('.input-width').value;
        let height = this.imageManagerModal.querySelector('.input-height').value;

        let presets = this.getImagePresets();
        if (preset && presets.indexOf(preset) !== -1) {
            return `&preset=${preset}`;
        }
        if (width && height) {
            return `&w=${width}&h=${height}`;
        }
        if (width) {
            return `&w=${width}`;
        }
        if (height) {
            return `&h=${height}`;
        }

        return null;
    }

    restoreImageSrc() {

        // If the active image does not contain base 64, Set the src box to match the active image src box
        let activeImageSrc = this.activeImage.getAttribute('src');
        let inputSrc = this.imageManagerModal.querySelector('.input-src');

        // If this is a base 64 image then bail
        if (activeImageSrc.indexOf('base64') !== -1) {
            inputSrc.value = '[Image Data]';
            return;
        }

        // If this is not a resizeable image then bail
        if (! activeImageSrc.includes('/photos/')) {
            inputSrc.value = activeImageSrc;
            return;
        }

        // Remove the domain if any, but keep the path, name and params
        const regex = new RegExp(/(\/photos\/)([0-9a-zA-z-_.]+)(\?[^#]+)?/g);
        let matches = regex.exec(activeImageSrc);

        // Set the base path / name
        if (matches[1]) {
            this.activeImage.setAttribute('data-path', matches[1]);
        }
        if (matches[2]) {
            this.activeImage.setAttribute('data-name', matches[2]);
        }

        // Set the modal input source to the cleaned url
        inputSrc.value = matches[0];
    }
    saveImageSrc() {
        let inputSrc = this.imageManagerModal.querySelector('.input-src').value;

        // If this is a base 64 image then bail
        if (inputSrc.includes('[Image Data]')) {
            return;
        }

        // If this is not a resizeable image then bail
        if (! inputSrc.includes('/photos/')) {
            this.activeImage.setAttribute('src', inputSrc);
            this.activeImage.setAttribute('data-src', inputSrc);
            this.activeImage.setAttribute('data-mfp-src', inputSrc);
            return;
        }

        // Remove the domain if any, but keep the path, name and params
        const regex = new RegExp(/(\/photos\/)([0-9a-zA-z-_.]+)(\?[^#]+)?/g);
        let matches = regex.exec(inputSrc);

        // Set the base path / name
        let cleanSrc = matches[0];
        if (matches[1]) {
            cleanSrc = matches[1];
            this.activeImage.setAttribute('data-path', matches[1]);
        }
        if (matches[2]) {
            cleanSrc += matches[2];
            this.activeImage.setAttribute('data-name', matches[2]);
        }

        // Rebuild the params based on the updated options
        let mode = this.getImageMode();
        let dimensions = this.getImageDimensions();
        let quality = this.getImageQuality();

        // Build the new src url and check for lazy load
        let srcUrl = `${cleanSrc}?`;
        let dataSrc = `${cleanSrc}?`;
        let dataMfpSrc = `${cleanSrc}?preset=full`;

        if (mode) {
            srcUrl += mode;
            dataSrc += mode;
            dataMfpSrc += '&' + mode;
        }
        if (dimensions) {
            srcUrl += dimensions;
            dataSrc += dimensions;
        }
        if (quality) {
            srcUrl += quality;
        }

        srcUrl.replace("null", "");
        dataSrc.replace("null", "");
        dataMfpSrc.replace("null", "");

        // Append the params
        this.activeImage.setAttribute('src', srcUrl);
        this.activeImage.setAttribute('data-src', dataSrc);
        this.activeImage.setAttribute('data-mfp-src', dataMfpSrc);
    }

    restoreAltText() {
        let activeImageAltTag = this.activeImage.getAttribute('alt');

        let inputTitle = this.imageManagerModal.querySelector('.input-title');
        inputTitle.value = null;

        if (activeImageAltTag !== 'null' && activeImageAltTag !== '[alt]') {
            inputTitle.value = activeImageAltTag;
        }
    }
    saveAltText() {
        let title = this.imageManagerModal.querySelector('.input-title').value;
        if (title !== '[alt]') {
            this.activeImage.setAttribute('alt', title);
        }
    }

    getMode() {
        // Try and get the data attribute
        if (this.activeImage.hasAttribute('data-mode')
            && this.activeImage.getAttribute('data-mode') !== 'null'
            && this.activeImage.getAttribute('data-mode') !== '[data_mode]'
        ) {
            return this.activeImage.getAttribute('data-mode');
        }

        // Otherwise check if it's in the url
        const params = this.getImageSrcParams();
        if (params && params.has('mode')) {
            this.activeImage.setAttribute('data-mode', params.get('mode'));
            return params.get('mode');
        }

        // Return a default value
        return 'resize';
    }
    restoreMode() {
        let mode = this.getMode();
        this.imageManagerModal.querySelector('.input-mode').value = mode;

        if (mode !== 'original') {
            this.restorePreset();
            this.showManipulationBlock();

        } else {
            this.hideManipulationBlock();
        }
    }
    saveMode() {
        let mode = this.imageManagerModal.querySelector('.input-mode').value;
        if (mode !== '[data_mode]') {
            this.activeImage.setAttribute('data-mode', mode);
        }
    }
    handleMode() {
        let inputMode = this.imageManagerModal.querySelector('.input-mode');

        dom.addEventListener(inputMode, 'change', () => {
            if (inputMode.value !== 'original') {
                this.restorePreset();
                this.showManipulationBlock();
            } else {
                this.hideManipulationBlock();
            }
        });
    }

    getQuality() {
        // Try and get the data attribute
        if (this.activeImage.hasAttribute('data-quality')
            && this.activeImage.getAttribute('data-quality') !== 'null'
        ) {
            return this.activeImage.getAttribute('data-quality');
        }

        // Return a default value
        return '80';
    }
    restoreQuality() {
        this.imageManagerModal.querySelector('.input-quality').value = this.getQuality();
    }
    saveQuality() {
        let quality = this.imageManagerModal.querySelector('.input-quality').value;
        if (quality !== '[data_quality]') {
            this.activeImage.setAttribute('data-quality', quality);
        }
    }

    getPreset() {
        // Try and get the data attribute
        if (this.activeImage.hasAttribute('data-preset')
            && this.activeImage.getAttribute('data-preset') !== 'null'
            && this.activeImage.getAttribute('data-preset') !== '[data_preset]'
        ) {
            return this.activeImage.getAttribute('data-preset');
        }

        // Otherwise check if it's in the url
        const params = this.getImageSrcParams();
        if (params && params.has('preset')) {
            this.activeImage.setAttribute('data-preset', params.get('preset'));
            return params.get('preset');
        }

        // Return a default value
        return 'medium';
    }
    restorePreset() {
        let preset = this.getPreset();
        this.imageManagerModal.querySelector('.input-preset').value = preset;

        if (preset === 'custom') {
            this.showDimensionsBlock();
        } else {
            this.hideDimensionsBlock();
        }
    }
    savePreset() {
        let preset = this.imageManagerModal.querySelector('.input-preset').value;
        if (preset !== '[data_preset]') {
            this.activeImage.setAttribute('data-preset', preset);
        }
    }
    handlePreset() {
        let inputPreset = this.imageManagerModal.querySelector('.input-preset');

        dom.addEventListener(inputPreset, 'change', () => {
            if (inputPreset.value === 'custom') {
                this.showDimensionsBlock();
            } else {
                this.hideDimensionsBlock();
            }
        });
    }

    showManipulationBlock() {
        this.imageManagerModal.querySelector('.manipulation').style.display = 'flex';
    }
    hideManipulationBlock() {
        this.imageManagerModal.querySelector('.manipulation').style.display = 'none';
    }

    getWidth() {
        // Try and get the data attribute
        if (this.activeImage.hasAttribute('data-width')
            && this.activeImage.getAttribute('data-width') !== 'null'
            && this.activeImage.getAttribute('data-width') !== '[data_width]'
        ) {
            return this.activeImage.getAttribute('data-width');
        }

        // Otherwise check if it's in the url
        const params = this.getImageSrcParams();
        if (params && params.has('w')) {
            this.activeImage.setAttribute('data-width', params.get('w'));
            return params.get('w');
        }

        // Return a default value
        return 800;
    }
    saveWidth() {
        let width = this.imageManagerModal.querySelector('.input-width').value;
        if (width !== '[data_width]') {
            this.activeImage.setAttribute('data-width', width);
        }
    }
    restoreWidth() {
        this.imageManagerModal.querySelector('.input-width').value = this.getWidth();
    }

    getHeight() {
        // Try and get the data attribute
        if (this.activeImage.hasAttribute('data-height')
            && this.activeImage.getAttribute('data-height') !== 'null'
            && this.activeImage.getAttribute('data-height') !== '[data_height]'
        ) {
            return this.activeImage.getAttribute('data-height');
        }

        // Otherwise check if it's in the url
        const params = this.getImageSrcParams();
        if (params && params.has('h')) {
            this.activeImage.setAttribute('data-height', params.get('h'));
            return params.get('h');
        }

        // Return a default value
        return 450;
    }
    saveHeight() {
        let height = this.imageManagerModal.querySelector('.input-height').value;
        if (height !== '[data_height]') {
            this.activeImage.setAttribute('data-height', height);
        }
    }
    restoreHeight() {
        this.imageManagerModal.querySelector('.input-height').value = this.getHeight();
    }

    showDimensionsBlock() {
        this.imageManagerModal.querySelector('.dimensions').style.display = 'flex';
    }
    hideDimensionsBlock() {
        this.imageManagerModal.querySelector('.dimensions').style.display = 'none';
    }

    getLazyLoad() {

        // Try and get the attribute
        if (this.activeImage.hasAttribute('loading')
            && this.activeImage.getAttribute('loading') === 'lazy'
        ) {
            return true;
        }

        // Or do we have a class
        if (dom.hasClass(this.activeImage, 'lazyload') || dom.hasClass(this.activeImage, 'is-lazy')) {
            return true;
        }

        // Otherwise check the url
        const params = this.getImageSrcParams();
        if (params && params.has('q') && parseInt(params.get('q')) === 5) {
            return true;
        }

        // Return a default
        return false;
    }
    restoreLazyLoad() {

        if (this.getLazyLoad()) {
            this.checkLazyLoad();
        } else {
            this.unCheckLazyLoad();
        }

        // Hide lazy load option for slider and carousel
        if (dom.hasClass(this.activeImage, 'owl-image')) {
            this.hideLazyLoadBlock();
        } else {
            this.showLazyLoadBlock();
        }
    }
    saveLazyLoad() {
        let lazy = this.imageManagerModal.querySelector('.input-lazy');

        if (lazy && lazy.checked
            && ! dom.hasClass(this.activeImage, 'owl-image')
        ) {
            dom.addClass(this.activeImage, 'lazyload');
            this.activeImage.removeAttribute('loading');
            //this.activeImage.setAttribute('loading', 'lazy');
        } else {
            dom.removeClass(this.activeImage, 'lazyload');
            this.activeImage.removeAttribute('loading');
        }
    }
    checkLazyLoad() {
        this.imageManagerModal.querySelector('.input-lazy').checked = true;
    }
    unCheckLazyLoad() {
        this.imageManagerModal.querySelector('.input-lazy').checked = false;
    }
    showLazyLoadBlock() {
        this.imageManagerModal.querySelector('#lazy-block').style.display = 'block';
    }
    hideLazyLoadBlock() {
        this.imageManagerModal.querySelector('#lazy-block').style.display = 'none';
    }

    restoreLightBox() {
        if (dom.hasClass(this.activeImage, 'has-lightbox') && ! dom.hasClass(this.activeImage, 'has-cta')) {
            this.checkLightBox();
            this.showLightBoxGroup();
        } else {
            this.unCheckLightBox();
            this.hideLightBoxGroup();
        }
    }
    saveLightBox() {
        let lightbox = this.imageManagerModal.querySelector('.input-lightbox');
        let cta = this.imageManagerModal.querySelector('.input-cta');

        if ((lightbox && lightbox.checked) && (! cta || ! cta.checked)) {
            dom.addClass(this.activeImage, 'has-lightbox');
        } else {
            dom.removeClass(this.activeImage, 'has-lightbox');
        }
    }
    handleLightBox() {
        let inputLightBox = this.imageManagerModal.querySelector('.input-lightbox');

        dom.addEventListener(inputLightBox, 'change', () => {
            if (inputLightBox.checked) {
                this.showLightBoxGroup();
                this.unCheckCta();
                this.hideCtaBlock();
            } else {
                this.hideLightBoxGroup();
            }
        });
    }
    checkLightBox() {
        this.imageManagerModal.querySelector('.input-lightbox').checked = true;
    }
    unCheckLightBox() {
        this.imageManagerModal.querySelector('.input-lightbox').checked = false;
    }

    restoreLightBoxGroup() {
        let groupId = this.activeImage.getAttribute('data-group');
        this.imageManagerModal.querySelector('.input-group-id').value = groupId || 1;
    }
    saveLightBoxGroup() {
        let group = this.imageManagerModal.querySelector('.input-group-id').value;
        this.activeImage.setAttribute('data-group', group);
    }
    showLightBoxGroup() {
        this.imageManagerModal.querySelector('.lightbox-group').style.display = 'block';
    }
    hideLightBoxGroup() {
        this.imageManagerModal.querySelector('.lightbox-group').style.display = 'none';
    }

    restoreCta() {
        if (dom.hasClass(this.activeImage, 'has-cta')
            && ! dom.hasClass(this.activeImage, 'has-lightbox')
            && ! dom.hasClass(this.activeImage, 'owl-image')
        ) {
            this.imageManagerModal.querySelector('.input-cta-title').value = this.activeImage.getAttribute('data-cta-title');
            this.imageManagerModal.querySelector('.input-cta-url').value = this.activeImage.getAttribute('data-cta-url');
            this.imageManagerModal.querySelector('.input-cta-target').value = this.activeImage.getAttribute('data-cta-target');
            this.checkCta();
            this.showCtaBlock();
        } else {
            this.unCheckCta();
            this.hideCtaBlock();
        }

        if (dom.hasClass(this.activeImage, 'owl-image')) {
            this.imageManagerModal.querySelector('#cta-toggle').style.display = 'none';
        } else {
            this.imageManagerModal.querySelector('#cta-toggle').style.display = 'block';
        }
    }
    saveCta() {
        let cta = this.imageManagerModal.querySelector('.input-cta');
        let ctaTitle = this.imageManagerModal.querySelector('.input-cta-title').value;
        let ctaUrl = this.imageManagerModal.querySelector('.input-cta-url').value;
        let ctaTarget = this.imageManagerModal.querySelector('.input-cta-target').value;
        let lightbox = this.imageManagerModal.querySelector('.input-lightbox');

        // Call to action
        if ((cta && cta.checked) && (! lightbox || ! lightbox.checked)) {
            dom.addClass(this.activeImage, 'has-cta');
            this.activeImage.setAttribute('data-cta-title', ctaTitle);
            this.activeImage.setAttribute('data-cta-url', ctaUrl);
            this.activeImage.setAttribute('data-cta-target', ctaTarget);

        } else {
            dom.removeClass(this.activeImage, 'has-cta');
            this.activeImage.removeAttribute('data-cta-title');
            this.activeImage.removeAttribute('data-cta-url');
            this.activeImage.removeAttribute('data-cta-target');
        }
    }
    handleCta() {
        let inputCta = this.imageManagerModal.querySelector('.input-cta');

        dom.addEventListener(inputCta, 'change', () => {
            if (inputCta.checked) {
                this.showCtaBlock();
                this.unCheckLightBox();
                this.hideLightBoxGroup();
            } else {
                this.hideCtaBlock();
            }
        });
    }
    checkCta() {
        this.imageManagerModal.querySelector('.input-cta').checked = true;
    }
    unCheckCta() {
        this.imageManagerModal.querySelector('.input-cta').checked = false;
    }
    showCtaBlock() {
        this.imageManagerModal.querySelector('.cta-block').style.display = 'block';
    }
    hideCtaBlock() {
        this.imageManagerModal.querySelector('.cta-block').style.display = 'none';
    }

    handleImageManagerSelectExisting() {

        let divImageSrc = this.imageManagerModal.querySelector('.image-src');

        if (this.builder.opts.onImageSelectClick || this.builder.opts.imageselect) {

            let selectExistingImage = this.imageManagerModal.querySelector('.input-select');

            if (selectExistingImage) {
                dom.addEventListener(selectExistingImage, 'click', () => {

                    if (this.builder.opts.onImageSelectClick) {
                        this.builder.opts.onImageSelectClick({
                            targetInput : this.imageManagerModal.querySelector('.input-src'),
                            theTrigger : selectExistingImage
                        });

                    } else {
                        let modalImageSelect = this.builderStuff.querySelector('.is-modal.imageselect');

                        let iframe = modalImageSelect.querySelector('iframe');
                        if (iframe.src === 'about:blank') {
                            iframe.src = this.builder.opts.imageselect;
                        }

                        this.util.showModal(modalImageSelect);
                    }
                });
            }

        } else {
            dom.removeClass(divImageSrc, 'image-select');
        }
    }

    handleImageManagerUpload() {

        let fileLargerImage1 = this.imageManagerModal.querySelector('#fileImage1');

        dom.addEventListener(fileLargerImage1, 'change', (e) => {

            let element = fileLargerImage1;
            while (element.nodeName.toLowerCase() !== 'form') {
                element = element.parentNode;
            }

            let frmUpload = element;
            dom.addClass(frmUpload, 'please-wait');
            this.imageManagerModal.querySelector('#hidRefId1').value = this.builder.opts.customval;

            let token = parent.document.head.querySelector('meta[name="csrf-token"]');
            if (token) {
                this.imageManagerModal.querySelector('input[name="_token"]').value = token.content;
            }

            if (this.builder.opts.onLargerImageUpload) {
                this.builder.opts.onLargerImageUpload(e);
            } else {
                frmUpload.submit();
            }
        });
    }

    handleSaveImageManager() {

        // Handle the ok btn
        let saveBtn = this.imageManagerModal.querySelector('.input-ok');

        dom.addEventListener(saveBtn, 'click', () => {
            this.builder.uo.saveForUndo();

            // Save the modal options
            this.saveImageSrc();
            this.saveAltText();

            this.saveMode();
            this.saveQuality();
            this.savePreset();
            this.saveWidth();
            this.saveHeight();

            this.saveLazyLoad();
            this.saveLightBox();
            this.saveLightBoxGroup();
            this.saveCta();

            // Check if image is part of module snippet.
            // If so, refresh the (active) module (hide imageTool).
            // If not, refresh imageTool position
            this.refreshIfIsModule(this.activeImage);

            //Trigger Change event
            this.builder.opts.onChange();

            //Trigger Render event
            this.builder.opts.onRender();

            this.util.hideModal(this.imageManagerModal);

            this.builder.elmTool.refresh();
        });
    }

    handleCloseImageManager() {

        let cancelBtn = this.imageManagerModal.querySelector('.input-cancel');

        dom.addEventListener(cancelBtn, 'click', () => {
            this.util.hideModal(this.imageManagerModal);
        });
    }

    refreshIfIsModule(elm) {

        let isModule = dom.parentsHasAttribute(elm, 'data-html');

        if (isModule) {
            this.hideImageTool();

            // Extra: make image[data-image-embed] clickable/editable
            if (elm.hasAttribute('data-sync')
                && ! dom.hasClass(elm, 'owl-image')
                && ! dom.hasClass(elm, 'lazyload')
                && ! dom.hasClass(elm, 'is-lazy')
            ) {
                let originalSrc = elm.getAttribute('data-src');
                let originalFilename = elm.getAttribute('data-filename');

                if (originalSrc) {
                    let element = elm;
                    while (! element.getAttribute('data-html')) {
                        element = element.parentNode;
                    }

                    let module = element;
                    let imgs = module.querySelectorAll('img');

                    Array.prototype.forEach.call(imgs, (img) => {
                        if (img.src === originalSrc) {
                            img.src = elm.src;
                            img.removeAttribute('data-src');
                            img.setAttribute('data-filename', originalFilename);
                        }
                    });

                    elm.removeAttribute('data-src');
                }
            }

            setTimeout(() => {
                this.util.refreshModule();
                this.hideImageTool();
            }, 1000);

        } else {
            this.refresh();
        }
    }
    refresh() {

        if (this.activeImage) {
            this.hideImageTool();

            setTimeout(() => {
                this.showImageTool();
                this.setImageToolPosition();

                // when there is image link applied
                if (this.activeImage.offsetWidth === 0) {
                    this.hideImageTool();
                    this.resetActiveImage();
                }

            }, 300);
        }
    }
    repositionImageTool() {

        if (this.builder.activeImage) {
            this.showImageTool();
            this.setImageToolPosition();
        }
    }
    click(e) {
        const elm = e.target;

        // If the element that was clicked is is not an image or its fixed then bail
        if (elm.tagName.toLowerCase() !== 'img' || elm.hasAttribute('data-fixed')) {
            this.resetActiveImage();
            this.hideImageTool();
            return;
        }

        // Set the active image
        this.builder.activeImage = elm;
        this.activeImage = elm;

        // Set the image tool position
        this.showImageTool();
        this.setImageToolPosition();
    }
}

export default Image;
