<template>
	<div class="sheet-objective-container" ref="baseInfoRef" @mouseout="isShowInfoEdit = false"
		@mouseover="isShowInfoEdit = true">
		<!-- <p style="margin-left: 100px; font-weight: bold; color: #000">一、选择题</p> -->
		<!-- <BaseTitleEditor ids="objectiveTitleEditor" :content="'一、选择题（共' + objectiveItems.length + '题，总计' + totalScore + '分)'"></BaseTitleEditor> -->
		<svg id="sheetObjectiveSvg" width="100%" :style="'height:' + svgHeight + 'px'"></svg>
		<div class="info-edit" v-show="isShowInfoEdit">
			<span @click="editModal = true" style="background-color: #00a43a;" v-if="!isAutoCreate">{{ $t('answerSheet.edit') }}</span>
			<span @click="doDelete" style="background-color: red;" v-if="!isAutoCreate">{{ $t('answerSheet.delete') }}</span>
		</div>
		<Modal v-model="editModal" :title="$t('answerSheet.baseInfo')" @on-ok="onReRender">
			<p class="edit-title">{{ $t('answerSheet.obejctiveTitle') }}</p>
			<InputNumber :max="objectiveItems.length" :min="3" v-model="number"></InputNumber>
		</Modal>
	</div>
</template>

<script>
	import BaseTitleEditor from './BaseTitleEditor'
	import Snap from "imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js";
	import {
		PAPER_W,
		PAPER_H,
		CONTENT_MT,
		CONTENT_ML,
		ANCHORPROP,
		CONTENT_START_X,
		CONTENT_START_Y,
		INFO_W,
		INFO_H,
		INFO_ITEM_GAP,
		INFO_ITEM_MARGIN,
		ID_LENGTH,
		INFO_LEFT_X,
		INFO_LEFT_W,
		ID_TITLE_H,
		ID_TITLE_Y,
		NUMBER_CELL_H,
		NUMBER_ITEM_W,
		NUMBER_ITEM_H,
		NUMBER_ITEM_MT,
		NUMBER_ITEM_ML,
		BLOCK_H,
		OBJ_ANCHOR_GAP,
		OBJ_ANCHOR_H_COUNT
	} from "@/utils/sheetConfig.js";
	export default {
		props: {
			items: {
				type: Array,
				default: () => {
					return [];
				},
			},
		},
		components: {
			BaseTitleEditor
		},
		data() { 
			return {
				isShowInfoEdit: false,
				editModal: false,
				objectiveGroup: null,
				snap: null,
				svgHeight: 0,
				number: 5,
				blockHeight: 0,
				objectiveItems: [],
				leftItems: [],
				blockList: [],
				anchorRectY: 0,
				everyOptionH:19,
				curBlockIndex:-2,
				preBlockCellCount:0,
				curColumn:0,
				curCellCount:0,
				times:-1,
				lastItem:null
			};
		},
		created() {
			this.snap = Snap("#sheetObjectiveSvg");
		},
		methods: {
			doDelete() {
				this.$EventBus.$emit('deleteItem', 'objective')
			},
			/* 设置客观题的配置数据 */
			setObjectiveConfig(){
				this.$store.commit('setColumnCount',this.number)
				let titleHeight = document.getElementById('titleEditor0').getBoundingClientRect().height
				let objectiveConfig = {
					"type": 1,
					"x": CONTENT_START_X - ANCHORPROP.gapX + 5,
					"y": 350 - (ANCHORPROP.gapY - 5) + titleHeight + 10,
					"width": INFO_W,
					"height": this.anchorRectY + 20,
					"pageNum": 1,
					"vblockCount": this.objectiveItems.length > this.number ? this.number * this.blockList.length : this.objectiveItems.length,
					"hblockCount": OBJ_ANCHOR_H_COUNT,
					"count": this.objectiveItems.length
				}
				this.$store.commit('setObjectiveConfig', objectiveConfig)
			},
			
			// 修改每列展示题数重新渲染
			onReRender() {
				
				// this.$store.commit('setColumnCount',this.number)
				this.leftItems = JSON.parse(JSON.stringify(this.objectiveItems))
				this.doRenderItems(this.objectiveItems, this.number);
				this.$EventBus.$emit('doRefresh')
			},

			// 渲染客观题区域边框
			doRenderBorder(items, number, blockCount) {
				let snap = this.snap;
				let objectiveHeight = 40 + this.blockHeight * blockCount;
				this.svgHeight = this.anchorRectY + 40;
				this.setObjectiveConfig()
				// 信息框
				let infoBox = snap
					.rect(CONTENT_START_X, 2, INFO_W, this.anchorRectY + 30)
					.attr({
						shapeRendering:"crispEdges",
						fill: "none",
						stroke: "black",
						strokeWidth:2
					});
				this.objectiveGroup.add(infoBox);
				this.$EventBus.$emit('doRefresh')
			},

			// 渲染客观题目
			doRenderItems(items, number) {
				this.curBlockIndex = -2,
				this.preBlockCellCount = 0,
				this.curColumn = 0,
				this.curCellCount = 0,
				this.lastItem = null
				this.blockHeight = this.everyOptionH * number
				this.objectiveGroup && this.objectiveGroup.remove(); // 先清除之前的绘制内容
				if (this.snap) {
					this.objectiveGroup = this.snap.paper.g();
				}
				let snap = this.snap;
				let MARGIN_LEFT = 25;
				let GAP = this.everyOptionH; //纵向间距
				let optionGap = 30; //横向间距
				let startY = GAP + 15;
				let needNewLineArr = items.map((item, index) =>
					this.needNewLine(index, number, items)
				);
				let indexAndNeed = [];
				// 提前计算 每个题目排列时 是否要进行换行 以及计算需要换到第几行 （行可以理解为选项块）
				for (let jIndex = 0; jIndex < needNewLineArr.length; jIndex++) {
					if (needNewLineArr[jIndex].need) {
						indexAndNeed.push({
							index: jIndex,
							need: true,
						});
					}
				}
				let itemsPositionArr = [];
				// 提前计算 每个题目排列时 是否要进行换行 以及计算需要换到第几行 （行可以理解为选项块）
				let times = -1
				let xArrIndex = 0
				for (let index = 0; index < items.length; index++) {
					let isChangeLine = needNewLineArr[index].need && !needNewLineArr[index - 1].need
					if(isChangeLine){
						itemsPositionArr.push({
							index: index,
							needNewLine: needNewLineArr[index].need,
							lineIndex: ++times,
							xArrIndex:0
						});
					}else{
						itemsPositionArr.push({
							index: index,
							needNewLine: needNewLineArr[index].need,
							lineIndex: needNewLineArr[index].need && !needNewLineArr[index - 1].need ? ++times : times,
							xArrIndex:needNewLineArr[index].xArrIndex
						});
					}
					
				}
				let blockList = [...new Set(itemsPositionArr.map(i => i.lineIndex))]
				this.blockList = blockList
				
				let xArr = []
				let curXArrIndex = 0
				for (let index = 0; index < OBJ_ANCHOR_H_COUNT; index++) {
					xArr.push(68 + index * OBJ_ANCHOR_GAP)
				}
				let trueSvg = require('@/icons/answersheet/t.svg');
				let falseSvg = require('@/icons/answersheet/f.svg');
				const context = require.context('@/icons/answersheet', false, /.svg/)
				const frames = []
				context.keys().forEach(k => {
					frames.push(context(k))
				})
				let codeSvgArr = []
				items.forEach((item, index) => {
					if (index > 0 && (itemsPositionArr[index].lineIndex !== itemsPositionArr[index - 1]
							.lineIndex)) {
						this.leftItems = items.slice(index, items.length)
					}
					let optionX = CONTENT_START_X + MARGIN_LEFT + this.getStartX(number, this.leftItems, item.id,index);
					let optionY = startY + GAP * (index + 1 <= number ? index : index % number) + ((itemsPositionArr[index].lineIndex + 1) * (this.blockHeight + this.everyOptionH))
					optionX = xArr[itemsPositionArr[index].xArrIndex] + 15
					// 渲染选项下标
					let itemOrder = snap
						.text(
							optionX,
							optionY,
							this.isAutoCreate ? index + 1 : item.order
						)
						.attr({
							textAnchor: "end",
							fontSize: 12,
							fontFamily: "Consolas",
						});
					this.objectiveGroup.add(itemOrder);
					// 渲染选项图片
					item.option.forEach((option, optionIndex) => {
						let code = String.fromCharCode(
							64 + parseInt(optionIndex + 1)
						).toLowerCase();
						let img = frames.slice(10,frames.length - 1)[optionIndex]
						let c3 = snap.image(
							item.type !== 'judge' ? img : optionIndex === 0 ? trueSvg : falseSvg,
							// optionX + NUMBER_ITEM_ML + optionGap * optionIndex,
							xArr[itemsPositionArr[index].xArrIndex + optionIndex + 1],
							optionY - 10,
							NUMBER_ITEM_W,
							NUMBER_ITEM_H
						);
						this.objectiveGroup.add(c3);
						curXArrIndex = itemsPositionArr[index].xArrIndex + optionIndex + 1
					});
				});
				console.log(this.leftItems)
				// diff代表剩余的数量  是否够排满一列
				let diff =  this.leftItems.length > this.number ? 0 : (this.number - this.leftItems.length)
				let refHeight = (this.blockHeight + this.everyOptionH) * (blockList.length) - this.everyOptionH
				// 如果不够排满一列 则最后一块渲染的高度就是 差值的高度
				let objectiveHeight = this.leftItems.length >= 0 ? refHeight - this.everyOptionH * diff : refHeight
				this.anchorRectY = startY +  objectiveHeight
				// 渲染选项框横向定位锚点
				for (let index = 0; index < OBJ_ANCHOR_H_COUNT; index++) {
					this.objectiveGroup.add(
						snap.rect(
							xArr[index],
							startY + objectiveHeight,
							NUMBER_ITEM_W,
							NUMBER_ITEM_H
						).attr({ shapeRendering:"crispEdges"})
					);
				}
				// 添加纵向定位锚点
				let anchorCount = this.objectiveItems.length > number ? number : this.objectiveItems.length
				this.blockList.forEach((blockItem, blockIndex) => {
					anchorCount = blockIndex === this.blockList.length - 1 ? Math.min(this.number,this.leftItems.length) : anchorCount
					anchorCount += this.blockList.length - 1
					for (let index = 0; index < anchorCount; index++) {
						this.objectiveGroup.add(
							snap.rect(20, startY + GAP * index - 10 + (this.blockHeight * blockIndex),
								NUMBER_ITEM_W, NUMBER_ITEM_H).attr({ shapeRendering:"crispEdges"})
						);
					}
				})


				// 渲染包围框
				this.doRenderBorder(items, number, blockList.length);
			},

			// 获取每一列渲染的x坐标
			getStartX(number, items, itemId,index) {
				// 根据index求出当前列最多选项的题目从而获取当前列的宽度
				let columnCount = Math.ceil(items.length / number); // 总共多少列
				let curColumn = parseInt(items.map(i => i.id).indexOf(itemId) / number); // 当前index在第几列
				let columnWidthArr = []; // 存放每一列的距前一列的宽度
				let singleOptionW = NUMBER_ITEM_W + NUMBER_ITEM_ML;
				let columnGap = 17.15 // 列与列之间的间隔
				let orderWidth = 11 // 题号的最大宽度
				for (var i = 0; i < columnCount; i++) {
					if (i === 0) {
						columnWidthArr.push(0); // 第一列左间距为0
					} else {
						// 后面每一列的取值为前一列最多选项宽度
						let startIndex = number * (i - 1);
						let maxOpitonCount = items
							.slice(startIndex, startIndex + number)
							.map((i) => i.option.length);
						columnWidthArr.push(singleOptionW * Math.max(...maxOpitonCount) + orderWidth + columnGap);
					}
				}
				// 第几列就取前几列的宽度总和 作为x值
				return columnWidthArr.slice(0, curColumn + 1).length ? columnWidthArr.slice(0, curColumn + 1).reduce((a,b) => a + b) : 0;
			},

			// 判断是否需要换行
			needNewLine(index, number, items) {
				let columnCount = Math.ceil(items.length / number); // 总共多少列
				let curColumn = parseInt(index / number); // 当前index在第几列
				let preColumnCells = [];
				let columnCells = [];
				let cellCount = 0
				let cellCountMax = OBJ_ANCHOR_H_COUNT; // 每行最多能放的选项数
				for (var i = 0; i < columnCount; i++) {
					if (i > 0) {
						// 后面每一列的取值为前一列最多选项宽度
						let startIndex = number * (i - 1);
						let maxOpitonCount = items
							.slice(startIndex, startIndex + number)
							.map((i) => i.option.length);
						preColumnCells.push(Math.max(...maxOpitonCount));
					}

					// 去所有列的最大选项数 方便得知自己当前列的最大值
					let startIndex2 = number * i;
					let maxOpitonCount2 = items
						.slice(startIndex2, startIndex2 + number)
						.map((i) => i.option.length);
					columnCells.push(Math.max(...maxOpitonCount2));
				}
				// console.log(index,preColumnCells)
				cellCount = preColumnCells.slice(0, curColumn).length ?
					preColumnCells.slice(0, curColumn).reduce((a, b) => a + b) :
					0; // 目前已经有的选项数
				// 如果前面所有选项数
				let preAllCount = cellCount + columnCells[curColumn]
				// 触发换列
				if(this.curCellCount !== cellCount){
					this.curCellCount = cellCount
					this.curColumn++
				}
				let totalCell = cellCount - this.preBlockCellCount + columnCells[curColumn] + (this.curColumn + 1)
				// 触发换行条件：如果当前需要换行并且上一个block不需要换行
				if(totalCell > cellCountMax && !this.lastItem.need){
					this.preBlockCellCount = cellCount
					this.curColumn = 0
				}
				// 计算当前block的总选项数 = 前面所有列的最大选项数之和 加上 当前列的最大选项数
				let curBlockPreCell = cellCount - this.preBlockCellCount + this.curColumn
				// console.log(index,cellCount,this.preBlockCellCount,curBlockPreCell)
				this.lastItem = {
					need: totalCell > cellCountMax, // 是否需要换行
					xArrIndex: curBlockPreCell
				}
				return this.lastItem;
			},
		},
		mounted: function() {
			this.snap = Snap("#sheetObjectiveSvg");
			this.objectiveGroup = this.snap.paper.g();
		},
		computed: {
			totalScore() {
				return this.objectiveItems.length ? this.objectiveItems.map(i => i.score).reduce((a, b) => a + b) : 0
			},
			// 是否为根据试卷自动生成的答题卡
			isAutoCreate() {
				return this.$store.state.answerSheet.isAutoCreate
			}
		},
		watch: {
			items: {
				// 数据变化时执行的逻辑代码
				handler(n, old) {
					if (n.length) {
						let objectiveArr = ["single", "multiple", "judge"];
						this.objectiveItems = n.filter((item) =>
							objectiveArr.includes(item.type)
						);

						this.blockHeight = 16 * this.number
						this.leftItems = JSON.parse(JSON.stringify(this.objectiveItems))
						this.$nextTick(() => {
							this.doRenderItems(this.objectiveItems, this.number);
						})
					}
				},
				immediate: true,
				// 开启深度监听
				deep: true,
			},
			anchorRectY: {
				handler(n, o) {
					this.$nextTick(() => {
						this.$emit("onRendered", n);
					});
				},
			},
		},
	};
</script>
<style scoped lang="less">
	.sheet-objective-container {
		/* position: absolute; */
		/* left: 0; */
		/* top: 350px; */
		width: 826px;
	}

	/* .sheet-info-container:hover .info-edit{
    display: flex;
} */

	.info-edit {
		position: absolute;
		top: 55px;
		right: 110px;
		height: 25px;
		/* background: #00a43a; */
		display: flex;
		justify-content: center;
		align-items: center;
		color: #fff;
		font-size: 12px;
		z-index: 0;

		span {
			margin-right: 10px;
			display: table;
			background-color: #000000;
			width: 40px;
			padding: 2px 0;
			text-align: center;
			cursor: pointer;
		}
	}

	.edit-title {
		margin: 10px 0;
	}
</style>
