"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const EventEmitter = require('events').EventEmitter;
const isEqual = require('lodash.isequal');

/* contentMode
* - 0: Cropped mode. Uniformly scale the video until it fills the visible boundaries (cropped). One dimension of the video may have clipped contents.
* - 1: Fit mode. Uniformly scale the video until one of its dimension fits the boundary (zoomed to fit). Areas that are not filled due to the disparity
* in the aspect ratio will be filled with black.
*/
class RGBRenderer {
    constructor() {
        this.cacheCanvasOpts = {};
        this.event = new EventEmitter();
        this.ready = false;
        this.contentMode = 1;
        this.container = {};
        this.canvas = {};
        this.element = {};
    }
    getView() {
        return this.element;
    }
    _calcZoom(vertical = false, contentMode = 0, width, height, clientWidth, clientHeight) {
        let localRatio = clientWidth / clientHeight;
        let tempRatio = width / height;
        if (isNaN(localRatio) || isNaN(tempRatio)) {
            return 1;
        }
        if (!contentMode) {
            if (vertical) {
                return localRatio > tempRatio ?
                    clientHeight / height : clientWidth / width;
            }
            else {
                return localRatio < tempRatio ?
                    clientHeight / height : clientWidth / width;
            }
        }
        else {
            if (vertical) {
                return localRatio < tempRatio ?
                    clientHeight / height : clientWidth / width;
            }
            else {
                return localRatio > tempRatio ?
                    clientHeight / height : clientWidth / width;
            }
        }
    }
    bind(element) {
        this.element = element;
        let container = document.createElement('div');
        Object.assign(container.style, {
            width: '100%',
            height: '100%',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center'
        });
        this.container = container;
        element.appendChild(this.container);
        this.canvas = document.createElement('canvas');
        this.container.appendChild(this.canvas);
    }
    unbind() {
        this.container && this.container.removeChild(this.canvas);
        this.element && this.element.removeChild(this.container);
        this.element = null;
        this.canvas = null;
        this.view = null;
    }
    refreshCanvas() {
    }
    updateCanvas(options = {
        width: 0,
        height: 0,
        rotation: 0,
        mirrorView: false,
        contentMode: 0,
        clientWidth: 0,
        clientHeight: 0,
    }) {
        if (isEqual(this.cacheCanvasOpts, options)) {
            return;
        }
        this.cacheCanvasOpts = Object.assign({}, options);
        if (options.rotation === 0 || options.rotation === 180) {
            this.canvas.width = options.width;
            this.canvas.height = options.height;
        }
        else if (options.rotation === 90 || options.rotation === 270) {
            this.canvas.height = options.width;
            this.canvas.width = options.height;
        }
        else {
            throw new Error('Invalid value for rotation. Only support 0, 90, 180, 270');
        }
        this.canvas.style.zoom = this._calcZoom(options.rotation === 90 || options.rotation === 270, options.contentMode, options.width, options.height, options.clientWidth, options.clientHeight);
        if (options.mirrorView) {
            this.canvas.style.transform = 'rotateY(180deg)';
        }
    }
    drawFrame(imageData) {
        if (!this.ready) {
            this.ready = true;
            this.event.emit('ready');
        }
        let mirror = 0;
        let contentWidth = imageData.width;
        let contentHeight = imageData.height;
        let left = 0;
        let top = 0;
        let right = 0;
        let bottom = 0;
        let rotation = imageData.rotation;
        let ts = imageData.timestamp;
        let width = contentWidth + left + right;
        let height = contentHeight + top + bottom;
        this.updateCanvas({
            width, height, rotation,
            mirrorView: mirror,
            contentMode: this.contentMode,
            clientWidth: this.container.clientWidth,
            clientHeight: this.container.clientHeight,
        });
        let ctx = this.canvas.getContext("2d");
        let tempData = imageData.data.slice();
        const arr = new Uint8ClampedArray(tempData);
        let tmpimage = new ImageData(arr, width, height);
        ctx.putImageData(tmpimage, 0, 0);


        // var img = new Uint8Array(imageData.data, 0, width * height * 4);
        // var gl = this.canvas.getContext('experimental-webgl');
        // var tex = gl.createTexture();
        // var vbo = gl.createBuffer();
        // var program = gl.createProgram();
        // gl.bindTexture(gl.TEXTURE_2D, tex);
        // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        // gl.texImage2D(
        //     gl.TEXTURE_2D, // target
        //     0, // mip level
        //     gl.RGBA, // internal format
        //     w, h, // width and height
        //     0, // border
        //     gl.RGBA, //format
        //     gl.UNSIGNED_BYTE, // type
        //     img // texture data
        // );
        // gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        // gl.bufferData(gl.ARRAY_BUFFER, 
        //             new Float32Array([-1, -1,
        //             1, -1,
        //             1, 1,               
        //             1, 1,
        //             -1, 1,
        //             -1, -1]), gl.STATIC_DRAW);

        // program.vs = gl.createShader(gl.VERTEX_SHADER);
        // gl.shaderSource(program.vs,
        //                 "attribute vec4 vertex;\n" +
        //                 "varying vec2 tc;\n" +
        //                 "void main(){\n" +
        //                 " gl_Position = vertex;\n" +
        //                 " tc = vertex.xy*0.5+0.5;\n" +
        //                 "}\n");

        // program.fs = gl.createShader(gl.FRAGMENT_SHADER);
        // gl.shaderSource(program.fs,
        //                 "precision highp float;\n" +
        //                 "uniform sampler2D tex;\n" +
        //                 "varying vec2 tc;\n" +
        //                 "void main(){\n" +
        //                 " gl_FragColor = texture2D(tex, tc);\n" +
        //                 "}\n");

        // gl.compileShader(program.vs);
        // gl.compileShader(program.fs);

        // gl.attachShader(program,program.vs);
        // gl.attachShader(program,program.fs);

        // gl.deleteShader(program.vs);
        // gl.deleteShader(program.fs);
        // gl.bindAttribLocation(program, 0, "vertex");
        // gl.linkProgram(program);
        // gl.useProgram(program);
        // gl.enableVertexAttribArray(0);
        // gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
        // gl.clear(gl.COLOR_BUFFER_BIT);
        // gl.drawArrays(gl.TRIANGLES, 0, 6);
    }
    setContentMode(mode = 0) {
        this.contentMode = mode;
    }
}
exports.default = RGBRenderer;
