import { GlobalLoader } from "../2d/loader";
import { getEnv } from "../2d/utils";
import { Texture, BaseTexture } from "../2d/texture";
import { Rectangle } from "../2d/math";

/**
 * 为了不影响原2djson图集的rotate判断，这里单独搞，rotate是6
 * @param url 
 * @param onLoad 参数就是图集的对象
 * @param onError 
 * @param imgUrl 不传会用url替换成png为图片路径
 */
export function loadAtlas(
    url: string,
    // onLoad: (textures: { [key: string]: Texture }) => void,//这种写法，d.ts生成有问题
    onLoad: (textures: any) => void,
    onError?: (err: any) => void,
    imgUrl?: string
) {
    //替换后缀改成.png
    imgUrl = imgUrl || url.replace(".atlas", ".png")
    Promise.all([
        //数据
        new Promise((r) => {
            if (getEnv() == "tb") {
                GlobalLoader.tbLoad((s, res) => {
                    r(s ? res : null)
                }, url, "utf8")
            } else {
                GlobalLoader.loadRawWeb((s, res) => {
                    r(s ? res : null)
                }, url, "text")
            }
        }) as Promise<string>,
        //图片
        new Promise((r) => {
            GlobalLoader.loadImage((s, image) => {
                r(s ? BaseTexture.fromImage(image) : null)
            }, imgUrl)
        }) as Promise<BaseTexture>
    ]).then((results) => {
        if (results[0] && results[1]) {
            var textures = createTexturesByAtlas(results[1], results[0])
            onLoad && onLoad(textures)
        } else {
            onError && onError("atlas图集：" + url + "加载失败")
        }

    })


}
//由于旋转角度问题，单开方法
export function createTexturesByAtlas(baseTexture: BaseTexture, altaData: string): { [key: string]: Texture } {
    const textures: { [key: string]: Texture } = {}
    //解析数据
    var reader = new AtlasReader(altaData)
    var tuple = new Array(4);
    var json = null
    while (true) {
        var line = reader.readLine();
        // console.log(line)
        if (line == null) break;
        line = line.trim();
        if (line.length == 0) { }
        else if (!json) {//把下面的干回去，头部信息，暂时不用，但要读完
            json = {}
            if (reader.readTuple(tuple) == 2) {
                // page.width = parseInt(tuple[0]);
                // page.height = parseInt(tuple[1]);
                reader.readTuple(tuple);
            }
            reader.readTuple(tuple);
            // page.minFilter = core.Texture.filterFromString(tuple[0]);
            // page.magFilter = core.Texture.filterFromString(tuple[1]);
            var direction = reader.readValue();
            // page.uWrap = core.TextureWrap.ClampToEdge;
            // page.vWrap = core.TextureWrap.ClampToEdge;
            // if (direction == "x")
            //     page.uWrap = core.TextureWrap.Repeat;
            // else if (direction == "y")
            //     page.vWrap = core.TextureWrap.Repeat;
            // else if (direction == "xy")
            //     page.uWrap = page.vWrap = core.TextureWrap.Repeat;
        } else {//下面的就是所有数据了
            var rotation = reader.readValue() == "true" ? 6 : 0;
            reader.readTuple(tuple);
            var x = parseInt(tuple[0]);
            var y = parseInt(tuple[1]);
            reader.readTuple(tuple);
            var w = parseInt(tuple[0]);
            var h = parseInt(tuple[1]);
            if (reader.readTuple(tuple) == 4) {
                if (reader.readTuple(tuple) == 4) {
                    reader.readTuple(tuple);
                }
            }
            var sw = parseInt(tuple[0]);
            var sh = parseInt(tuple[1]);
            reader.readTuple(tuple);
            var ox = parseInt(tuple[0]) /// resolution;
            var oy = parseInt(tuple[1]) /// resolution;
            let frame: Rectangle = null;
            //裁切的数据
            let trim: Rectangle = null;
            //贴图原始尺寸
            const orig = new Rectangle(
                0,
                0,
                Math.floor(sw),
                Math.floor(sh)
            );
            //如果旋转过
            if (rotation) {
                frame = new Rectangle(
                    Math.floor(x),
                    Math.floor(y),
                    Math.floor(h),
                    Math.floor(w)
                );
            } else {
                frame = new Rectangle(
                    Math.floor(x),
                    Math.floor(y),
                    Math.floor(w),
                    Math.floor(h)
                );
            }
            //如果是被截掉过透明边界的 ,,加上如果和原始尺寸不一致也是裁切
            if (ox || oy || w != sw || h != sh) {
                //其实就是在orig上切图，偏移
                // trim = new Rectangle(
                //     Math.floor(ox),
                //     Math.floor(oy),
                //     Math.floor(w),
                //     Math.floor(h)
                // );
                //斟酌是否有必要用Math.floor，包括上面所有的
                trim = new Rectangle(ox, sh - h - oy, w, h);
            }
            //暂时不考虑进全局图集
            textures[line] = new Texture(
                baseTexture,
                frame,
                orig,
                trim,
                rotation,
                // data.anchor
            );
            //index:-1读完
 /*region.index = parseInt(*/reader.readValue()/*)*/;
        }
    }

    return textures;
}

class AtlasReader {
    lines: Array<string>;
    index: number = 0;

    constructor(text: string) {
        this.lines = text.split(/\r\n|\r|\n/);
    }

    readLine(): string {
        if (this.index >= this.lines.length)
            return null;
        return this.lines[this.index++];
    }

    readValue(): string {
        let line = this.readLine();
        let colon = line.indexOf(":");
        if (colon == -1)
            throw new Error("Invalid line: " + line);
        return line.substring(colon + 1).trim();
    }

    readTuple(tuple: Array<string>): number {
        let line = this.readLine();
        let colon = line.indexOf(":");
        if (colon == -1)
            throw new Error("Invalid line: " + line);
        let i = 0, lastMatch = colon + 1;
        for (; i < 3; i++) {
            let comma = line.indexOf(",", lastMatch);
            if (comma == -1) break;
            tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
            lastMatch = comma + 1;
        }
        tuple[i] = line.substring(lastMatch).trim();
        return i + 1;
    }
}