# src/layers/windLayer.js

    import {CanvasOverlayer} from './canvasOverlay';

    /**
     * initWindlayer based on mapboxgl-canvas
     */
    export class WindLayer extends CanvasOverlayer {
        constructor(opts) {
            let _opts = opts || {};
            super(_opts);
            this.windImage = _opts.image || new Image();
            this.radius = _opts.radius || 2;
            // this.redraw = _redraw.bind(this);
        }

        /**
         * render particles based on image
         * @param {*grid wind image} image
         */
        updateWind(image, geojson, compressRatio) {
            let canvas = this.canvas, pix2render = [],
                ctx = this.canvas.getContext("2d");
            if (this.particles == undefined) {
                console.log("generating particles...");
                this.particles = genParticles(image, geojson, compressRatio, this.radius);
            }
            // ctx.globalAlpha = 0.95;
            if (!geojson) {
                console.log("generating particles complete! num: " + this.particles.length);
                this.redraw(this.particles);
            } else {
                // wind data should be rendered as mapboxgl vector.
                console.log("generating particles complete! num: " + this.particles.features.length + " in geojson.");
            }
        }
    }

    function _redraw() {
        // this.particles
    }

    /**
     * generate particles based on got Grid wind image.
     * (actually image -> particles)
     * called after wind image loaded event..
     * return particles: Array, particles with wind strength and angle.
     */
    function genParticles(image, geojson, compressRatio, radius) {
        let windImage = image || this.windImage,
            tmpCanvas = document.createElement("canvas"),
            tmpCtx = tmpCanvas.getContext("2d"),
            particles = [], features = [];
        if (geojson) {
            particles = {
                "type": "FeatureCollection",
                "name": "particles",
                "features": features
            }
        }

        tmpCanvas.width = windImage.width;
        tmpCanvas.height = windImage.height;
        tmpCtx.drawImage(windImage, 0, 0);
        // imageData.data.length: width*height*4
        let imageData = tmpCtx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height),
            dataLength = imageData.data.byteLength;
        if (compressRatio == undefined || (compressRatio !== undefined && compressRatio < 1)) {
            console.warn("Input compressRatio invalid, use default 1.");
            compressRatio = 1;
        }
        compressRatio = parseInt(Number(compressRatio));
        for (let i=1;i<tmpCanvas.height-1;i+=compressRatio) {
            // i:0~180, j:0~360
            for (let j=0;j<tmpCanvas.width;j+=compressRatio) {
                let particle = {
                    'lon': -180 + j,
                    'lat': -90 + i,
                };
                let uIndex = (i * 360 + j) * 4, vIndex = uIndex + 1;
                let uVal = imageData.data[uIndex], vVal = imageData.data[vIndex],
                    windPow = Math.pow(uVal, 2) + Math.pow(vVal, 2),
                    angle = Number(Math.atan(vVal/uVal).toFixed(2)),
                    color = 'rgba('+ (windPow/255).toFixed(0) + ', 255, 100, 0.7)';
                // return geojson dataSource for mapboxgl.vector layer.
                if (geojson) {
                    particle = { "type": "Feature",
                        "properties": {
                            "angle": angle,
                            "color": color
                        },
                        "geometry": {
                            "type": "Point",
                            "coordinates": [-180 + j, -90 + i]
                        }
                    }
                    features.push(particle);
                } else {
                    particle.color = color;
                    particle.angle = angle;
                    particle.radius = radius;
                    particles.push(particle);
                }
            }
        }
        return particles;
    }