import Texture from "../texture/Texture";
import { Rectangle } from "../math";
import { nextPow2 } from "./twiddle";
import BaseTexture from "../texture/BaseTexture";

const pool = [];
let padding = 2;
let maxSize = 4096;
/**
 * 用于优化webgl图集处理
 * 将所有图片画于一张canvas，返回这些图片的texture
 * 不会计入全局缓存，有需要回调里缓存
 * 暂时不考虑旋转图片
 * 矩形遍历方式还有待优化，考虑是否开发属性，具体情况自行修改填充方式，还有padding
 * @param images  基本是base64形式的图片对象集{aaa:"vasdasdasdacasfwe",bbb:"vasdasdasdacasfwe"},以后支持直接的图片标签，或链接，或canvas；
 * @param callback 回调
 */
export function DrawAllToCanvas(images: any, callback) {
    let textures = {};
    let imagesAll = [];
    //获取所有图片的数量
    var countAll = Object.getOwnPropertyNames(images).length;
    preLoad(images, (img) => {
        imagesAll.push(img);
        //全部加载好后
        if (imagesAll.length == countAll) {
            //排序,宽从小到大，高从小到大，因为时倒序放
            imagesAll.sort(compare('width', 'height'));
            while (imagesAll.length) {
                //只要imagesAll中还有图片就一直执行
                putInCanvas(imagesAll, textures)
            }
            callback(textures)
        }
    })
}


function preLoad(images: any, callback: Function) {
    for (var key in images) {
        var bitmap = images[key];
        // let imgTag = document.createElement('img');
        // let imgTag = new Image();
        let backCanvas;
        if (typeof (bitmap) == 'string') {
            let imgTag = new Image();
            if (bitmap.indexOf("iVBO") === 0 || bitmap.indexOf("/9j/2w") === 0) {
                imgTag.src = 'data:image/png;base64,' + bitmap;
            }
            else {
                //如果是图片链接
                imgTag.src = bitmap;
            }
            imgTag["imageKey"] = key;
            imgTag.onload = function () {
                callback(imgTag)
            }
        }
        //如果是图片标签
        else if (bitmap instanceof HTMLImageElement) {
            bitmap["imageKey"] = key;
            if (bitmap.complete && bitmap.width && bitmap.height) {
                callback(bitmap)
            } else {
                //还未加载
                bitmap.onload = function () {
                    callback(bitmap)
                }
            }
        }
        //如果是canvas
        else if (bitmap instanceof HTMLCanvasElement) {
            callback(bitmap)
        }
    }
}

function compare(name1, name2) {
    return function (a, b) {
        let fir1 = a[name1];
        let sec1 = b[name1];
        if (fir1 === sec1) {
            let fir2 = a[name2];
            let sec2 = b[name2];
            if (fir2 === sec2) {
                return 0; // 表示位置不变
            } else {
                return fir2 > sec2 ? 1 : -1; // 表示从大到小排序 
            }
        } else {
            return fir1 > sec1 ? 1 : -1; // 表示从小到大排序
        }
    }
}
/**
 * 合图集核心，差一点，要不要考虑图片旋转，暂时没有，如需添加，texture底层需修改
 * @param imagesAll 
 * @param textures 
 */
function putInCanvas(imagesAll, textures) {
    //可用矩形
    var freeRects = [];
    //图片信息数组
    var imageInfos: imageInfo[] = [];
    //先初始化maxSize*maxSize
    var canvas = document.createElement('canvas');
    canvas.width = maxSize;
    canvas.height = maxSize;
    //添加第一个可用矩形
    freeRects.push(new Rectangle(0, 0, maxSize, maxSize))
    //可变
    var canvasWidth = 0, canvasHeight = 0
    //先排满在canvas
    let match = false;
    for (var i = imagesAll.length - 1; i >= 0; i--) {
        let img = imagesAll[i];
        match = false
        for (var j = freeRects.length - 1; j >= 0; j--) {
            let freeRect = freeRects[j];
            if (freeRect.width >= img.width + padding && freeRect.height >= img.height + padding) {
                match = true
                //有满足的，记录
                var imageIn = new imageInfo(img, freeRect.x, freeRect.y)
                imageInfos.push(imageIn)
                //imagesAll里移除
                imagesAll.splice(i, 1);
                //freeRects里移除
                freeRects.splice(j, 1);
                //然后添加两个矩形,如果为边缘矩形，就用unshift，否则用push，因为是倒序，push的会先检测，先占用；
                //考虑何种方式最优
                //right
                var restW = freeRect.width - img.width - padding
                if (restW > 0) {
                    var rightRect = new Rectangle(freeRect.x + img.width + padding, freeRect.y, restW, img.height + padding);
                    freeRect.y == 0 ? freeRects.unshift(rightRect) : freeRects.push(rightRect)
                }
                //down
                var restH = freeRect.height - img.height - padding
                if (restH > 0) {
                    var downRect = new Rectangle(freeRect.x, freeRect.y + img.height + padding, freeRect.width, restH);
                    freeRect.x == 0 ? freeRects.unshift(downRect) : freeRects.push(downRect)
                }
                //修改宽高
                // if (freeRect.x == 0) canvasHeight += (img.height + padding)
                // if (freeRect.y == 0) canvasWidth += (img.width + padding)
                //有任何一个imageIn的x加width大于canvasWidth就修改
                if (imageIn.image.width + imageIn.x > canvasWidth) {
                    canvasWidth = imageIn.image.width + imageIn.x
                }
                if (imageIn.image.height + imageIn.y > canvasHeight) {
                    canvasHeight = imageIn.image.height + imageIn.y
                }
                break
            }
        }
        //只要出现一张没放下，就break
        if (!match) break
    }
    //检查canvas宽高，尽可能小
    canvas.width = nextPow2(canvasWidth + padding);
    canvas.height = nextPow2(canvasHeight + padding);
    //开始绘制
    var ctx = canvas.getContext("2d")
    for (var m = 0; m < imageInfos.length; m++) {
        let imageInfo = imageInfos[m];
        let image = imageInfo.image
        ctx.drawImage(imageInfo.image, 0, 0, image.width, image.height, imageInfo.x, imageInfo.y, image.width, image.height)
    }
    //查看canvas
    // document.body.appendChild(canvas)
    //基础纹理
    var baseTexture = new BaseTexture(canvas);
    //赋值所有纹理
    for (var n = 0; n < imageInfos.length; n++) {
        let imageInfo = imageInfos[n];
        let image = imageInfo.image
        //纹理imageKey
        textures[image.imageKey] = new Texture(
            baseTexture,
            new Rectangle(imageInfo.x, imageInfo.y, image.width, image.height),//大图上的位置
            new Rectangle(0, 0, image.width, image.height),//原始尺寸
            null,
        );
    }

}

class imageInfo {
    image: any;
    x: number;
    y: number;
    constructor(image: any, x: number = 0, y: number = 0) {
        this.image = image;
        this.x = x;
        this.y = y;

    }
}

