/**
 * 曲谱节拍器
 * auth: lsq
 * time: 2022.11.14
 */
import { reactive, watch } from "vue";
import { tickUrl as tick, tockUrl as tock } from "/src/constant/audios";
import { browser } from "/src/utils/index";
import state from "/src/state";
import { Howl } from "howler";
import tockAndTick from "/src/constant/tockAndTick.json";
import tickWav from "/src/assets/tick.mp3";
import tockWav from "/src/assets/tock.mp3";
import { audioData as audioDataState } from "../view/audio-list"

type IOptions = {
	speed: number;
};
const browserInfo = browser();
let tipsTimer: any = null; // 光标提示定时器

// HTMLAudioElement 音频
const audioData = reactive({
	tick: null as unknown as HTMLAudioElement,
	tock: null as unknown as HTMLAudioElement,
});

let tickTockPlayTime = 0;

export const metronomeData = reactive({
	disable: true,
	initPlayerState: false,
	lineShow: false,
	isClick: false,
	metro: null as unknown as Metronome,
	metroList: [] as number[],
	activeList: [] as number[],
	metroMeasure: [] as any[],
	activeIndex: null as any,
	activeMetro: {} as any,
	cursorMode: 2 as number, // 光标模式：1:音符指针；2:节拍指针；3:关闭指针
	cursorTips: '' as string, // 光标模式提示文字
	followAudioIndex: 1, // 当前的拍数
	totalNumerator: 2, // 总拍数
	firstBeatTypeArr:[] as number[] // 第一小节的节拍
});

watch(
	() => metronomeData.cursorMode,
	() => {
		const img: HTMLElement = document.querySelector("#cursorImg-0")!;
		if (img) {
			switch (metronomeData.cursorMode) {
				case 1:
					img.classList.remove("lineHide");
                    img.style.opacity = 'inherit'
					metronomeData.cursorTips = '您已切换到指针跟随音符播放';
                    img.style.opacity = 'inherit'
					break;
				case 2:
					img.classList.add("lineHide");
                    img.style.opacity = 'inherit'
					metronomeData.cursorTips = '您已切换到指针跟随节拍播放';
                    // console.log('光标',img)
					break;
				case 3:
                    img.style.opacity = '0'
					metronomeData.cursorTips = '您已关闭指针显示';
					// console.log('隐藏光标')
					break;
				default:
					break;
			}
			hideCursorTip()
		}
	}
);

// 切换隐藏光标
const toggleLine = () => {
	if (!metronomeData.lineShow) return;
	const img: HTMLElement = document.querySelector("#cursorImg-0")!;
	if (img) {
		if (state.times[state.activeNoteIndex].multipleRestMeasures) {
			img.classList.remove("lineHide");
		} else {
			img.classList.add("lineHide");
		}
	}
};
watch(
	() => metronomeData.lineShow,
	() => {
		const img: HTMLElement = document.querySelector("#cursorImg-0")!;
		if (img) {
			if (metronomeData.lineShow) {
				img.classList.add("lineHide");
			} else {
				img.classList.remove("lineHide");
			}
		}
	}
);

class Metronome {
	playType = "tick";
	source = null as any; // 创建音频源头
	source1 = null as any;
	source2 = null as any;

	constructor(option?: IOptions) {}
	init(times: any[]) {
		this.calculation(times);
		metronomeData.activeList = [];
		this.initPlayer()
	}
	initPlayer() {
		// if (!this.source1) {
		// 	this.source1 = this.loadAudio1();
		// }
		// if (!this.source2) {
		// 	this.source2 = this.loadAudio2();
		// }
		// metronomeData.initPlayerState = true;
		if(metronomeData.initPlayerState) return
		Promise.all([this.createAudio(tickWav), this.createAudio(tockWav)]).then(
			([tick, tock]) => {
				if (tick) {
					audioData.tick = tick;
				}
				if (tock) {
					audioData.tock = tock;
				}
				metronomeData.initPlayerState = true;
			}
		);		
	}
	createAudio = (src: string): Promise<HTMLAudioElement | null> => {
		return new Promise((resolve) => {
			// const a = new Audio(src + '?v=' + Date.now());
			const a = new Audio(src);
			a.load();
			a.onloadedmetadata = () => {
				resolve(a);
			};
			a.onerror = () => {
				resolve(null);
			};
		});
	};

	// 播放
	sound = (currentTime: number) => {
		let index = -1;
		let activeMetro = -1;
		for (let i = 0; i < metronomeData.metroList.length; i++) {
			const item = metronomeData.metroList[i];

			if (currentTime >= item) {
				// console.log(currentTime , item)
				index = i;
				activeMetro = item;
			} else {
				break;
			}
		}
		if (index > -1 && metronomeData.activeIndex !== index) {
			metronomeData.activeIndex = index;
			// console.log("播放", metronomeData.activeIndex);
			metronomeData.activeMetro = this.getStep(activeMetro);
			// console.log("🚀 ~ metronomeData.activeMetro",metronomeData.activeMetro.measureNumberIndex, metronomeData.activeMetro.index)
			tickTockPlayTime = currentTime
			this.playAudio();
			metronomeData.isClick = false;
			return;
		}
		// toggleLine()
		metronomeData.isClick = false;
	};
	
	// 暂停的时候，点击音符，需要找到对应的节拍器的位置
	findMetronomePosition = (currentTime: number) => {
		console.log('取消选段1111',currentTime)
		const originTime = currentTime;
		// if (!state.sectionStatus){
		// 	currentTime = setCurrentTime(currentTime);
		// }
		let index = -1;
		let activeMetro = -1;
		for (let i = 0; i < metronomeData.metroList.length; i++) {
			const item = metronomeData.metroList[i];
			if (currentTime >= item) {
				// console.log(currentTime , item)
				index = i;
				activeMetro = item;
			} else {
				break;
			}
		}
		if (index > -1 && (metronomeData.activeIndex !== index || (metronomeData.activeIndex === 0 && index === 0) ) ) {
			metronomeData.activeIndex = index;
			// console.log("节拍器播放", '节拍器索引:',metronomeData.activeIndex, '节拍器时间:',currentTime, '实际时间:',originTime,'xml计算的时间:',metronomeData.metroList[metronomeData.activeIndex]);
			metronomeData.activeMetro = this.getStep(activeMetro);
			console.log("🚀 ~ metronomeData.activeMetro",metronomeData.activeMetro.measureNumberIndex, metronomeData.activeMetro.index)
			tickTockPlayTime = currentTime
			// this.playAudio();
			metronomeData.isClick = false;
			return;
		}
		metronomeData.isClick = false;
		if (currentTime === 0) {
			metronomeData.activeMetro = {}
		}
	};

	// 播放
	playAudio = () => {
		// 关闭定时器节拍器
		return
		/* 如果是 评测模式且不为MIDI并且节拍器资源加载成功的时候  不运行节拍器播放*/
		if (state.modeType === "practise" && state.playMode !== "MIDI") {
			if(state.playType === "play" && state.playSource === "music" && audioDataState.songCollection.beatSongEle){
				return
			}			
			if(state.playType === "play" && state.playSource === "background" && audioDataState.songCollection.beatBackgroundEle){
				return
			}			
			if(state.playType === "sing" && state.playSource === "music" && audioDataState.songCollection.beatFanSongEle){
				return
			}			
			if(state.playType === "sing" && state.playSource === "background" && audioDataState.songCollection.beatBanSongEle){
				return
			}			
			if(state.playType === "sing" && state.playSource === "mingSong" && audioDataState.songCollection.beatMingSongEle){
				return
			}			
		}
		// console.log("播放自带的节拍器 233333")
		if (!metronomeData.initPlayerState || state.playState === 'paused') return;
		const beatVolume = state.setting.beatVolume / 100
		// this.source = metronomeData.activeMetro?.index === 0 ? this.source1 : this.source2;
		// this.source.volume(metronomeData.disable || state.playState === 'paused' ? 0 : beatVolume);
		// Audio 播放音频
		this.source = metronomeData.activeMetro?.index === 0 ? audioData.tick : audioData.tock;
		this.source.volume = metronomeData.disable ? 0 : beatVolume;
		if (this.source.volume <= 0) {
			this.source.muted = true
		} else {
			this.source.muted = false
		}
		// console.log('节拍器播放的时间',tickTockPlayTime)
		this.source.play();
	};

	/**
	 * 跟练模式播放，跟练模式没有曲子音频播放器
	 */
	simulatePlayAudio = () => {
		// console.log(333, metronomeData.followAudioIndex)
		if (!metronomeData.initPlayerState) return;
		const beatVolume = state.setting.beatVolume / 100
		// this.source = metronomeData.followAudioIndex === 1 ? this.source1 : this.source2;
		// Audio 播放音频
		this.source = metronomeData.followAudioIndex === 1 ? audioData.tick : audioData.tock;
		// this.source.volume(metronomeData.disable ? 0 : beatVolume);
		this.source.volume = metronomeData.disable ? 0 : beatVolume
		/**
		 * https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/volume
		 * volume属性在部分ios手机的Safari浏览器不被支持
		 */
		if (this.source.volume <= 0) {
			this.source.muted = true
		} else {
			this.source.muted = false
		}
		// console.log('音量',this.source,this.source.volume)
		this.source.play();
		metronomeData.followAudioIndex += 1;
		metronomeData.followAudioIndex = metronomeData.followAudioIndex > metronomeData.totalNumerator ? 1 : metronomeData.followAudioIndex;
	};

	// 切换
	selectPlay() {}

	loadAudio1 = () => {
		return new Howl({
			src: tockAndTick.tick,
			// 如果是ios手机,需要强制使用audio,不然部分系统版本第一次播放没有声音
			// html5: browserInfo.ios,
		});
	};
	loadAudio2 = () => {
		return new Howl({
			src: tockAndTick.tock,
			// html5: browserInfo.ios,
		});
	};
	getStep(time: number) {
		for (let i = 0; i < metronomeData.metroMeasure.length; i++) {
			const list = metronomeData.metroMeasure[i];
			const item = list.find((n: any) => n.time === time);
			if (item) {
				// console.log('index',item)
				return item;
			}
		}
		return {};
	}

	// 计算 所有的拍子的时间
	calculation(times: any[]) {
		// console.log("🚀 ~ times", times);
		// 1.统计有多少小节
		const measures: any[] = [];
		let xmlNumber = -1;
		let isDiff = false //弱起时间不够补的时候
		for (let i = 0; i < times.length; i++) {
			const note = times[i];
			const measureNumberXML = note.MeasureNumberXML;
			// console.log("🚀 ~ note?.noteElement?.sourceMeasure", note?.noteElement?.sourceMeasure)
			// console.log("🚀 ~ measureNumberXML", measureNumberXML, note)
			// console.log("🚀 ~ measureNumberXML", note)
			const measureListIndex = measureNumberXML - 1;
			// 当渐快渐慢的时候  不播节拍器
			if(isWithinRange(state.gradual, measureListIndex)){
				xmlNumber = measureNumberXML;
				continue
			}
			if (measureNumberXML > -1) {
				if (measureNumberXML != xmlNumber) {
					// 弱起的时候 根据音符结尾时间减去音符开头时间，得到的不是正常小节的时间，然后平均分配节拍之后，当前节拍间隔会非常短 这里弱起取整个小节的时间
					// 当小节时间 减去音符时间，前奏没有预留时间时候，从歌词开始唱的那里开始响节拍器
					let startTime = note.measures[0].time
					if(i === 0 && note.measures[0].difftime>0){
						startTime = note.measures[note.measures.length - 1].endtime - note.measures[0].measureLength
						if(startTime < 0){
							isDiff = true
						}
					}
					if(isDiff) {
						// 当前小节有歌词，开放弱起节拍器
						let isLyric = false
						let noteIndex = 0
						while(!isLyric && noteIndex<note.measures.length){
							isLyric = !!note.measures[noteIndex]?.formatLyricsEntries?.length
							noteIndex ++
						}
						isDiff = !isLyric
					}
					if(isDiff){
						xmlNumber = measureNumberXML;
						continue
					}
					// 最后一小节的时间 有可能和下一小节开始时间接不上
					const { time, endtime, noteLengthTime } = note.measures[note.measures.length - 1]
					let nextNoteStartTime = times[note.measures[note.measures.length - 1].i + 1]?.time
					let noteEndTime = 0
					if(!nextNoteStartTime){
						// 当不够的时候补上时值
						noteEndTime = time + noteLengthTime > endtime ? time + noteLengthTime : endtime
					}else{
						if(Math.abs(nextNoteStartTime - endtime)*1000< 10){
							// 当首位本来就是相连的
							noteEndTime = endtime
						}else{
							// 当首位不相连，差值大于这个音符的持续时间的时候取这个音符的时间（防止有间奏的连起来时间太长），否则直接取后一个音符的开始时间
							noteEndTime = nextNoteStartTime - time > noteLengthTime ? time + noteLengthTime : nextNoteStartTime
						}	
					}
					const m = {
						measureNumberXML: measureNumberXML,
						measureNumberIndex: measureListIndex,
						CompoundTempo: note?.noteElement?.sourceMeasure?.CompoundTempo || "",
						numerator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.numerator || 0,
						denominator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.denominator || 0,
						start: startTime,
						end: noteEndTime,
						time: noteEndTime - startTime,
						stave_x: note?.noteElement?.sourceMeasure?.verticalMeasureList?.[0]?.stave?.x || 0,
						end_x: note?.stave?.end_x || 0 || 0,
						stepList: [] as number[],
						svgs: [] as any[],
						isRestFlag: note.isRestFlag,
					};
					/**
					 * bug:#9877
					 * 多分轨合并显示，不同分轨的音符数量可能不同
					*/
					let measureArr = note.measures;
					if (state.isCombineRender) {
						measureArr = measureArr.filter((item: any) => item.MeasureNumberXML === m.measureNumberXML)
					}
					m.stepList = calculateMetroStep(measureArr, m);
					measures.push(m);
					xmlNumber = measureNumberXML;
				}
			}
		}
		//console.log(measures, measures.length,'小节汇总');

		let metroList: number[] = [];
		const metroMeasure: any[] = [];
		console.log("节拍器 每一小节时间:", measures)
		console.log("节拍器 间隔:", measures.map(item => {
			return {
				time: item.time,
				measureNumberXML: item.measureNumberXML
			}
		}))
		try {
			for (let i = 0; i < measures.length; i++) {
				const measure = measures[i];
				// 87拍和45拍要根据小节返回的CompoundTempo特殊处理
				const beatTypeArr = getBeatTypeArr(measure.numerator, measure.denominator, measure.CompoundTempo)
				const CompoundTempoArr = beatTypeArr.map((beatType:number) => {
					return Math.abs(beatType*measure.numerator)
				})
				if(i===0){
					metronomeData.firstBeatTypeArr = beatTypeArr
				}
				metroMeasure[i] = [] as number[];
				// 根据有几个拍子，划分成几份
				const widthStep = 100 / (beatTypeArr.length+1);
				// 当前拍子的组合数（2+3+2，3+2）中的数字
				let beatNum = 0;
				// if (measure.measureNumberXML == 98) {
				// 	debugger
				// }
				for (let j = 0; j < beatTypeArr.length; j++) {
					// 累加
					const beatMuit = Array(j).fill("").reduce((num:number,v:any,i:number) => {
						return num += Math.abs(beatTypeArr[i])
					}, 0) || 0
					const time = measure.time * beatMuit + measure.start;
					metroList.push(time);
					let left = "";
					// 当前拍子数对应的节拍位置索引
					let currentIdx = 0;
					if (j == 0) {
						currentIdx = 0
					} else {
						beatNum += CompoundTempoArr[j-1];
						currentIdx = beatNum
					}
					// 如果是87拍，并且是3+2+2的组合，第二拍的节拍指针需要定位到第四个音符的位置
					// if (measure.numerator === 7 && measure.denominator === 8 && measure.CompoundTempo === '3+2+2' && j === 1) {
					// 	currentIdx += 1;
					// }
					if (measure.stepList[currentIdx]) {
						left = measure.stepList[currentIdx] + "px";
					} else {
						const preLeft = measure.stepList[j - 1];
						left = !preLeft || preLeft.toString().indexOf("%") > -1 ? `${widthStep*(j+1)}%` : `${preLeft}px + ${widthStep}%`;
						measure.stepList[j] = left;
					}					
					metroMeasure[i].push({
						isTick: beatTypeArr[j] < 0,
						index: j,
						time,
						left: left?.indexOf("%") > -1 ? `calc(${left})` : left,
						measureNumberXML: measure.measureNumberXML,
						isRestFlag: measure.isRestFlag,
						stepList: measure.stepList
					});
				}
			}
		} catch (error) {
			console.log(error);
		}
		console.log('节拍器',metroList, metroMeasure);
		// 5.得到所有的节拍时间
		metronomeData.metroList = metroList;
		metronomeData.metroMeasure = metroMeasure;
		// console.log(9999,metroList,7777,metroMeasure)
		metronomeData.activeMetro = metroMeasure[0]?.[0] || {};
	}
}

/** 获取节拍类型数组 */
export function getBeatTypeArr(numerator?:number, denominator?:number, CompoundTempo?:string){
	const speedBeatUnit = state.speedBeatUnit
	const Numerator = numerator || state.osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4
	const Denominator = denominator || state.osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Denominator || 4
	let loopArr = []
	// 规则 负数代表重声，正数代表轻声
	switch (`${Numerator}/${Denominator}`) {
		case "2/2":
			loopArr = [-1/2, 1/2]
			break;		
		case "3/2":
			loopArr = [-1/3, 1/3, 1/3]
			break;
		case "5/4":
			//5/4拍根据谱面的CompoundTempo来特殊处理
			if(CompoundTempo==="2+3"){
				loopArr = [-1/5, 1/5, -1/5, 1/5, 1/5]
			}else{
				loopArr = [-1/5, 1/5, 1/5, -1/5, 1/5]
			}
			break;
		case "3/8":
			// 3/8拍 速度为浮点4分音符时候特殊处理
			if(speedBeatUnit==="1/4."){
				loopArr = [-1/1]
			}else{
				loopArr = [-1/3, 1/3, 1/3]
			}
			break;
		case "6/8":
			loopArr = [-1/2, 1/2]
			break;	
		case "7/8":
			//7/8拍根据谱面的CompoundTempo来特殊处理
			if(CompoundTempo==="2+2+3"){
				loopArr = [-2/7, 2/7, 3/7]
			}else if(CompoundTempo==="2+3+2"){
				loopArr = [-2/7, 3/7, 2/7]
			}else{
				loopArr = [-3/7, 2/7, 2/7]
			}
			break;	
		case "9/8":
			loopArr = [-3/9, 3/9, 3/9]
				break;				
		default:
			loopArr.push(-1/Numerator);
			for (let i = 1; i < Numerator; i++) {
				loopArr.push(1/Numerator);
			}
			break;
	}
	// console.log(loopArr, "loopArr")
	return loopArr
}


// 计算拍子的时值
function calculateMetroStep(arr: any[], m: any): number[] {
	const measureLength = arr.reduce((total: number, item: any) => {
		total += item._noteLength;
		return total;
	}, 0);
	const clap = measureLength / m.numerator;
	if (arr.length === 1) {
		const wholeNote = arr[0].svgElement;
		if (wholeNote && !wholeNote.isRest()) {
			const measure_bbox = wholeNote?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0, right: 0 };
			let bbox = wholeNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
			let stepWidth = Math.abs(measure_bbox.right - bbox.x) / m.numerator;
			let stepList: number[] = [];
			for (let i = 0; i < m.numerator; i++) {
				stepList.push(bbox.x - measure_bbox.x + i * stepWidth);
			}
			// console.log("🚀 ~ stepList:", stepList, m.measureNumberXML)
			return stepList;
		}
		try {
			// 开头是休止符
			if (m.measureNumberXML === 1 && wholeNote && wholeNote.isRest()) {
				const measure_bbox = wholeNote?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0, right: 0 };
				let bbox = wholeNote?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
				let stepWidth = Math.abs(measure_bbox.right - bbox.x) / m.numerator;
				let stepList: any[] = [];
				// 第一小节是休止符，节拍指针应该等分宽度
				const widthStep = 100 / (m.numerator + 1);
				// for (let i = -1; i < m.numerator - 1; i++) {
				// 	stepList.push(bbox.x - measure_bbox.x + i * stepWidth);
				// }
				// for (let i = 1; i <= m.numerator; i++) {
				// 	stepList.push(widthStep * i + '%');
				// }
				// console.log(wholeNote?.attrs?.el, m.measureNumberXML)
				// console.log("🚀 ~ stepList:", stepList, m.measureNumberXML)
				return stepList;
			}
		} catch (error) {
			console.log("🚀 ~ error:", error);
		}

		return [];
	}
	// console.log("🚀 ~ arr", [...arr],`小节总时值: ${measureLength}`, clap, m.measureNumberXML);
	let totalLength = 0;
	let notes: any[] = [];
	let stepList: number[] = [];
	for (let i = 0; i < arr.length; i++) {
		const item = arr[i];
		item.index = i;
		const noteLength = item._noteLength;
		totalLength += noteLength;
		// 大于一拍
		const exceedStep = Math.floor(totalLength / clap);
		// console.log(`note`, item?.svgElement?.attrs?.el,notes.length,{noteLength, exceedStep,clap}, m.measureNumberXML)
		if (exceedStep >= 1) {
			totalLength -= clap;
			// 一拍
			let measure_bbox = item?.svgElement?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0 };
			/**
			 * bug: #9875
			 * 简谱，渲染有点问题，先使用vf-stave的位置
			 */
			if (state.musicRenderType !== "staff") {
				measure_bbox = item?.svgElement?.attrs?.el?.parentElement?.parentElement?.querySelector('.vf-stave')?.getBoundingClientRect?.() || { x: 0 };
			}			
			/**
			 * 如果measure_bbox不存在（多分轨合并显示可能会出现），则用note再获取一次
			 */
			if (!measure_bbox.width && notes.length > 0) {
				measure_bbox = state.musicRenderType !== "staff" ? notes[0]?.svgElement?.attrs?.el?.parentElement?.parentElement?.querySelector('.vf-stave')?.getBoundingClientRect?.() || { x: 0 } : 
				notes[0]?.svgElement?.attrs?.el?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0 }
			}
			if (notes.length > 0) {
				let bbox = notes[0]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
				let x: any = bbox.x - measure_bbox.x;
				if (notes[0]._noteLength / clap >= 1) {
					const nextNote = arr[notes[0].index + 1]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: measure_bbox.right } || { x: 0 };
					const stepWidth = Math.abs(bbox.x - nextNote.x) / 2;
					x = bbox.x - measure_bbox.x + stepWidth;
					// console.log(`音符超一拍`, notes[0]?.svgElement?.attrs?.el, arr[notes[0].index + 1]?.svgElement?.attrs?.el, bbox.x - nextNote.x, stepWidth, m.measureNumberXML);
				}
				// console.log(`一拍`, notes[0]?.svgElement?.attrs?.el, m.measureNumberXML, notes[0]._noteLength , clap, 'aa')
				stepList.push(x);
			} else {
				let bbox = item?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
				let x: any = bbox.x - measure_bbox.x;
				// console.log(`一拍`, item?.svgElement?.attrs?.el, m.measureNumberXML)
				stepList.push(x);
			}
			notes = [];
			let bbox = item?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: 0 };
			let x: any = bbox.x - measure_bbox.x;
			let stepWidth = 0;
			if (exceedStep > 1) {
				// 二拍以上
				const nextNote = arr[i + 1]?.svgElement?.attrs?.el?.getBoundingClientRect?.() || { x: measure_bbox.right } || { x: 0 };
				stepWidth = Math.abs(bbox.x - nextNote.x) / exceedStep;
				// console.log("二拍以上 ~ nextNote:",bbox.x , nextNote.x,stepWidth, item?.svgElement?.attrs?.el,arr[i + 1]?.svgElement?.attrs?.el, exceedStep);
			}

			for (let j = 1; j < exceedStep; j++) {
				totalLength -= clap;
				// console.log(`超一拍`,item?.svgElement?.attrs?.el, m.measureNumberXML)
				stepList.push(x + stepWidth * j);
			}
		}

		//有时值就将音符加入
		if (totalLength > Number.EPSILON && totalLength > 0) {
			notes.push(item);
		}
	}
	stepList = stepList.reduce((list: any[], n: number) => {
		if (list.includes(n)) {
			list.push(undefined as any);
		} else {
			list.push(n);
		}
		return list;
	}, []);
	// console.log("stepList", [...stepList], m.measureNumberXML);
	return stepList;
}

// 延迟兼容处理
function setCurrentTime(time: number) {
	if (browserInfo.huawei || browserInfo.xiaomi) {
		time += 0.125;
	} else if (browserInfo.android) {
		time += 0.11;
	} else if (browserInfo.ios) {
		time += 0.01;
	}
	return time;
}

// 自动隐藏光标提示
function hideCursorTip() {
	if (!tipsTimer) {
		tipsTimer = setTimeout(() => {
			metronomeData.cursorTips = ''
			clearTimeout(tipsTimer)
			tipsTimer = null
		}, 2000);
	} else {
		clearTimeout(tipsTimer)
		tipsTimer = setTimeout(() => {
			metronomeData.cursorTips = ''
			clearTimeout(tipsTimer)
			tipsTimer = null
		}, 2000);
	}
}
function isWithinRange(ranges:any[], index:number) {
	for (const range of ranges) {
		const start = range[0].measureIndex;
		const end = range[1].measureIndex;
		if (index >= start && index < end) {
			return true;
		}
	}
	return false;
}
export default Metronome;
