import * as cc  from 'cc';
import { DEBUG } from 'cc/env';

export class HitColor {
    static hitTestAll(pos: cc.Vec3, node: cc.Node): boolean {
        if(this.hitTest(pos, node)){
            return true;
        }
        for(var i = 0; i < node.children.length; i++){
            var item = node.children[i];
            if(item.active && this.hitTestAll(pos, item))
                return true;
        }
        return false;
	}
	static hitTest(pos: cc.Vec3, node: cc.Node,a=0): boolean {
        const sprite = node.getComponent(cc.Sprite);
        if(!sprite || !sprite.spriteFrame)
            return false;
		const ppos = world2pixel(pos, node);
		const texture = sprite.spriteFrame.texture;
		const color = readpixel(texture, ppos.x, ppos.y, node);
        if(DEBUG && color && color.a !== 0){
            // console.log("hitTest=true");
        }
		return color && ( color.a > a);
	}

	static hitColor(pos: cc.Vec3, node: cc.Node): cc.math.Color | null {
		const ppos = world2pixel(pos, node);
		const texture = node.getComponent(cc.Sprite).spriteFrame.texture;
		return readpixel(texture, ppos.x, ppos.y);
	}
}

function world2pixel(pos: cc.Vec3, node: cc.Node): cc.Vec2 {
	const wpos = pos.clone();
	const sprite = node.getComponent(cc.Sprite);
    const transform = node.getComponent(cc.UITransform);
    transform.convertToNodeSpaceAR(wpos, wpos);
    wpos.x += transform.anchorX * transform.width;
    wpos.y = transform.height - (wpos.y + transform.anchorY*transform.height);
    const packable = sprite.spriteFrame.packable;
    const offset = sprite.spriteFrame.offset;
    const rect = sprite.spriteFrame.rect;
    const texture = sprite.spriteFrame.texture;
    const sx = (sprite.trim?rect.width:(packable?transform.width:texture.width))/transform.width;
    const sy = (sprite.trim?rect.height:(packable?transform.height:texture.height))/transform.height;
    const x = Math.round(wpos.x*sx + (sprite.trim?rect.x:0));
	const y = Math.round(wpos.y*sy + (sprite.trim?rect.y:0));
    return cc.v2(x, y);
}

const buffer = new Uint8Array(4);
const region = new cc.gfx.BufferTextureCopy();
region.texOffset.x = 0;
region.texOffset.y = 0;
region.texExtent.width = 1;
region.texExtent.height = 1;

function readpixel(texture: cc.Texture2D, x: number, y: number, node: cc.Node): cc.math.Color | null {
    const gfxTexture = texture.getGFXTexture();
    if (!gfxTexture) {
        return null;
    }
    // 检查是否为压缩纹理格式
    const isCompressed = isCompressedFormat(gfxTexture.info.format);

    region.texOffset.x = x;
    region.texOffset.y = y;
    cc.director.root?.device.copyTextureToBuffers(gfxTexture, [buffer], [region]);
    // console.log(buffer);
    let color = new cc.math.Color(...buffer);
    if (DEBUG) {
        // console.log(`像素位置(${x},${y})颜色: R=${color.r}, G=${color.g}, B=${color.b}, A=${color.a}`);
    }
    return color;
}

// 判断是否为压缩纹理格式
function isCompressedFormat(format: cc.gfx.Format): boolean {
    const Format = cc.gfx.Format;
    return (format >= Format.ASTC_RGBA_4X4 && format <= Format.ASTC_SRGBA_12X12) ||
           (format >= Format.BC1 && format <= Format.BC7) ||
           (format >= Format.ETC_RGB8 && format <= Format.ETC2_SRGB8_A8);
}