import { _decorator, Node, UITransform, Component, Camera, RenderTexture, view, log, game, screen, NodeEventType, SpringJoint2D, Sprite, Texture2D, ImageAsset, SpriteFrame } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('CaptureImage')
export class CaptureImage extends Component {

    @property(Camera) copyCamera: Camera = null!; // 拷贝用的摄像机
    @property(Node) targetNode: Node = null!; // 需要捕捉的目标节点
    @property(Sprite) showImage: Sprite = null!; // 显示图像的精灵(用于产生透明像素)

    // 调试用
    @property(Node) captureBtn: Node = null!; // 捕捉按钮
    @property(Node) closeBtn: Node = null!; // 关闭按钮
    @property(Node) downloadBtn: Node = null!; // 下载按钮

    rt: RenderTexture // 渲染纹理，用于捕捉图像
    private _image: HTMLImageElement // 存储生成的 HTML 图像元素
    _canvas: HTMLCanvasElement = null!; // HTML 画布元素
    _buffer: ArrayBufferView = null!; // 用于存储读取像素的缓冲区

    start() {
        // 初始化渲染纹理，设置宽度和高度为可视区域尺寸
        this.rt = new RenderTexture();
        this.rt.reset({ width: view.getVisibleSize().width, height: view.getVisibleSize().height, });

        this.copyCamera.targetTexture = this.rt; // 设置摄像机的目标纹理为渲染纹理

        // 调试用
        // this.captureBtn.active = true; // 显示捕捉按钮
        // this.closeBtn.active = false; // 隐藏关闭按钮

        // 为捕捉按钮和关闭按钮添加触摸结束事件
        this.captureBtn.on(NodeEventType.TOUCH_END, this.copyRenderTex, this);
        this.closeBtn.on(NodeEventType.TOUCH_END, this.clearCapture, this);
        this.downloadBtn.on(NodeEventType.TOUCH_END, this.onDownLoad, this);

    }

    private copyRenderTex() {
        // 获取目标节点的宽度、高度和锚点
        const width = this.targetNode.getComponent(UITransform).width;
        const height = this.targetNode.getComponent(UITransform).height;
        const anchorPoint = this.targetNode.getComponent(UITransform).anchorPoint;
        const worldPos = this.targetNode.getWorldPosition(); // 获取目标节点的世界坐标

        // 从渲染纹理中读取像素数据
        this._buffer = this.rt.readPixels(Math.round(worldPos.x - width * anchorPoint.x), Math.round(worldPos.y - height * anchorPoint.y), width, height);

        // 创建画布，如果已存在则清空
        if (!this._canvas) {
            this._canvas = document.createElement('canvas');
            this._canvas.width = width;
            this._canvas.height = height;
        } else {
            let ctx = this._canvas.getContext('2d');
            ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
        }

        let ctx = this._canvas.getContext('2d')!; // 获取2D上下文
        let rowBytes = width * 4; // 每行字节数（RGBA）

        // 将像素数据绘制到画布上
        for (let row = 0; row < height; row++) {
            let sRow = height - 1 - row; // 反向行数
            let imageData = ctx.createImageData(width, 1); // 创建图像数据
            let start = sRow * width * 4; // 计算当前行开始的像素数据索引
            for (let i = 0; i < rowBytes; i++) {
                imageData.data[i] = this._buffer[start + i]; // 填充图像数据
            }
            ctx.putImageData(imageData, 0, row); // 将图像数据放置到画布上
        }

        // 计算缩放比例和最终图像的宽高
        const scale = (view.getVisibleSizeInPixel().height / screen.devicePixelRatio) / view.getDesignResolutionSize().height;
        const imageWidth = width * scale;
        const imageHeight = height * scale;

        // 创建新的图像元素并设置样式
        let img = new Image(imageWidth, imageHeight);
        img.style.position = "absolute";
        img.style.marginTop = -imageHeight / 2 + "px"; // 中心对齐
        img.style.marginLeft = -imageWidth / 2 + "px"; // 中心对齐
        img.style.top = "50%";
        img.style.left = "50%";
        img.src = this._canvas.toDataURL(); // 设置图像源为画布的图像数据URL

        // game.container!.appendChild(img); // 将图像添加到游戏容器中
        game.canvas.appendChild(img); // 将图像添加到游戏容器中

        if (this._image) {
            // game.container!.removeChild(this._image); // 如果已有图像，先移除
            game.canvas.removeChild(this._image); // 如果已有图像，先移除
        }
        this._image = img; // 更新当前图像


        // 独立渲染层相关(与透明区域的产生有关)
        let imageAsset = new ImageAsset(this._canvas);
        let texture2 = new Texture2D();
        texture2.image = imageAsset;
        let spriteFrame = new SpriteFrame();
        spriteFrame.texture = texture2;
        this.showImage.spriteFrame = spriteFrame;

        // 调试用
        // this.captureBtn.active = false; // 隐藏捕捉按钮
        // this.closeBtn.active = true; // 显示关闭按钮

        let base64Img = this._canvas.toDataURL();
        this.node.emit('capture', base64Img);
    }

    private clearCapture() {
        // 清理当前图像
        if (this._image) {
            // game.container!.removeChild(this._image); // 从容器中移除图像
            game.canvas.removeChild(this._image); // 从容器中移除图像
        }
        this._image = null; // 清空图像引用
        this.captureBtn.active = true; // 显示捕捉按钮
        this.closeBtn.active = false; // 隐藏关闭按钮
    }

    private onDownLoad() {
        // 下载当前图像
        if (this._image) {
            let a = document.createElement('a');
            a.href = this._image.src;
            a.download = 'capture.png';
            a.click();
        }
    }
}
