<template>
	<div ref="liquefactionModal"></div>
    <a-modal
        class="liquefaction generalModel"
        v-model:visible="liqufeaction"
        :footer="null"
		:get-container="() => $refs.liquefactionModal"
        width="78%"
        :maskClosable="false"
        :centered="true"
        :closable="false"
        wrapClassName="#app"
        :keyboard="false"
    >
		<div class="generalModel_btn">
			<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
				<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
					<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
					<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
					<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
				</svg>
			</div>
		</div>
		
		<div class="liquefaction_center">
			<div class="liquefaction_canvas_box">
				<canvas id="c"></canvas>
				<div v-show="arrows.show" class="moveDom" :style="arrows.domStyle"></div>
				<div v-show="arrows.show" class="jiantouDom" :style="arrows.jiantouStyle"> </div>
			</div>
			<div class="liquefaction_parameter">
				<div class="liquefaction_parameter_item">
					<div class="liquefaction_parameter_item_title">
						<span>{{ $t('exportModel.Size') }}</span>
						<input type="number" v-model="routes" @change="routesChange('routes')">
					</div>
					<div class="liquefaction_parameter_item_input">
						<input type="range" v-model="routes" @change="routesChange('routes')">
					</div>
				</div>
				<div class="liquefaction_parameter_item">
					<div class="liquefaction_parameter_item_title">
						<span>{{ $t('exportModel.density') }}</span>
						<input type="number" v-model="density" @change="routesChange('density')">
					</div>
					<div class="liquefaction_parameter_item_input">
						<input type="range" v-model="density" @change="routesChange('density')">
					</div>
				</div>
				<div class="liquefaction_parameter_item icon">
					<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
					<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
				</div>
				<div class="liquefaction_parameter_item">
					<div class="generage_btn started_btn" @click="cancelDsign">{{ $t('Cropper.Cancel')}}</div>
					<div class="generage_btn started_btn" @click="submit">{{ $t('Cropper.Finish')}}</div>
				</div>
			</div>
			
		</div>
    </a-modal>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs, onBeforeUnmount } from "vue";
import { useI18n } from "vue-i18n";
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
    components: {
    },
	emits: ['submitLiquefaction'],
    setup(props,{emit}) {
        // let presentState = ref('paypal');
		let liqufeaction = ref(false);
		let liqufeactionData = reactive({
			routes: 30,//移动框大小
			density: 30,//移动大小
		})
		let arrows = ref({
			show:false,
			domStyle:{
				left:0,
				top:0,
				width:0,
				height:0,
			},
			jiantouStyle:{
				height:'1px',
				transform:`translateY(-100%) rotate(${90}deg)`,
			}
		})
		let records = []//撤回
		let normalCanvasState = []//反撤回
		let canvas
		let canvasImgData = {
			width:0,
			height:0,
		}
		let downX
		let downY
		let context
		let init = async (data)=>{
			records = []
			liqufeaction.value = true
			document.addEventListener("keydown", kyeDown);
			document.addEventListener("keyup", KeyUp);
			await new Promise((resolve, reject) => {
				nextTick(()=>{
					resolve()
				})
			})
			let img = new Image()
			img.setAttribute('crossOrigin', 'Anonymous')
			img.onload = () => {
				canvasImgData.width = img.width
				canvasImgData.height = img.height
				let canvasBox = document.querySelector('.liquefaction .liquefaction_canvas_box')
				canvas = document.getElementById('c')
				let scale = canvasBox.offsetWidth / img.width
				let width = canvasBox.offsetWidth
				let height = img.height * scale
				if(height > canvasBox.offsetHeight){
					height = canvasBox.offsetHeight
					width = img.width / img.height * height
				}
				canvas.width = width
				canvas.height = height
				let optfor = false
				context = canvas.getContext('2d');
				context.drawImage(img, 1, 1, canvas.width, canvas.height);
				let imgData = context.getImageData(0, 0, canvas.width, canvas.height)
				
				let canvasDownX
				let canvasDownY
				let distance = 0
				let angle
				let mousedown = (event)=>{
					let e = getMousePosition(event,false)
					down(e)
				}
				let touchdown = (event)=>{
					let e = getMousePosition(event,true)
					down(e)
				}
				let down = (event)=> {
					let canvasPosition = canvas.getBoundingClientRect()
					let maxX = canvasPosition.width + canvasPosition.x
					let minX = canvasPosition.x
					let maxY = canvasPosition.height + canvasPosition.y
					let minY = canvasPosition.y
					if (event.clientX > minX && event.clientX < maxX && event.clientY > minY && event.clientY < maxY) {
						downX = event.clientX
						downY = event.clientY
						canvasDownX = downX - minX
						canvasDownY = downY - minY
					}
					optfor = true
					arrows.value.jiantouStyle.height = distance + 'px'
					arrows.value.jiantouStyle.left = event.clientX - canvasBox.getBoundingClientRect().left + 'px'
					arrows.value.jiantouStyle.top = event.clientY - canvasBox.getBoundingClientRect().top + 'px'
					arrows.value.domStyle.width = liqufeactionData.routes * 2 + 'px'
					arrows.value.domStyle.height = liqufeactionData.routes * 2 + 'px'
					arrows.value.domStyle.left = event.clientX - canvasBox.getBoundingClientRect().left - liqufeactionData.routes + 'px'
					arrows.value.domStyle.top = event.clientY - canvasBox.getBoundingClientRect().top - liqufeactionData.routes + 'px'
					arrows.value.show = true
					let mouseup = ()=>{
						if(!optfor)return
						if(distance != 0){
							let {upDownX, upDownY} = calculateTargetCoordinates(canvasDownX, canvasDownY,distance,angle)
							liquify(imgData, canvasDownX, canvasDownY, upDownX, upDownY, liqufeactionData.routes, liqufeactionData.density)
						}
						distance = 0
						arrows.value.show = false
						const copiedImgData = new ImageData(new Uint8ClampedArray(imgData.data), imgData.width, imgData.height);
						records.push(copiedImgData)
						context.putImageData(copiedImgData, 0, 0);
						optfor = false
						canvasBox.removeEventListener('mousemove', mouseMove);
						canvasBox.removeEventListener('touchmove', touchmove);
						document.removeEventListener('mouseup', mouseup);
						document.removeEventListener('touchend', mouseup);
					}
					canvasBox.addEventListener('mousemove', mouseMove);
					canvasBox.addEventListener('touchmove', touchmove);
					document.addEventListener('mouseup', mouseup);
					document.addEventListener('touchend', mouseup);
				}
				let mouseMove = (event)=>{
					let e = getMousePosition(event,false)
					move(e)
				}
				let touchmove = (event)=>{
					let e = getMousePosition(event,true)
					move(e)
				}
				let move = function (moveEvent) {
					let height = distanceFun(downX , downY , moveEvent.clientX , moveEvent.clientY)
					if(optfor){
						let height = distanceFun(downX , downY , moveEvent.clientX , moveEvent.clientY)
						angle = angleFun(downX , downY , moveEvent.clientX , moveEvent.clientY)

						if(height < liqufeactionData.routes){
							distance = height
							arrows.value.jiantouStyle.height = height + 'px'
						}
						arrows.value.jiantouStyle.transform = `translateY(-100%) rotate(${angle+90}deg)`
						
					}
				}
				// canvas.addEventListener('mousedown', down);
				canvasBox.addEventListener('mousedown', mousedown);
				canvasBox.addEventListener('touchstart', touchdown);
			}
			if(data._element){
				img.src = data._element.src
			}else{
				img.src = data
			}


        }

		let distanceSqr = (x1, y1, x2, y2) => sqr(x1 - x2) + sqr(y1 - y2); 
		let sqr = (x) => x * x;; 
		let eachCircleDot = (imageData, ox, oy, r, callback)=>{
			var imgWidth = imageData.width,
				imgHeight = imageData.height,
				data = imageData.data,
				left = ox - r,
				right = ox + r,
				top = oy - r,
				bottom = oy + r,
				dotRedOffset, dotGreenOffset, dotBlueOffset, alphaOffset;
			for (var x = left; x < right; x++){
				for (var y = top; y < bottom; y++){
					if (distanceSqr(x, y, ox, oy) <= sqr(r)) {

						dotRedOffset = y * imgWidth * 4 + x * 4;
						dotGreenOffset = dotRedOffset + 1;
						dotBlueOffset = dotGreenOffset + 1;
						alphaOffset = dotBlueOffset + 1;

						callback(
							// 当前点的坐标
							{ x: x, y: y },
							// 点的RGBA四个分量对应字节的下标
							{
								r: dotRedOffset,
								g: dotGreenOffset,
								b: dotBlueOffset,
								a: alphaOffset,
							},
							// 传进来的ImageData的data部分
							data

						);

					}

				}
			}
		}

		let keyDowns = []
		let kyeDown = (event)=>{
			if(keyDowns.indexOf(event.code)>-1){
			}else{
				keyDowns.push(event.code)
				if(keyDowns.indexOf('ControlLeft') > -1 && keyDowns.indexOf('KeyZ') > -1 && keyDowns.indexOf('ShiftLeft') > -1){
					historyState('')
				}else if(keyDowns.indexOf('ControlLeft') > -1 && keyDowns.indexOf('KeyZ') > -1){
					historyState('reverse')
				}
			}
		}
		let KeyUp = (event) =>{
			keyDowns = keyDowns.filter(function(item) {
				return event.code !== item;
			})
		}
		const historyState = (str)=>{
			console.log(str);
			let obj
			if(str == 'reverse' && records.length > 0){//反撤回
				obj = records.pop()
				normalCanvasState.push(obj);
			}else if(str == '' && normalCanvasState.length > 1){
				obj = normalCanvasState.pop()
				records.push(obj);
			}else{
				return
			}
			console.log(obj,context);
			context.putImageData(obj, 0, 0);

		}
		onBeforeUnmount(()=>{
			document.removeEventListener("keydown", kyeDown);
			document.removeEventListener("keyup", KeyUp);
		})
		let copyImageDataBuff = (imgData)=>{
			var data = imgData.data,
				imgDataBuff = [];
			for (var i in data){
				imgDataBuff[i] = data[i];
			}
			return imgDataBuff;
		}
		let moveDot = (imgData, dataBuff, x, y, srcX, srcY)=> {

			var imgWidth = imgData.width,
				imgHeight = imgData.height,
				data = imgData.data;

			// // 进行边界检查，确保不超出图像范围
			x = Math.max(0, Math.min(Math.round(x), imgWidth - 1));
			y = Math.max(0, Math.min(Math.round(y), imgHeight - 1));
			srcX = Math.max(0, Math.min(Math.round(srcX), imgWidth - 1));
			srcY = Math.max(0, Math.min(Math.round(srcY), imgHeight - 1));
			srcX = Math.round(srcX);
			srcY = Math.round(srcY);

			var targetStartOffset = y * imgWidth * 4 + x * 4,
				srcStartOffset = srcY * imgWidth * 4 + srcX * 4;
			for (var i = 0; i < 4; i++)
				data[targetStartOffset + i] = dataBuff[srcStartOffset + i];
		}
		let liquify = (imgData, cx, cy, mx, my, r, strenth) => {
			var imgDataBuff = copyImageDataBuff(imgData);
			eachCircleDot(imgData, cx, cy, r, function (posi) {
				var tx = posi.x,
					ty = posi.y;
				var u = transFormula(cx, cy, mx, my, tx, ty, r, strenth);
				moveDot(imgData, imgDataBuff, tx, ty, u.x, u.y);
				function transFormula(cx, cy, mx, my, tx, ty, r, strenth) {
					strenth = strenth || 100;
					var relativity = sqr(r) - distanceSqr(tx, ty, cx, cy);
					var distanceMovedSqr = distanceSqr(mx, my, cx, cy);
					var rate = sqr(relativity / (relativity + distanceMovedSqr * (100 / strenth)));
					var ux = tx - rate * (mx - cx),
						uy = ty - rate * (my - cy);
					return { x: ux, y: uy };
				}
			});
		}
		let distanceFun = (x1, y1, x2, y2) => {
			return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
		}
		let angleFun = (x1, y1, x2, y2) => {
			return Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI);
		}
		let calculateTargetCoordinates = (x1, y1, distance, angleDegrees) => {
			let angleRad = angleDegrees * (Math.PI / 180);
			let x2 = x1 + distance * Math.cos(angleRad);
			let y2 = y1 + distance * Math.sin(angleRad);
			return { upDownX: x2, upDownY: y2 };
		}
		let cancelDsign = ()=>{
			liqufeaction.value = false
		}
		let routesChange = (str)=>{
			liqufeactionData[str] = Math.round(liqufeactionData[str]/10)*10;
			if (liqufeactionData[str] < 10) {
				liqufeactionData[str] = 10; // 设置为最小值
			} else if (liqufeactionData[str] > 100) {
				liqufeactionData[str] = 100; // 设置为最大值
			}
		}
		let submit = ()=>{
			const newCanvas = document.createElement('canvas');
            newCanvas.width = canvasImgData.width;
            newCanvas.height = canvasImgData.height;
			const newCtx = newCanvas.getContext('2d');
			newCtx.drawImage(
                canvas,  
                0, 0,                   
                canvas.width,
                canvas.height, 
                0, 0,               
				newCanvas.width,     
                newCanvas.height  
            );
			emit('submitLiquefaction',newCanvas.toDataURL('image/png'))
			cancelDsign()
		}
        return {
            liqufeaction,
			...toRefs(liqufeactionData),
			arrows,
			init,
			historyState,
			cancelDsign,
			routesChange,
			submit,
        };
    },
    data() {
        return {
        };
    },
    mounted() {},
    methods: {
       
    },
});
</script>
<style lang="less" scoped>
.liquefaction {
	background: #f9fafb;
    .liquefaction_center{
		height: 100%;
		display: flex;
		align-items: center;
		.liquefaction_canvas_box{
			background: #fff;
			height: 90%;
			width: 80%;
			text-align: center;
			// overflow-x: auto;
			position: relative;
			// overflow-y: hidden;
			display: flex;
			align-items: center;
			overflow: hidden;
			justify-content: center;
		}
		.liquefaction_parameter{
			padding-top: 5rem;
			height: 100%;
			flex: 1;
			.liquefaction_parameter_item{
				display: flex;
				flex-direction: column;
				.liquefaction_parameter_item_title{
					display: flex;
					justify-content: space-between;
					input{
						width: 30%;
						text-align: right;
					}
				}
				.liquefaction_parameter_item_input{
					width: 100%;
					input{
						width: 100%;
					}
				}
				&.icon{
					flex-direction: row;
					i{
						width: 4rem;
						height: 4rem;
						display: flex;
						border-radius: .5rem;
						font-size: 2rem;
						cursor: pointer;
						border: 2px solid #000;
						margin-right: 1rem;
						align-items: center;
						justify-content: center;
						font-weight: 600;
					}
					i::last-nth{
						margin: 0;
					}
				}
			}
			.liquefaction_parameter_item:last-child{
				margin-top: 20px;
				text-align: center;
				div{
					margin-bottom: 1rem;
				}
			}
		}
		.moveDom {
			width: 20px;
			height: 20px;
			border-radius: 50%;
			box-sizing: border-box;
			border: 1px solid;
			position: absolute;
			pointer-events: none;
		}

		.jiantouDom {
			position: absolute;
			width: 2px;
			height: 1px;
			background-color: #000;
			transform-origin: center bottom;
			transform: translateY(-100%);
			pointer-events: none;
		}

		.jiantouDom::before {
			content: "";
			display: block;
			position: absolute;
			width: 10px;
			height: 10px;
			left: 50%;
			transform: translateX(-50%) rotate(45deg);
			border-top: 2px solid #000;
			border-left: 2px solid #000;
			pointer-events: none;
		}
		
	}
}
</style>