/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */
var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};define(["require","exports","jquery","TYPO3/CMS/Backend/FormEngineValidation","TYPO3/CMS/Core/Ajax/AjaxRequest","cropperjs","imagesloaded","./Icons","./Modal","jquery-ui/draggable","jquery-ui/resizable"],(function(t,e,r,a,i,s,o,n,c){"use strict";r=__importDefault(r),s=__importDefault(s);class h{constructor(){this.initialized=!1,this.cropImageContainerSelector="#t3js-crop-image-container",this.cropImageSelector="#t3js-crop-image",this.coverAreaSelector=".t3js-cropper-cover-area",this.cropInfoSelector=".t3js-cropper-info-crop",this.focusAreaSelector="#t3js-cropper-focus-area",this.cropBox=(0,r.default)(),this.defaultFocusArea={height:1/3,width:1/3,x:0,y:0},this.defaultOpts={autoCrop:!0,autoCropArea:.7,dragMode:"crop",guides:!0,responsive:!0,viewMode:1,zoomable:!1,checkCrossOrigin:!1},this.cropBuiltHandler=()=>{this.initialized=!0;const t=this.cropper.getImageData(),e=this.currentModal.find(this.cropImageSelector);this.currentModal.find(".cropper-canvas img").removeClass("cropper-hide"),this.imageOriginalSizeFactor=e.data("originalWidth")/t.naturalWidth,this.cropVariantTriggers.each((e,a)=>{const i=(0,r.default)(a).attr("data-crop-variant-id"),s=this.convertRelativeToAbsoluteCropArea(this.data[i].cropArea,t),o=r.default.extend(!0,{},this.data[i],{cropArea:s});this.updatePreviewThumbnail(o,(0,r.default)(a))}),this.currentCropVariant.cropArea=this.convertRelativeToAbsoluteCropArea(this.currentCropVariant.cropArea,t),this.cropBox=this.currentModal.find(".cropper-crop-box"),this.setCropArea(this.currentCropVariant.cropArea),this.currentCropVariant.coverAreas&&this.initCoverAreas(this.cropBox,this.currentCropVariant.coverAreas),this.currentCropVariant.focusArea&&(h.isEmptyArea(this.currentCropVariant.focusArea)&&(this.currentCropVariant.focusArea=r.default.extend(!0,{},this.defaultFocusArea)),this.initFocusArea(this.cropBox),this.scaleAndMoveFocusArea(this.currentCropVariant.focusArea)),this.currentCropVariant.selectedRatio&&this.currentModal.find(`[data-bs-option='${this.currentCropVariant.selectedRatio}']`).addClass("active")},this.cropMoveHandler=t=>{if(!this.initialized)return;let e=Math.ceil(t.detail.width),a=Math.ceil(t.detail.height);(e<15||a<15)&&(e=Math.max(15,a),a=Math.max(15,e),this.cropper.setData({width:e,height:a})),this.currentCropVariant.cropArea=r.default.extend(!0,this.currentCropVariant.cropArea,{width:Math.floor(e),height:Math.floor(a),x:Math.floor(t.detail.x),y:Math.floor(t.detail.y)}),this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger),this.updateCropVariantData(this.currentCropVariant);const i=Math.round(this.currentCropVariant.cropArea.width*this.imageOriginalSizeFactor),s=Math.round(this.currentCropVariant.cropArea.height*this.imageOriginalSizeFactor);this.cropInfo.text(`${i}×${s} px`)},this.cropStartHandler=()=>{this.currentCropVariant.focusArea&&(this.focusArea.draggable("option","disabled",!0),this.focusArea.resizable("option","disabled",!0))},this.cropEndHandler=()=>{this.currentCropVariant.focusArea&&(this.focusArea.draggable("option","disabled",!1),this.focusArea.resizable("option","disabled",!1))}}static isEmptyArea(t){return r.default.isEmptyObject(t)}static wait(t,e){window.setTimeout(t,e)}static toCssPercent(t){return 100*t+"%"}static serializeCropVariants(t){return JSON.stringify(t,(t,e)=>"id"===t||"title"===t||"allowedAspectRatios"===t||"coverAreas"===t?void 0:e)}initializeTrigger(){(0,r.default)(".t3js-image-manipulation-trigger").off("click").on("click",t=>{t.preventDefault(),this.trigger=(0,r.default)(t.currentTarget),this.show()})}initializeCropperModal(){const t=this.currentModal.find(this.cropImageSelector);o(t.get(0),()=>{this.init()})}show(){const t=this.trigger.data("modalTitle"),e=this.trigger.data("buttonPreviewText"),a=this.trigger.data("buttonDismissText"),s=this.trigger.data("buttonSaveText"),o=this.trigger.data("url"),h=this.trigger.data("payload");n.getIcon("spinner-circle",n.sizes.default,null,null,n.markupIdentifiers.inline).then(n=>{this.currentModal=c.advanced({additionalCssClasses:["modal-image-manipulation"],buttons:[{btnClass:"btn-default float-start",dataAttributes:{method:"preview"},icon:"actions-view",text:e},{btnClass:"btn-default",dataAttributes:{method:"dismiss"},icon:"actions-close",text:a},{btnClass:"btn-primary",dataAttributes:{method:"save"},icon:"actions-document-save",text:s}],content:(0,r.default)('<div class="modal-loading">').append(n),size:c.sizes.full,style:c.styles.dark,title:t}),this.currentModal.on("shown.bs.modal",()=>{new i(o).post(h).then(async t=>{this.currentModal.find(".t3js-modal-body").append(await t.resolve()).addClass("cropper"),this.currentModal.find(".modal-loading").remove(),this.initializeCropperModal()})}),this.currentModal.on("hide.bs.modal",()=>{this.destroy()}),this.currentModal.css("pointer-events","none")})}init(){const t=this.currentModal.find(this.cropImageSelector),e=this.trigger.attr("data-crop-variants");if(!e)throw new TypeError("ImageManipulation: No cropVariants data found for image");this.data=r.default.isEmptyObject(this.data)?JSON.parse(e):this.data,this.cropVariantTriggers=this.currentModal.find(".t3js-crop-variant-trigger"),this.activeCropVariantTrigger=this.currentModal.find(".t3js-crop-variant-trigger.is-active"),this.cropInfo=this.currentModal.find(this.cropInfoSelector),this.saveButton=this.currentModal.find("[data-method=save]"),this.previewButton=this.currentModal.find("[data-method=preview]"),this.dismissButton=this.currentModal.find("[data-method=dismiss]"),this.resetButton=this.currentModal.find("[data-method=reset]"),this.aspectRatioTrigger=this.currentModal.find("[data-method=setAspectRatio]"),this.currentCropVariant=this.data[this.activeCropVariantTrigger.attr("data-crop-variant-id")],this.cropVariantTriggers.off("click").on("click",t=>{if((0,r.default)(t.currentTarget).hasClass("is-active"))return t.stopPropagation(),void t.preventDefault();this.activeCropVariantTrigger.removeClass("is-active"),(0,r.default)(t.currentTarget).addClass("is-active"),this.activeCropVariantTrigger=(0,r.default)(t.currentTarget);const e=this.data[this.activeCropVariantTrigger.attr("data-crop-variant-id")],a=this.cropper.getImageData();e.cropArea=this.convertRelativeToAbsoluteCropArea(e.cropArea,a),this.currentCropVariant=r.default.extend(!0,{},e),this.update(e)}),this.aspectRatioTrigger.off("click").on("click",t=>{const e=(0,r.default)(t.currentTarget).attr("data-bs-option"),a=r.default.extend(!0,{},this.currentCropVariant),i=a.allowedAspectRatios[e];this.setAspectRatio(i),this.setCropArea(a.cropArea),this.currentCropVariant=r.default.extend(!0,{},a,{selectedRatio:e}),this.update(this.currentCropVariant)}),this.saveButton.off("click").on("click",()=>{this.save(this.data)}),this.trigger.attr("data-preview-url")?this.previewButton.off("click").on("click",()=>{this.openPreview(this.data)}):this.previewButton.hide(),this.dismissButton.off("click").on("click",()=>{this.currentModal.modal("hide")}),this.resetButton.off("click").on("click",t=>{const e=this.cropper.getImageData(),a=(0,r.default)(t.currentTarget).attr("data-crop-variant");if(t.preventDefault(),t.stopPropagation(),!a)throw new TypeError("TYPO3 Cropper: No cropVariant data attribute found on reset element.");const i=JSON.parse(a),s=this.convertRelativeToAbsoluteCropArea(i.cropArea,e);this.currentCropVariant=r.default.extend(!0,{},i,{cropArea:s}),this.update(this.currentCropVariant)}),h.isEmptyArea(this.currentCropVariant.cropArea)&&(this.defaultOpts=r.default.extend({autoCropArea:1},this.defaultOpts)),this.cropper=new s.default(t.get(0),r.default.extend(this.defaultOpts,{ready:this.cropBuiltHandler,crop:this.cropMoveHandler,cropend:this.cropEndHandler,cropstart:this.cropStartHandler,data:this.currentCropVariant.cropArea})),this.update(this.currentCropVariant)}update(t){const e=r.default.extend(!0,{},t),a=t.allowedAspectRatios[t.selectedRatio];this.currentModal.find("[data-bs-option]").removeClass("active"),this.currentModal.find(`[data-bs-option="${t.selectedRatio}"]`).addClass("active"),this.setAspectRatio(a),this.setCropArea(e.cropArea),this.currentCropVariant=r.default.extend(!0,{},e,t),this.cropBox.find(this.coverAreaSelector).remove(),this.cropBox.has(this.focusAreaSelector).length&&(this.focusArea.resizable("destroy").draggable("destroy"),this.focusArea.remove()),t.focusArea&&(h.isEmptyArea(t.focusArea)&&(this.currentCropVariant.focusArea=r.default.extend(!0,{},this.defaultFocusArea)),this.initFocusArea(this.cropBox),this.scaleAndMoveFocusArea(this.currentCropVariant.focusArea)),t.coverAreas&&this.initCoverAreas(this.cropBox,this.currentCropVariant.coverAreas),this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger)}initFocusArea(t){this.focusArea=(0,r.default)('<div id="t3js-cropper-focus-area" class="cropper-focus-area"></div>'),t.append(this.focusArea),this.focusArea.draggable({containment:t,create:()=>{const t="undefined"!=typeof window&&void 0!==window.document,e=!(!t||!window.document.documentElement)&&"ontouchstart"in window.document.documentElement,r=!!t&&"PointerEvent"in window,a=r?"pointerdown":e?"touchstart":"mousedown",i=r?"pointerup pointercancel":e?"touchend touchcancel":"mouseup";this.focusArea.on(a,()=>{this.cropper.disable()}),this.focusArea.on(i,()=>{this.cropper.enable()}),this.scaleAndMoveFocusArea(this.currentCropVariant.focusArea)},drag:()=>{const{left:e,top:r}=t.offset(),{left:a,top:i}=this.focusArea.offset(),{focusArea:s,coverAreas:o}=this.currentCropVariant;s.x=(a-e)/t.width(),s.y=(i-r)/t.height(),this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger),this.checkFocusAndCoverAreasCollision(s,o)?this.focusArea.addClass("has-nodrop"):this.focusArea.removeClass("has-nodrop")},revert:()=>{const{left:e,top:r}=t.offset(),{left:a,top:i}=this.focusArea.offset(),{focusArea:s,coverAreas:o}=this.currentCropVariant;return!!this.checkFocusAndCoverAreasCollision(s,o)&&(this.focusArea.removeClass("has-nodrop"),h.wait(()=>{s.x=(a-e)/t.width(),s.y=(i-r)/t.height(),this.updateCropVariantData(this.currentCropVariant)},250),!0)},revertDuration:200,stop:()=>{const{left:e,top:r}=t.offset(),{left:a,top:i}=this.focusArea.offset(),{focusArea:s}=this.currentCropVariant;s.x=(a-e)/t.width(),s.y=(i-r)/t.height(),this.scaleAndMoveFocusArea(s)}}).resizable({containment:t,handles:"all",resize:()=>{const{left:e,top:r}=t.offset(),{left:a,top:i}=this.focusArea.offset(),{focusArea:s,coverAreas:o}=this.currentCropVariant;s.height=this.focusArea.height()/t.height(),s.width=this.focusArea.width()/t.width(),s.x=(a-e)/t.width(),s.y=(i-r)/t.height(),this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger),this.checkFocusAndCoverAreasCollision(s,o)?this.focusArea.addClass("has-nodrop"):this.focusArea.removeClass("has-nodrop")},stop:(e,a)=>{const{left:i,top:s}=t.offset(),{left:o,top:n}=this.focusArea.offset(),{focusArea:c,coverAreas:h}=this.currentCropVariant;this.checkFocusAndCoverAreasCollision(c,h)?a.element.animate(r.default.extend(a.originalPosition,a.originalSize),250,()=>{c.height=this.focusArea.height()/t.height(),c.width=this.focusArea.width()/t.width(),c.x=(o-i)/t.width(),c.y=(n-s)/t.height(),this.scaleAndMoveFocusArea(c),this.focusArea.removeClass("has-nodrop")}):this.scaleAndMoveFocusArea(c)}})}initCoverAreas(t,e){e.forEach(e=>{const a=(0,r.default)('<div class="cropper-cover-area t3js-cropper-cover-area"></div>');t.append(a),a.css({height:h.toCssPercent(e.height),left:h.toCssPercent(e.x),top:h.toCssPercent(e.y),width:h.toCssPercent(e.width)})})}updatePreviewThumbnail(t,e){let r;const a=e.find(".t3js-cropper-preview-thumbnail-crop-area"),i=e.find(".t3js-cropper-preview-thumbnail-crop-image"),s=e.find(".t3js-cropper-preview-thumbnail-focus-area"),o=this.cropper.getImageData();a.css({height:h.toCssPercent(t.cropArea.height/o.naturalHeight),left:h.toCssPercent(t.cropArea.x/o.naturalWidth),top:h.toCssPercent(t.cropArea.y/o.naturalHeight),width:h.toCssPercent(t.cropArea.width/o.naturalWidth)}),t.focusArea&&s.css({height:h.toCssPercent(t.focusArea.height),left:h.toCssPercent(t.focusArea.x),top:h.toCssPercent(t.focusArea.y),width:h.toCssPercent(t.focusArea.width)}),r=a.css(["width","height","left","top"]),i.css({height:parseFloat(r.height)*(1/(t.cropArea.height/o.naturalHeight))+"px",margin:-1*parseFloat(r.left)+"px",marginTop:-1*parseFloat(r.top)+"px",width:parseFloat(r.width)*(1/(t.cropArea.width/o.naturalWidth))+"px"})}scaleAndMoveFocusArea(t){this.focusArea.css({height:h.toCssPercent(t.height),left:h.toCssPercent(t.x),top:h.toCssPercent(t.y),width:h.toCssPercent(t.width)}),this.currentCropVariant.focusArea=t,this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger),this.updateCropVariantData(this.currentCropVariant)}updateCropVariantData(t){const e=this.cropper.getImageData(),a=this.convertAbsoluteToRelativeCropArea(t.cropArea,e);this.data[t.id]=r.default.extend(!0,{},t,{cropArea:a})}setAspectRatio(t){this.cropper.setAspectRatio(t.value)}setCropArea(t){const e=this.currentCropVariant.allowedAspectRatios[this.currentCropVariant.selectedRatio];0===e.value?this.cropper.setData({height:t.height,width:t.width,x:t.x,y:t.y}):this.cropper.setData({height:t.height,width:t.height*e.value,x:t.x,y:t.y})}checkFocusAndCoverAreasCollision(t,e){return!!e&&e.some(e=>t.x<e.x+e.width&&t.x+t.width>e.x&&t.y<e.y+e.height&&t.height+t.y>e.y)}convertAbsoluteToRelativeCropArea(t,e){const{height:r,width:a,x:i,y:s}=t;return{height:r/e.naturalHeight,width:a/e.naturalWidth,x:i/e.naturalWidth,y:s/e.naturalHeight}}convertRelativeToAbsoluteCropArea(t,e){const{height:r,width:a,x:i,y:s}=t;return{height:r*e.naturalHeight,width:a*e.naturalWidth,x:i*e.naturalWidth,y:s*e.naturalHeight}}setPreviewImages(t){const e=this.cropper.image,a=this.cropper.getImageData();Object.keys(t).forEach(i=>{const s=t[i],o=this.convertRelativeToAbsoluteCropArea(s.cropArea,a),n=this.trigger.closest(".form-group").find(`.t3js-image-manipulation-preview[data-crop-variant-id="${i}"]`),c=this.trigger.closest(".form-group").find(`.t3js-image-manipulation-selected-ratio[data-crop-variant-id="${i}"]`);if(0===n.length)return;let h=n.width(),d=n.data("preview-height");const p=o.width/o.height,l=h/p;l>d?h=d*p:d=l,h>o.width&&(h=o.width,d=o.height);const u=h/o.width,f=(0,r.default)("<div />").html('<img src="'+e.src+'">'),g=this.currentModal.find(`.t3-js-ratio-title[data-ratio-id="${s.id}${s.selectedRatio}"]`);c.text(g.text()),f.addClass("cropper-preview-container"),n.empty().append(f),f.wrap('<span class="thumbnail thumbnail-status"></span>'),f.width(h).height(d).find("img").css({height:a.naturalHeight*u,left:-o.x*u,top:-o.y*u,width:a.naturalWidth*u})})}openPreview(t){const e=h.serializeCropVariants(t);let r=this.trigger.attr("data-preview-url");r=r+(r.includes("?")?"&":"?")+"cropVariants="+encodeURIComponent(e),window.open(r,"TYPO3ImageManipulationPreview")}save(t){const e=h.serializeCropVariants(t),i=(0,r.default)("#"+this.trigger.attr("data-field"));this.trigger.attr("data-crop-variants",JSON.stringify(t)),this.setPreviewImages(t),i.val(e),a.markFieldAsChanged(i),this.currentModal.modal("hide")}destroy(){this.currentModal&&(this.cropper instanceof s.default&&this.cropper.destroy(),this.initialized=!1,this.cropper=null,this.currentModal=null,this.data=null)}}return new h}));