<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;">编辑</span>
			<span @click="doDelete" style="background-color: red;" v-if="!isAutoCreate">删除</span>
		</div>
		<Modal v-model="editModal" title="配置基本信息项" @on-ok="onReRender">
			<p class="edit-title">每列显示题数</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
	} 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
			};
		},
		created() {
			this.snap = Snap("#sheetObjectiveSvg");
		},
		methods: {
			doDelete() {
				this.$EventBus.$emit('deleteItem', 'objective')
			},
			// 修改每列展示题数重新渲染
			onReRender() {
				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;
				// 信息框
				let infoBox = snap
					.rect(CONTENT_START_X, 2, INFO_W, this.anchorRectY + 20)
					.attr({
						fill: "rgba(0,0,0,0)",
						stroke: "#000"
					});
				this.objectiveGroup.add(infoBox);
				this.$EventBus.$emit('doRefresh')
			},

			// 渲染客观题目
			doRenderItems(items, number) {
				this.blockHeight = 26 * 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 = 22;
				let optionGap = NUMBER_ITEM_W + 5;
				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 = [];
				// 提前计算 每个题目排列时 是否要进行换行 以及计算需要换到第几行 （行可以理解为选项块）
				for (let index = 0; index < items.length; index++) {
					itemsPositionArr.push({
						index: index,
						needNewLine: needNewLineArr[index].need,
						lineIndex: needNewLineArr[index].blockIndex
					});
				}
				let blockList = [...new Set(itemsPositionArr.map(i => i.lineIndex))]
				this.blockList = blockList

				items.forEach((item, index) => {
					if (index > 0 && (itemsPositionArr[index].lineIndex !== itemsPositionArr[index - 1]
						.lineIndex)) {
						this.leftItems = this.leftItems.slice(index, this.leftItems.length)
					}
					let optionX = CONTENT_START_X + MARGIN_LEFT + this.getStartX(number, this.leftItems, item.id);
					let optionY = startY + GAP * (index + 1 <= number ? index : index % number) + ((
						itemsPositionArr[index].lineIndex + 1) * this.blockHeight)
					// console.log(index,optionX)
					// 渲染选项下标
					let itemOrder = snap
						.text(
							optionX,
							optionY,
							this.isAutoCreate ? index + 1 : item.order
						)
						.attr({
							textAnchor: "end",
							width: 40,
							fontSize: 12,
							fontFamily: "Times New Roman",
						});
					this.objectiveGroup.add(itemOrder);

					item.option.forEach((option, optionIndex) => {
						let code = String.fromCharCode(
							64 + parseInt(optionIndex + 1)
						).toLowerCase();
						// 渲染选项图片
						// let img = require("../../icons/answersheet/" + code + ".svg");
						let img = require('@/icons/answersheet/' + code + '.svg');
						let trueSvg = require('@/icons/answersheet/t.svg');
						let falseSvg = require('@/icons/answersheet/f.svg');
						let c3 = snap.image(
							item.type !== 'judge' ? img : optionIndex === 0 ? trueSvg : falseSvg,
							optionX + NUMBER_ITEM_ML + optionGap * optionIndex,
							optionY - 10,
							NUMBER_ITEM_W,
							NUMBER_ITEM_H
						);
						this.objectiveGroup.add(c3);
					});

				});

				let diff = this.leftItems.length - this.number
				let refHeight = this.blockHeight * (blockList.length - 1)
				let objectiveHeight = diff > 0 ? refHeight : refHeight - 26 * diff * -1
				this.anchorRectY = startY + GAP * number + objectiveHeight
				for (let index = 0; index < 28; index++) {
					// 渲染选项框横向定位锚点
					this.objectiveGroup.add(
						snap.rect(
							CONTENT_START_X + MARGIN_LEFT + NUMBER_ITEM_ML + optionGap * (index - 1),
							startY + GAP * number + objectiveHeight,
							NUMBER_ITEM_W,
							NUMBER_ITEM_H
						)
					);
				}
				// 添加纵向定位锚点
				let anchorCount = this.objectiveItems.length > number ? number : this.objectiveItems.length
				this.blockList.forEach((blockItem, blockIndex) => {
					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)
						);
					}
				})


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

			// 获取每一列渲染的x坐标
			getStartX(number, items, itemId) {
				// 根据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 = 10 // 列与列之间的间隔
				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 cellCountMax = 20; // 每行最多能放的选项数
				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));
				}
				let cellCount = preColumnCells.slice(0, curColumn).length ?
					preColumnCells.slice(0, curColumn).reduce((a, b) => a + b) :
					0; // 目前已经有的选项数
				// 如果前面所有列的最大选项数之和 加上 当前列的最大选项数  大于最大值 则需要换行
				let totalCell = cellCount + columnCells[curColumn]
				return {
					need: totalCell > cellCountMax, // 是否需要换行
					blockIndex: totalCell > cellCountMax ? parseInt(totalCell / cellCountMax) - 1 : -1 // 当前需要换到第几行
				};
			},
		},
		mounted: function() {
			this.snap = Snap("#sheetObjectiveSvg");
			this.objectiveGroup = this.snap.paper.g();

			// this.$nextTick(() => {
			//   this.$emit("onRendered", this.$refs.baseInfoRef.clientHeight);
			// });
		},
		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 = 26 * 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: 750px;
	}

	/* .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>
