<template>
  <div>
		<n-space justify="start">
			<cropper
				class="cropper"
				:src="snap_to_inters ? srcImageIntersections : src"
				:stencil-component="this.$options.components.RectangleStencil"
				:stencil-props="stencilProps"
				:auto-zoom="true"
				:checkOrientation="false"
				@change="change"
				ref="cropper"
			/>

			<n-space vertical justify="space-between" class="options_panel">
				<div>
					<h2>Preview</h2>
					<div class="preview_wrapper">
						<n-image
							class="preview"
							:src="preview_data_url"
						/>
					</div>
				</div>

				<h2 style="margin-top: 3em;">Options</h2>

				rotate by {{ rotate_angle }}°
				<n-slider v-model:value="rotate_angle" @update:value="update_rotate" :step="1" :min="-180" :max="180" />
				<n-checkbox :disabled="free_transform" v-model:checked="lock_aspect_ratio">lock aspect ratio to flip chart size</n-checkbox>
				<n-checkbox v-model:checked="free_transform">free transform handles</n-checkbox>
				<n-checkbox v-model:checked="snap_to_inters">snap to intersections</n-checkbox>
			</n-space>
		</n-space>
  </div>
</template>

<script>
import {Cropper, RectangleStencil} from 'vue-advanced-cropper'
import FreeSnapStencil from '../components/FreeSnapStencil.vue'
import 'vue-advanced-cropper/dist/style.css'


/* eslint-disable vue/no-unused-components */
export default {
	components: {
		Cropper,
		FreeSnapStencil,
		RectangleStencil
	},
	props: {
		src: {
			type: String,
			required: true,
		},
		inters: {
			type: Array,
			required: false,
			default: () => [],
		},
	},
	data() {
		return {
			srcImgElement: null,
			srcImgLoaded: false,
			preview_data_url: null,
			lock_aspect_ratio: true,
			free_transform: false,
			snap_to_inters: false,
			bbox: [],
			rotate_angle: 0,
		}
	},
	created() {
		this.srcImgElement = new Image()
		this.srcImgElement.src = this.src
		this.srcImgElement.crossOrigin = 'Anonymous'
		this.srcImgElement.onload = () => {
			this.srcImgLoaded = true
		}
	},
	computed: {
		srcImageIntersections() {
			if (!this.srcImgLoaded) {
				return this.src
			}

			var canvasElement = document.createElement('canvas')
			canvasElement.width = this.srcImgElement.width
			canvasElement.height = this.srcImgElement.height

			var ctx = canvasElement.getContext('2d')
			ctx.drawImage(this.srcImgElement, 0,0)
			
			this.drawIntersections(ctx)
			
			try {
				return ctx.canvas.toDataURL()
			}
			catch(e) {
				return this.src
			}
		},
		stencilProps() { 
			if (this.lock_aspect_ratio) {
				return {
					aspectRatio: 1/1.41421356,
					intersections: this.inters
				}
			}
			return {intersections: this.inters}
		}
	},
	methods: {
		drawIntersections(ctx) {
			for (let i=0; i < this.inters.length; i++) {
				let x = this.inters[i][0]
				let y = this.inters[i][1]
				this.drawCircle(
					ctx, x,y,
					8, 'rgba(255,255,255,0.9)',
					'rgba(255,255,255,0.4)', 25)
			}
		},
		drawCircle(ctx, x, y, radius, fill, stroke, strokeWidth) {
			ctx.beginPath()
			ctx.arc(x, y, radius, 0, 2 * Math.PI, false)
			if (fill) {
				ctx.fillStyle = fill
				ctx.fill()
			}
			if (stroke) {
				ctx.lineWidth = strokeWidth
				ctx.strokeStyle = stroke
				ctx.stroke()
			}
		},
		coordinates_to_bbox(coordinates) {
			let top_left = [
				coordinates.left,
				coordinates.top
			]
			let top_right = [
				coordinates.left + coordinates.width,
				coordinates.top
			]
			let bottom_right = [
				coordinates.left + coordinates.width,
				coordinates.top + coordinates.height
			]
			let bottom_left = [
				coordinates.left,
				coordinates.top + coordinates.height
			]

			return [top_left, top_right, bottom_right, bottom_left]
		},
		change({ coordinates, canvas }) {
			try {
				this.preview_data_url = canvas.toDataURL()
				this.bbox = this.coordinates_to_bbox(coordinates)
			} catch (e) {return}
		},
		update_rotate() {
			this.$refs.cropper.appliedImageTransforms= {
				rotate: this.rotate_angle,
				flip: {
					horizontal: false,
					vertical: false,
				},
			}
		},
		getResult() {
			return {
				bbox: JSON.parse(JSON.stringify(this.bbox)),
				rotate: -this.rotate_angle
			}
		}
	}
}
</script>

<style scoped>
h2 {
	font-weight: bold;
	font-size: 1.2em;
	color: #999;
}

.options_panel {
	display: inline;
	background-color: #f5f5f5;
	padding: 1.5em;
	border-radius: 1em;
}

.cropper {
	height: 600px;
	width: 600px;
	max-width: 80vw;
	background: #DDD;
}

.preview_wrapper {
	width: 20vw;
	height: 20vw;
}

.preview {
	object-fit: contain;
}
</style>