<template>
	<view class="_vocr">
		<view>
			<view v-if="workstep == 1" class="rel">
				<cover-image v-if="maskpng" :src="file_stor(maskpng)" class="abs t0 l0" :style="{opacity:0.8,width: '100%', height: height + 'vw'}"></cover-image>
				<camera device-position="back" flash="off" :style="{width: '100%', height: height + 'vw'}"></camera>
			</view>
			<view v-if="workstep == 2" class="rel">
				<image :src="src" :style="{width: '100%', height: height + 'vw',display:'block'}"></image>
				<view v-for="txtpo in txtpos" class='abs' @tap="boxclick(txtpo)" :style="{top:txtpo.top,left:txtpo.left,width:txtpo.width,height:txtpo.height,minWidth:'0.7em',minHeight:'0.7em',border:'1px solid ' + bordercolor,borderRadius:'3px'}"></view>
				<view v-if="txtpos.length == 0" class='abs b0 r0 _noocr'>无文字</view>
			</view>
			<view class="flex px2" style="justify-content: space-between;height:3em;">
				<view>
					<ciy-svgimg v-if="workstep==0" @tap="workstep=1" :src="svg.opencamera" ciystyle="width:2em;height:2em;"></ciy-svgimg>
					<ciy-svgimg v-else @tap="workstep=0" :src="svg.closecamera" ciystyle="width:2em;height:2em;"></ciy-svgimg>
				</view>
				<view>
					<button v-if="workstep==1" class="btn lg cc" @tap="ocrnow">拍摄识别</button>
				</view>
				<view>
					<ciy-svgimg v-if="workstep == 2" @tap="workstep=1" :src="svg.recamera" ciystyle="width:2em;height:2em;"></ciy-svgimg>
					<view v-else style="width:2em;height:2em;"></view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		emits: ['change', 'textclick'],
		props: {
			maskpng: {
				type: String,
				default: ''
			},
			height: {
				type: String,
				default: '66'
			},
			bordercolor: {
				type: String,
				default: '#00e112'
			},
			mode: {
				type: String,
				default: 'text' //idcard身份证自动校正，none 无文字不ocr，text ocr有文字(无文字5秒超时)
			},
			checkidcard: {
				type: String,
				default: '' //front人像，back国徽
			},
		},
		data() {
			return {
				txtpos: [],
				src: '',
				svg:{
					opencamera:'<svg viewBox="0 0 1024 1024" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M868 288a64 64 0 0 1 101 52l3 303a64 64 0 0 1-103 51l-207-158a64 64 0 0 1 2-103l204-145z" fill="#1296db"></path><path d="M144 192h456a96 96 0 0 1 96 96v417a96 96 0 0 1-96 96H144a96 96 0 0 1-96-96V288a96 96 0 0 1 96-96z" fill="#1296db"></path></svg>',
					closecamera:'<svg viewBox="0 0 1024 1024" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M107 152A32 32 0 1 1 149 104l768 672a32 32 0 0 1-42 48l-768-672z" fill="#1296db"></path><path d="M733 462l-37-52 172-122a64 64 0 0 1 101 52l3 303a64 64 0 0 1-20 47l-44-47-3-303-172 122z m-35-54l36 53c-11 7-24 12-37 12a64 64 0 0 1-64-64V288a32 32 0 0 0-32-32h-206V192h206a96 96 0 0 1 96 96v121c0-0 1-1 2-1zM632 608h64v97a96 96 0 0 1-96 96H144a96 96 0 0 1-96-96V288a96 96 0 0 1 96-96h96v64h-96a32 32 0 0 0-32 32v417a32 32 0 0 0 32 32h456a32 32 0 0 0 32-32V608z" fill="#1296db"></path></svg>',
					recamera:'<svg viewBox="0 0 1024 1024" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M533 175v-62l-228 143 228 143v-107c114 26 200 128 200 249 0 141-116 257-257 257s-257-116-257-257c0-32-26-57-57-57-32 0-57 26-57 57 0 204 167 371 371 371s371-167 371-371c0-185-137-339-314-366z" fill="#1296db"></path></svg>'
				},
				workstep: 0,
			};
		},
		watch: {},
		computed: {},
		mounted() {
			var vkopn = {};
			vkopn.version = 'v1';
			vkopn.track = {};
			vkopn.track.IDCard = {};
			vkopn.track.IDCard.mode = 2;
			vkopn.track.OCR = {};
			vkopn.track.OCR.mode = 2;
			vkopn.gl = this.gl;
			this.session = wx.createVKSession(vkopn);
			this.session.start(err => {
				this.session.on('updateAnchors', this.onanchor);
			});
		},
		unmounted() {
			this.session.off('updateAnchors', this.onanchor);
			this.session.stop();
			this.session.destroy();
		},
		methods: {
			boxclick(po) {
				this.$emit('textclick', po);
			},
			onanchor(anchors) {
				if (typeof(this.auchorcb) == 'function')
					this.auchorcb(anchors);
			},
			Step(step) {
				this.workstep = step;
			},
			//摄像头开关在下，且用图标占位。
			//重新拍摄在下右。方便点击。
			//拍摄识别在中。


			//按拍摄后，自动识别
			//无文字，在图片旁边标注即可。
			//拍照完成，上面有文字。
			//用户点门头，上传门头。
			//用户点企业，再点文字，文字进企业框。
			//用户点展位号，
			//


			//拍照，拍照+识别
			//在摄像头正常的时候，点一下门头，拍照，上传。
			//在摄像头正常的时候，点一下企业，拍照识别，点框
			//在摄像头正常的时候，点一下企业，拍照识别，点框



			async runvk(mode, file) {
				return new Promise(async (resolve, reject) => {
					var _time = setTimeout(() => {
						reject('timeout');
					}, 5000);
					this.auchorcb = anchors => {
						clearTimeout(_time);
						resolve(anchors);
					};
					if (mode == 'idcard') {
						this.session.detectIDCard({
							frameBuffer: file.buffer,
							width: file.width,
							height: file.height,
							getAffineImg: true,
						});
					} else {
						this.session.runOCR({
							frameBuffer: file.buffer,
							width: file.width,
							height: file.height,
						});
					}
				}).catch(e => {
					console.error('vk error', e);
					return e;
				});
			},
			ocrnow() {
				const ctx = wx.createCameraContext();
				ctx.takePhoto({
					quality: 'high',
					success: async (res) => {
						this.workstep = 2;
						this.txtpos = [];
						this.src = res.tempImagePath;
						res.buffer = await this.getimgbuffer(res);
						var ret = {};
						ret.tempimg = res.tempImagePath;
						ret.width = res.width;
						ret.height = res.height;
						if (this.mode == 'idcard') {
							var anchors = await this.runvk('idcard', res);
							var anchor = anchors[0];
							if (anchor.isComplete != 1)
								return this.alert('身份证拍摄不完整');
							if (this.checkidcard == 'front') {
								if (anchor.label != 0)
									return this.alert('请拍摄身份证人像面');
								if (anchor.orientation != 0)
									return this.alert('请朝上放正拍摄身份证');
							}
							if (this.checkidcard == 'back') {
								if (anchor.label != 1)
									return this.alert('请拍摄身份证国徽面');
								if (anchor.orientation != 0)
									return this.alert('请朝上放正拍摄身份证');
							}
							ret.idcardface = anchor.label; //0 照片面 / 1 国徽面
							ret.orientation = anchor.orientation; // 身份证朝向 （0 朝上 1 朝下 2 朝下 3 朝左）

							const canvas = wx.createOffscreenCanvas({
								type: '2d',
								width: anchor.affineImgWidth,
								height: anchor.affineImgHeight,
							});
							const context = canvas.getContext('2d');

							context.clearRect(0, 0, anchor.affineImgWidth, anchor.affineImgHeight);

							context.setTransform(
								Number(anchor.affineMat[0]), Number(anchor.affineMat[3]), Number(anchor.affineMat[1]),
								Number(anchor.affineMat[4]), Number(anchor.affineMat[2]), Number(anchor.affineMat[5])
							);
							context.drawImage(this._img, 0, 0, res.width, res.height);
							const imageData = context.getImageData(0, 0, anchor.affineImgWidth, anchor.affineImgHeight);
							res.buffer = imageData.data.buffer;
							res.width = anchor.affineImgWidth;
							res.height = anchor.affineImgHeight;
							this.src = canvas.toDataURL();
						}
						ret.txts = [];
						ret.txtall = '';
						if (this.mode != 'none') { //无文字时会有直接卡死bug
							try {
								var anchors = await this.runvk('ocr', res);
								ret.anchors = anchors;
								for (var i in anchors) {
									if (anchors[i].text)
										ret.txtall = anchors[i].text;
									if (!anchors[i].subtext)
										continue;
									ret.txts.push(anchors[i].subtext);
									var pos = anchors[i].box;
									this.txtpos.push({
										text: anchors[i].subtext,
										alltext: anchors[i].text,
										pos: pos,
										top: (pos[0].y * 100) + '%',
										left: (pos[0].x * 100) + '%',
										width: ((pos[1].x - pos[0].x) * 100) + '%',
										height: ((pos[2].y - pos[0].y) * 100) + '%',
									});
								}
							} catch (e) {
								console.log(e);
								//this.toast('无文字，请重新拍摄');
								//this.workstep = 1;
								//return;
							}
						}
						this.$emit('change', ret);
					}
				});
			},
			async getimgbuffer(file) {
				const canvas = wx.createOffscreenCanvas({
					type: '2d',
					width: file.width,
					height: file.height,
				});
				const context = canvas.getContext('2d');
				this._img = canvas.createImage();
				this._img.src = file.tempImagePath;
				var err = await this.goe(this.go_load(this._img));
				if (err)
					return reject('Image Load Error');

				context.clearRect(0, 0, file.width, file.height);
				context.drawImage(this._img, 0, 0, file.width, file.height);

				var imgData = context.getImageData(0, 0, file.width, file.height);
				return imgData.data.buffer;
			}
		}
	}
</script>

<style scoped>
	._vocr {
		margin: 0;
		padding: 0;
		position: relative;
	}

	._noocr {
		background: #00000044;
		color: #000000;
		text-shadow: 1px 1px 0 #ffffff88;
		padding: 0.3em 0.8em;
		border-radius: 0.5em 0 0 0;
	}
</style>