#include "Asset_ImagePack.h"

Asset_ImagePack::Asset_ImagePack()
{
}
Asset_ImagePack::~Asset_ImagePack()
{
}

void Asset_ImagePack::Init()
{
    DIR *dir;
    struct dirent *ent;
    std::string path = "ImagePacks2/";
    dir = opendir(path.c_str());

    while ((ent = readdir(dir)))
    {
        // 跳过.和..目录
        if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
            continue;
        std::string RealPath = path + ent->d_name;
        Ifstream_NPK Fs;
        Fs.open(RealPath.c_str(), std::ios::in | std::ios::binary);
        if (Fs.is_open())
        {
            std::string Header = Fs.ReadString();
            // 如果是NPK
            if (Header.find("NeoplePack_Bill") != std::string::npos)
            {
                // 读取img数量
                int ImageCount = Fs.ReadInt();
                // 读取头
                NpkInfo *ImgList = new NpkInfo[ImageCount];
                for (int i = 0; i < ImageCount; i++)
                {
                    ImgList[i].Offset = Fs.ReadInt();
                    ImgList[i].Length = Fs.ReadInt();
                    ImgList[i].Path = Fs.ReadInfo();
                }
                for (int i = 0; i < ImageCount; i++)
                {
                    IMG img;
                    img.imgOffset = ImgList[i].Offset;
                    img.imgSize = ImgList[i].Length;
                    img.img_index = i;
                    img.lpBelongsFile = ent->d_name;
                    img.lpImgName = ImgList[i].Path;
                    img.lp_lplist = NULL;
                    img.png_sum = 0;

                    map_npk.insert(make_pair(img.lpImgName, img));
                }
                // 销毁
                delete[] ImgList;
            }
        }
        Fs.close();
    }
    closedir(dir);
}

void Asset_ImagePack::ParseColor(BYTE *Tab, int Type, BYTE *SaveByte, int Offset)
{
    BYTE a = 0;
    BYTE r = 0;
    BYTE g = 0;
    BYTE b = 0;
    switch (Type)
    {
    case 0x0e:
        a = (BYTE)(Tab[1] >> 7);
        r = (BYTE)((Tab[1] >> 2) & 0x1f);
        g = (BYTE)((Tab[0] >> 5) | ((Tab[1] & 3) << 3));
        b = (BYTE)(Tab[0] & 0x1f);
        a = (BYTE)(a * 0xff);
        r = (BYTE)((r << 3) | (r >> 2));
        g = (BYTE)((g << 3) | (g >> 2));
        b = (BYTE)((b << 3) | (b >> 2));
        break;
    case 0x0f:
        a = (BYTE)(Tab[1] & 0xf0);
        r = (BYTE)((Tab[1] & 0xf) << 4);
        g = (BYTE)(Tab[0] & 0xf0);
        b = (BYTE)((Tab[0] & 0xf) << 4);
        break;
    }
    SaveByte[Offset + 0] = b;
    SaveByte[Offset + 1] = g;
    SaveByte[Offset + 2] = r;
    SaveByte[Offset + 3] = a;
}

void Asset_ImagePack::LoadImgToMem(IMG *p)
{
    std::string Path = "ImagePacks2/" + p->lpBelongsFile;
    // SDL_Log("LoadImgToMem : %s", Path.c_str());
    Ifstream_NPK Fs;
    Fs.open(Path.c_str(), std::ios::in | std::ios::binary);
    if (Fs.is_open())
    {
        Fs.seekg(p->imgOffset);
        std::string Flag = Fs.ReadString(); // 读取Flag
        if (Flag.find("Neople Img File") != std::string::npos)
        {
            // 索引表大小
            long TableLength = Fs.ReadLong();
            // img 版本 4字节
            Fs.ReadInt(); // 读取版本
            // img 帧数
            int IndexCount = Fs.ReadInt();
            // 图片数量赋值
            p->png_sum = IndexCount;

            // new出 Png数量的 结构体
            ImgInfo *PngList = new ImgInfo[IndexCount];

            for (int i = 0; i < IndexCount; i++)
            {
                PngList[i].Type = Fs.ReadInt();
                if (PngList[i].Type == 17)
                {
                    // 引用贴图
                    int frbuf = Fs.ReadInt();
                    // 压缩类型 用来临时存一下引用编号
                    PngList[i].CmpType = frbuf;
                    ////大小
                    PngList[i].Size = 0;
                    PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size;
                    continue;
                }
                // 压缩类型
                PngList[i].CmpType = Fs.ReadInt();
                // 宽度
                PngList[i].Width = Fs.ReadInt();
                // 高度
                PngList[i].Height = Fs.ReadInt();
                // 大小
                PngList[i].Size = Fs.ReadInt();
                // Xpos
                PngList[i].Xpos = Fs.ReadInt();
                // Ypos
                PngList[i].Ypos = Fs.ReadInt();
                // 帧域X
                PngList[i].FrameXpos = Fs.ReadInt();
                // 帧域Y
                PngList[i].FrameYpos = Fs.ReadInt();
                // 计算偏移
                if (i == 0)
                    PngList[i].Offset = 0 + p->imgOffset + TableLength + 32;
                else
                    PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size;
            }

            for (int i = 0; i < IndexCount; i++)
            {
                // 引用
                if (PngList[i].Type == 17)
                {
                    // 引用编号
                    int YYIndex = PngList[i].CmpType;
                    int sizebuf = PngList[YYIndex].Width * PngList[YYIndex].Height * 4;
                    BYTE *bByte = new BYTE[sizebuf];
                    memcpy(bByte, PngList[PngList[i].CmpType].PNGdata, sizebuf);
                    PngList[i].PNGdata = PngList[YYIndex].PNGdata;

                    // 压缩类型 用来临时存一下引用编号
                    PngList[i].CmpType = PngList[YYIndex].CmpType;
                    // 宽度
                    PngList[i].Width = PngList[YYIndex].Width;
                    // 高度
                    PngList[i].Height = PngList[YYIndex].Height;
                    // 大小
                    PngList[i].Size = 0;
                    // Xpos
                    PngList[i].Xpos = PngList[YYIndex].Xpos;
                    // Ypos
                    PngList[i].Ypos = PngList[YYIndex].Ypos;
                    // 帧域X
                    PngList[i].FrameXpos = PngList[YYIndex].FrameXpos;
                    // 帧域Y
                    PngList[i].FrameYpos = PngList[YYIndex].FrameYpos;
                    continue;
                }

                Fs.seekg(PngList[i].Offset);
                BYTE *PngData = Fs.ReadCustomSize(PngList[i].Size);
                int DeSize = PngList[i].Width * PngList[i].Height * 4;
                BYTE *bByte = new BYTE[DeSize];
                unsigned long RealSize = DeSize;
                uncompress(bByte, &RealSize, PngData, (unsigned long)PngList[i].Size);
                delete[] PngData;

                if (PngList[i].Type != 16)
                {
                    int PngByteSize = DeSize * 2;
                    PngList[i].PNGdata = new BYTE[PngByteSize];

                    for (int e = 0; e < PngByteSize; e += 4)
                    {
                        BYTE NeedData[2];
                        memset(NeedData, 0, 2);
                        memcpy(NeedData, bByte + (e / 4) * 2, 2);
                        ParseColor(NeedData, PngList[i].Type, PngList[i].PNGdata, e);
                    }
                    delete[] bByte;
                }
                else
                {
                    PngList[i].PNGdata = bByte;
                }
            }

            p->lp_lplist = PngList;
        }
        else if (Flag.find("Neople Image File") != std::string::npos)
        {
            // LoadImgToMem2(p);
        }
        Fs.close();
    }
}

Asset_ImagePack::IMG *Asset_ImagePack::GetIMG(std::string imgName)
{
    IMG *img = NULL;
    std::map<std::string, IMG>::iterator itr;
    itr = map_npk.find(imgName);
    if (itr == map_npk.end())
    {
        std::string mes = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!调用了不存在的Img : " + imgName;
        SDL_Log(mes.c_str());
        img = &map_npk["sprite/interface/base.img"];
    }
    else
    {
        img = &itr->second;
    }
    // 如果图片数组不存在 或者 图片数据不存在都要重读
    if (!img->lp_lplist)
    {
        LoadImgToMem(img);
    }
    img->UseTime = SDL_GetTicks();
    return img;
}
