
import { Director, director, Node, NodeEventType, sys, UIOpacity, UIRenderer, Vec3 } from 'cc';
import { JSB } from 'cc/env';

const nodeProto: any = Node.prototype;

const temp_v3 = new Vec3();


nodeProto._delaySort = function(){
    director.on(Director.EVENT_AFTER_UPDATE, this.sortByPosZ, this);
}
nodeProto.autoSort = function(){
    this.on(NodeEventType.CHILD_ADDED, this._delaySort, this);
}
nodeProto.sortByPosZ = function(){
    let _children = this._children;
    if (_children.length > 1) {
        // insertion sort
        let child, child2;
        for (let i = 1, count = _children.length; i < count; i++) {
            child = _children[i];
            let j = i;
            for (; j > 0 &&
                (child2 = _children[j - 1])._lpos.z > child._lpos.z; j--) {
                    _children[j] = child2;
                }
            _children[j] = child;
        }
    }
    this._updateSiblingIndex();
    if(sys.isNative){
        this._setChildren(_children);
    }
    director.off(Director.EVENT_AFTER_UPDATE, this._delaySort, this);
}
nodeProto.toX = function(x: number){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.x = x;
    this.setPosition(temp_v3);
}
nodeProto.addX = function(add_x: number){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.x += add_x;
    this.setPosition(temp_v3);
}
nodeProto.toY = function(y: number){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.y = y;
    this.setPosition(temp_v3);
}
nodeProto.addY = function(add_y: number){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.y += add_y;
    this.setPosition(temp_v3);
}
nodeProto.toZ = function(z: number, need_sort:boolean){
    this._lpos.z = z;
    // Vec3.copy(temp_v3, this._lpos);
    // temp_v3.z = z;
    // this.setPosition(temp_v3);
    if(need_sort && this.parent){
        this.parent._delaySort();
    }
}
nodeProto.toXY = function(x:number, y:number){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.x = x;
    temp_v3.y = y;
    this.setPosition(temp_v3);
}
nodeProto.to0 = function(){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.x = 0;
    temp_v3.y = 0;
    this.setPosition(temp_v3);
}
nodeProto.toXYByArr = function(pos:Array<number>){
    Vec3.copy(temp_v3, this._lpos);
    temp_v3.x = pos[0];
    temp_v3.y = pos[1];
    this.setPosition(temp_v3);
}

nodeProto.toScaleX = function(x: number){
    Vec3.copy(temp_v3, this._lscale);
    temp_v3.x = x;
    this.setScale(temp_v3);
}
nodeProto.toScaleY = function(y: number){
    Vec3.copy(temp_v3, this._lscale);
    temp_v3.y = y;
    this.setScale(temp_v3);
}
nodeProto.toScaleXY = function(scale: number){
    Vec3.copy(temp_v3, this._lscale);
    temp_v3.x = temp_v3.y = scale;
    this.setScale(temp_v3);
}
function setLocalOpacityDirty (node: Node, dirty: boolean, opacity: number) {
    if (!node.isValid) {
        return;
    }
    const render = node._uiProps.uiComp as UIRenderer;
    let final_opacity = node._uiProps.localOpacity * opacity;
    if (render && render.color) { // exclude UIMeshRenderer which has not color
        render.renderEntity.colorDirty = dirty;
        render.renderEntity.localOpacity = final_opacity
    }
    for (let i = 0; i < node.children.length; i++) {
        setLocalOpacityDirty(node.children[i], dirty, final_opacity);
    }
}
nodeProto.toOpacity = function(opacity: number){
    // console.log(this.name, opacity)
    this._uiProps.localOpacity = opacity;
    if (JSB) {
        setLocalOpacityDirty(this, true, 1);
    }
}
