import GameDataCenter from "../../data/GameDataCenter";
import FguiLoadMgr from "../fgui/FguiLoadMgr";

const { ccclass, disallowMultiple } = cc._decorator;

/**
 * rolllabel
 */
@ccclass
@disallowMultiple
export default class RollLabel extends cc.Component {
	private targetVal: number = null;
	private startVal: number = null;
	private cb: Function = null;
	private curVal: number = null;
	private isChange: boolean = false;

	//目标和起始值的差值
	private min: number;

	//管理文本对象
	obj: fairygui.GLabel | fairygui.GTextField | fairygui.GRichTextField = null;

	private upArrCom: fairygui.GComponent;
	private upEff: cc.Tween;
	private arr: fairygui.GComponent;

	changeTime: number;
	readonly defaulChangeTime = 0.5;
	readonly defaulOffsetX = 0.5;
	readonly defaulOffsetY = 0;

	endCb: Function;

	//累计时间
	private curTime: number = 0;

	setData(targetVal: number, cb: (curval: number) => void = null, param: RollLabelParam = null) {
		this.endCb = param.endCb;
		this.changeTime = param?.changeTime ? param.changeTime : this.defaulChangeTime;
		if (cb) this.cb = cb.bind(param?.target);
		if (param?.oldval) {
			this.initLabel(param.oldval);
		}
		if (this.targetVal != null) {
			if (this.targetVal == targetVal) return;
			this.StartRollNum(targetVal);
			if (param?.needArr) {
				if (this.upArrCom == null) {
					this.upArrCom = fgui.UIPackage.createObject("Common", "RollLabelEff") as fairygui.GComponent;
					this.obj.node.addChild(this.upArrCom.node);
					this.arr = this.upArrCom.getChild("arr") as fairygui.GComponent;

					// let leftupx = -this.obj.node.anchorX * this.obj.node.width;
					// let offsetx = param?.arrOffsetX != null ? param.arrOffsetX : this.defaulOffsetX;
					// let posx = leftupx + offsetx * this.obj.node.width;

					// let leftupy = (1 - this.obj.node.anchorY) * this.obj.node.height;
					// let offsety = param?.arrOffsetY != null ? param.arrOffsetY : this.defaulOffsetY;
					// let posy = leftupy + offsety * this.obj.node.height + this.arr.height / 2;
					let leftupx = 0;
					let offsetx = param?.arrOffsetX != null ? param.arrOffsetX : this.defaulOffsetX;
					let posx = leftupx + offsetx * this.obj.width;

					let leftupy = 0;
					let offsety = param?.arrOffsetY != null ? param.arrOffsetY : this.defaulOffsetY;
					let posy = leftupy - offsety * this.arr.height;

					this.upArrCom.x = posx;
					this.upArrCom.y = posy;
					this.upArrCom.touchable = false;
				}
				this.StartEff();
			}
		} else {
			this.initLabel(targetVal);
		}
	}

	initLabel(val) {
		this.targetVal = val;
		this.curVal = val;
		this.ChangeLabel(val);
	}

	ChangeLabel(num: number) {
		if (this.cb) {
			this.cb(num);
		} else {
			FguiLoadMgr.setLabel(this.obj, num?.toString());
		}
	}

	StartEff() {
		if (this.upEff) this.upEff.stop();
		this.upArrCom.visible = true;
		this.arr.y = 0;
		this.arr.alpha = 0;
		this.upEff = cc
			.tween(this.arr)
			.to(0.15, {
				alpha: 1,
			})
			.delay(0.2)
			.to(0.15, {
				alpha: 0,
				y: -16,
			})
			.call(() => {
				this.upArrCom.visible = false;
			})
			.start();
	}

	StartRollNum(num) {
		if (this.isChange) {
			this.curVal = this.targetVal;
			this.startVal = this.curVal;
			this.SetChangeState(num);
		} else {
			this.startVal = this.curVal;
			this.SetChangeState(num);
		}
	}

	SetChangeState(targetVal: number) {
		this.targetVal = targetVal;
		this.min = this.targetVal - this.startVal;
		this.curTime = 0;
		this.isChange = true;
	}

	protected update(dt: number): void {
		if (this.isChange) {
			this.curTime += dt;
			if (this.curTime > this.changeTime) this.curTime = this.changeTime;
			let persent = this.curTime / this.changeTime;
			this.curVal = Math.floor(persent * this.min + this.startVal);
			if (this.curVal == this.targetVal || this.curTime >= this.changeTime) {
				this.curVal = this.targetVal;
				this.isChange = false;
				if (this.endCb) this.endCb();
			}
			this.ChangeLabel(this.curVal);
		}
	}

	protected onDisable(): void {
		this.clearState();
	}

	private clearState() {
		if (this.upArrCom) this.upArrCom.visible = false;
		this.isChange = false;
		this.targetVal = null;
		this.curVal = null;
		this.startVal = null;
		this.min = 0;
		this.curTime = 0;
	}
}

export class RollLabelParam {
	/**
	 * cb需要绑定的bind(target)
	 */
	target?: any;
	/**
	 * 是否需要箭头特效
	 */
	needArr?: boolean;
	/**
	 * 箭头特效向右偏移百分比，默认0.5（以文本宽度为100%
	 */
	arrOffsetX?: number;
	/**
	 * 箭头特效向上偏移百分比，默认0.5（以箭头高度为100%
	 */
	arrOffsetY?: number;
	/**
	 * 是否需要一开始就改变数字
	 */
	oldval?: number;
	/**
	 * 改变时间
	 */
	changeTime?: number;
	/**
	 * 完成时的回调
	 */
	endCb?: Function;
}
