#pragma once
//纹理Map
extern std::unordered_map<std::string, std::map<int,TexturePtr>>ImageRecObject;
std::mutex ImageRecObjectmutex;

extern NPK_M* npk;

extern WThreadPool threadPool;

void ThreadPreloadImg_Success(std::string Name , SQInteger Scene)
{
    //调用回调
    sq_pushroottable(v);
    sq_pushstring(v, _SST(Name.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, Scene);
    sq_call(v, 2, 0, 1);
    sq_pop(v, 2);
}

void ThreadPreloadImgFunc(std::vector<std::string> ImgList, std::string Name , SQInteger Scene) {
    //先遍历一次 把需要加载的img存下来
    std::vector<std::string> RealImgList;
    ImageRecObjectmutex.lock();
    for (auto it = ImgList.begin(); it != ImgList.end(); ++it) {
        std::string Iname = *it;
        if (!ImageRecObject.count(Iname)) {
            RealImgList.push_back(*it);
        }
    }
    ImageRecObjectmutex.unlock();

    //开始加载img 并存入临时map
    std::map<std::string ,std::map<int,TexturePtr>> TexturePtrVL;
    for (auto it = RealImgList.begin(); it != RealImgList.end(); ++it) {
        std::string imgpath = *it;
        IMG* img = npk->ReadNpkTable(imgpath);

        for (int i = 0; i < img->png_sum; i++)
        {
            std::string RealTextureName = imgpath;
            
            DWORD Height = img->lp_lplist[i].Height;
            DWORD Width = img->lp_lplist[i].Width;
            BYTE* Data = img->lp_lplist[i].PNGdata;

            BinaryData data = { ((void*)Data) ,Height * Width * 4 };
            TexturePtr t = new Texture;
            t->Load(PixelSize(Width, Height), data, PixelFormat::Bpp32BGRA);
            t->SetUserData(&img->lp_lplist[i]);

            TexturePtrVL[RealTextureName][i] = t;
        }
        npk->ReleaseNpkTable(img);
    }

    //拿锁 赋值map
    ImageRecObjectmutex.lock();
    for (auto it = TexturePtrVL.begin(); it != TexturePtrVL.end(); it++) {
        if (!ImageRecObject.count(it->first)) {
            ImageRecObject[it->first] = it->second;
        }
    }
    ImageRecObjectmutex.unlock();


    auto f1 = std::bind(&ThreadPreloadImg_Success,  Name , Scene);
    Application::GetInstance().PerformInMainThread(f1);
}


//线程加载Img资源
static SQInteger ThreadPreloadImg(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    std::vector<std::string> ImgList;
    sq_pushnull(v);  // null iterator
    while (SQ_SUCCEEDED(sq_next(v, 2)))
    {
        const SQChar* path;
        sq_getstring(v, -1, &path);
        ImgList.push_back((char*)path);
        //这里-1是值，-2是键
        sq_pop(v, 2); //在下一次迭代之前弹出键和值
    }
    sq_pop(v, 1);

    const SQChar* Name;
    sq_getstring(v, 3,&Name);

    SQInteger SceneId;
    sq_getinteger(v, 4, &SceneId);

    auto f1 = std::bind(&ThreadPreloadImgFunc, ImgList, (char*)Name, SceneId);

    threadPool.concurrentRun(f1);

    return 1;
}