import { _decorator, CCFloat, Component, RichText, UITransform } from 'cc';
const { ccclass, property } = _decorator;

/**
 * 富文本检查
 * 还在测试开发中
 */
@ccclass('RichTextCheck')
export class RichTextCheck extends Component {
	@property(CCFloat)
	private height: number = 0;
	@property(CCFloat)
	private width: number = 0;

	private richtext: RichText;
	private ui: UITransform

	private originFontSize: number;
	private originLineHeight: number;

	protected onLoad(){
		this.ui = this.node.getComponent(UITransform);
		this.richtext = this.node.getComponent(RichText);

		this.originFontSize = this.richtext.fontSize;
		this.originLineHeight = this.richtext.lineHeight;

		this.adaptFontSize();
	}

	private text: string;
	private calculating: boolean = false;

	private max_full_size: number;
	private min_full_size: number;
	private limit_size: number = 0;

	private _adapt_np_: mtec.NudityPromise<'end'>;

	protected lateUpdate(dt: number): void {
		if(this.richtext.string!=this.text) this.adaptFontSize();

		if(this.calculating) this.calculateFontSize();
	}

	private calculateFontSize(){
		if(this.ui.width > this.width || this.ui.height > this.height){
			this.max_full_size = this.richtext.fontSize;
		}else{
			this.min_full_size = this.richtext.fontSize;
		}

		let size = mtec.number.fixedNum((this.max_full_size + this.min_full_size) / 2, 2);
		let line_height = mtec.number.fixedNum(size * this.originLineHeight / this.originFontSize, 2);

		this.richtext.fontSize = size;
		this.richtext.lineHeight = line_height;
		this.calculating = (this.max_full_size-this.min_full_size) > 0.02;

		if(!this.calculating){
			this.limit_size = Math.min(this.limit_size, this.min_full_size);
			let np = this._adapt_np_;
			this._adapt_np_ = null;
			np.resolve('end');
		}
	}

	private adaptFontSize(){
		this.text = this.richtext.string;
		this.max_full_size = this.originFontSize;
		this.min_full_size = this.limit_size;

		let np = this._adapt_np_;
		this._adapt_np_ = new mtec.NudityPromise();
		if(np) this._adapt_np_.promise.then(()=>np.resolve('end'));

		this.calculating = true;
	}

	public forceAdatptFontSize(active: boolean){
		this.node.active = true;

		this.adaptFontSize();
		this._adapt_np_.promise.then(()=>this.node.active = active);

		return this._adapt_np_.promise;
	}

	public adaptThen<R>(callback?: ()=>R){
		let p = this._adapt_np_ ? this._adapt_np_.promise : undefined;
		return Promise.resolve(p).then(callback)
	}
}

