import { Label, Color, Component, _decorator, UITransform, SpriteFrame, Node, Sprite, builtinResMgr, dynamicAtlasManager, Widget } from 'cc';
const { type, ccclass, requireComponent } = _decorator;
const whitetexture = () => <any>builtinResMgr.get('white-texture');
const assign = Object.assign;

/**
 * 显示 dynamic atlas 和 Label atlas 内容
 * 点击右下文字(cur/total)可以切换当前查看的页面
 */
@ccclass
@requireComponent(UITransform)
export class DynamicAtlasViewer extends Component {
	@type(Sprite) private sp: Sprite = null;
	@type(Label) private lb: Label = null;
	@type(Sprite) private bg: Sprite = null;

	private _i = 0;

	onLoad() {
		const { layer } = this.node;
		const texture = whitetexture();

		if (!this.bg) {
			const bg = assign(new Node, { layer });
			uniMargins(assign(bg.addComponent(Widget), { alignMode: Widget.AlignMode.ALWAYS }));
			this.bg = assign(bg.addComponent(Sprite), { sizeMode: Sprite.SizeMode.CUSTOM, color: new Color('#AAAAAAFF'), spriteFrame: assign(new SpriteFrame, { texture, packable: false }) });
			this.node.addChild(bg);
		}

		if (!this.sp) {
			const sp = assign(new Node, { layer });
			uniMargins(assign(sp.addComponent(Widget), { alignMode: Widget.AlignMode.ALWAYS }));
			this.sp = assign(sp.addComponent(Sprite), { sizeMode: Sprite.SizeMode.CUSTOM, spriteFrame: assign(new SpriteFrame, { texture, packable: false }) });
			this.node.addChild(sp);
		}

		if (!this.lb) {
			const lb = assign(new Node, { layer });
			assign(lb.addComponent(Widget), { isAlignBottom: true, isAlignRight: true, alignMode: Widget.AlignMode.ALWAYS });
			this.lb = assign(lb.addComponent(Label), { color: Color.RED, fontSize: 30, string: '0/0', cacheMode: Label.CacheMode.CHAR });
			this.node.addChild(lb);
		}
	}

	onEnable() {
		this.sp.spriteFrame.texture = whitetexture();
		this._i = 0;
		this.lb.node.on(Node.EventType.TOUCH_END, this._touchEnd, this);
	}

	onDisable() {
		this.sp.spriteFrame.texture = whitetexture();
		this.lb.node.off(Node.EventType.TOUCH_END, this._touchEnd, this);
	}

	update() {
		const { sp, lb, _i } = this;
		const atlases = dynamicAtlasManager['_atlases'];
		const tex = _i < atlases.length ? atlases[_i]?._texture : lb['_texture'];

		if (tex !== sp.spriteFrame.texture) {
			sp.spriteFrame.texture = tex ?? whitetexture();
			//需要通知 assembler 更新 texture 信息
			sp.setTextureDirty();
			sp.markForUpdateRenderData();
		}

		lb.string = (_i < atlases.length) ? (dynamicAtlasManager.atlasCount > 0 ? `${_i + 1}/${dynamicAtlasManager.atlasCount + 1}` : "disabled") : 'CHARS';
	}

	private _touchEnd() {
		this._i = (this._i + 1) % (dynamicAtlasManager.atlasCount + 1);
	}
}

export function uniMargins(widget: Widget, margin = 0): Widget {
	widget.isAlignLeft = widget.isAlignRight = widget.isAlignTop = widget.isAlignBottom = true;
	widget.left = widget.right = widget.top = widget.bottom = margin;
	return widget;
}