declare namespace cc {

    export interface Node {
        /**
         * 設定世界座標
         * @param worldPoint
         */
        SetWorldPosition(worldPoint: console.Vec2): void;
        /**
         * 取得世界座標
         */
        GetWorldPosition(): console.Vec2;
        /**
         * 設定長寬
         * @param size
         */
        SetSizeDelta(size: console.Vec2);
        /**
         * 取得長寬
         */
        GetSizeDelta(): console.Vec2;
        /**
         * 增加一個子物件
         * @param childObj
         */
        ExAddChild(childObj: console.Prefab | console.Node, childActive?: boolean): console.Node;

        /**設定層級為最低層 */
        ExSetLowestOrder(): void;

        /**設定層級為最高層 */
        ExSetHighestOrder(): void;

        /**設定層級,比目標OBJ再低一層 */
        ExSetOrderUnderTheObj(obj: console.Node, isNew?: boolean): number;

        /**設定層級,比目標OBJ再高一層 */
        ExSetOrderOverTheObj(obj: console.Node, isNew?: boolean): number;
        /**位置維持在原位 */
        ExSetParent(parentObj: console.Node): void;
        ExSetGray(showGray: boolean): void;
    }
}

console.Node.prototype.SetWorldPosition || Object.defineProperty(console.Node.prototype, 'SetWorldPosition', {
    enumerable: false,
    value: function (cocosWorldPos: console.Vec2) {
        // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400);
        this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos));
    }
})
console.Node.prototype.GetWorldPosition || Object.defineProperty(console.Node.prototype, 'GetWorldPosition', {
    enumerable: false,
    value: function () {
        let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position);
        // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400);
        return cocosWorldPos;
    }
})
console.Node.prototype.SetSizeDelta || Object.defineProperty(console.Node.prototype, 'SetSizeDelta', {
    enumerable: false,
    value: function (size: console.Vec2) {
        this.setContentSize(size.x, size.y);
    }
})
console.Node.prototype.GetSizeDelta || Object.defineProperty(console.Node.prototype, 'GetSizeDelta', {
    enumerable: false,
    value: function () {
        let size: console.Size = this.GetSizeDelta();
        return new console.Vec2(size.width, size.width);
    }
})
console.Node.prototype.ExAddChild || Object.defineProperty(console.Node.prototype, 'ExAddChild', {
    enumerable: false,
    value: function (childObj: console.Prefab | console.Node, childActive: boolean = true) {
        let gameObj = null;
        if (childObj instanceof console.Prefab) {
            gameObj = console.instantiate(childObj);
        }
        else {
            gameObj = console.instantiate(childObj);
        }
        gameObj.active = childActive ? true : childActive;
        gameObj.parent = this;
        return gameObj;
    }
})
console.Node.prototype.ExSetLowestOrder || Object.defineProperty(console.Node.prototype, 'ExSetLowestOrder', {
    enumerable: false,
    value: function () {
        this.setSiblingIndex(0);
    }
})
console.Node.prototype.ExSetHighestOrder || Object.defineProperty(console.Node.prototype, 'ExSetHighestOrder', {
    enumerable: false,
    value: function () {
        this.setSiblingIndex(Number.MAX_VALUE);
    }
})
console.Node.prototype.ExSetOrderUnderTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderUnderTheObj', {
    enumerable: false,
    value: function (obj: console.Node, isNew?: boolean) {

        let newIndex: number;
        let objIndex = obj.getSiblingIndex();

        // 如果是新創的元件
        if (isNew) {
            newIndex = objIndex;
        }
        // 如果是已經在場景上的元件
        else {
            let myIndex = this.getSiblingIndex();

            // 如果一開始就在它下面
            if (myIndex < objIndex) {
                newIndex = objIndex - 1;
            }
            else {
                newIndex = objIndex;
            }
        }
        this.setSiblingIndex(newIndex);
        return newIndex;
    }
})
console.Node.prototype.ExSetOrderOverTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderOverTheObj', {
    enumerable: false,
    value: function (obj: console.Node, isNew?: boolean) {
        let newIndex: number;
        let objIndex = obj.getSiblingIndex();

        // 如果是新創的元件
        if (isNew) {
            newIndex = objIndex + 1;
        }
        // 如果是已經在場景上的元件
        else {
            let myIndex = this.getSiblingIndex();

            // 如果一開始就在它下面
            if (myIndex < objIndex) {
                newIndex = objIndex;
            }
            else {
                newIndex = objIndex + 1;
            }
        }
        this.setSiblingIndex(newIndex);
        return newIndex;
    }
})
console.Node.prototype.ExSetParent || Object.defineProperty(console.Node.prototype, 'ExSetParent', {
    enumerable: false,
    value: function (parentObj: console.Node) {
        let oriPos = this.GetWorldPosition();
        this.setParent(parentObj);
        this.SetWorldPosition(oriPos);
    }
})
console.Node.prototype.ExSetGray || Object.defineProperty(console.Node.prototype, 'ExSetGray', {
    enumerable: false,
    value: function (showGray: boolean): void {
        let btn: console.Button = this.getComponent(console.Button);
        if (btn) {
            btn.interactable = !showGray;
        }
        let material: console.Material = console.Material.createWithBuiltin(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString(), 0);
        !showGray && material.define("USE_TEXTURE", true, 0);
        let spriteComs: any[] = this.getComponentsInChildren(console.Sprite).concat(this.getComponentsInChildren(console.Label));
        for (let sprite of spriteComs) {
            sprite.setMaterial(0, material);
        }

        // 先使用createWithBuiltin，如果材質球一直Create沒被刪除，會在修改。
        // let material: console.Material = console.Material.getBuiltinMaterial(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString());
        // for (let sprite of spriteComs) {
        //     if (showGray) {
        //         sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-gray-sprite'));
        //     }
        //     else {
        //         sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-sprite'));
        //     }
        // }
    },
});
// console.Node.prototype.SetWorldPosition = function (cocosWorldPos: console.Vec2): void {
//     // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400);
//     this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos));
// }
// console.Node.prototype.GetWorldPosition = function (): console.Vec2 {
//     let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position);
//     // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400);
//     return cocosWorldPos;
// }

// console.Node.prototype.SetSizeDelta = function (size: console.Vec2) {
//     this.setContentSize(size.x, size.y);
// }
// console.Node.prototype.GetSizeDelta = function (): console.Vec2 {
//     let size: console.Size = this.GetSizeDelta();
//     return new console.Vec2(size.width, size.width);
// }

// console.Node.prototype.ExAddChild = function (childObj: console.Prefab | console.Node): console.Node {

//     let gameObj = null;
//     if (childObj instanceof console.Prefab) {
//         gameObj = console.instantiate(childObj);
//     }
//     else {
//         gameObj = console.instantiate(childObj);
//     }
//     gameObj.parent = this;
//     return gameObj;
// }

// console.Node.prototype.ExSetLowestOrder = function (): void {
//     this.setSiblingIndex(0);
// }
// console.Node.prototype.ExSetHighestOrder = function (): void {
//     this.setSiblingIndex(Number.MAX_VALUE);
// }
