#include <Windows.h>
#include "SquirrelClassEx.h"

//演员对象智能指针Map
static std::map<uint64_t, ActorPtr>ActorPtrMapObject;
//音频对象智能指针Map
static std::map<size_t, SoundPtr>SoundActorPtrMapObject;
extern std::unordered_map<std::string, std::map<int, TexturePtr>>ImageRecObject;

//时装List Map
std::map<SQInteger, std::string>GameAvatarList;
//装备List Map
std::map<SQInteger, std::string>GameEquipmentList;
//地图List Map
std::map<SQInteger, std::string>GameMapList;
//怪物List Map
std::map<SQInteger, std::string>GameMonsterList;
//被动对象List Map
std::map<SQInteger, std::string>GamePassobjectList;
//音频 Map
std::map<std::string, std::string>GameAudioList;

//文字类注册函数
#include "TextActorRegister.h"
//精灵类注册函数
#include "SpriteActorRegister.h"
//音频类注册函数
#include "SoundActorRegister.h"
//场景类注册函数
#include "StageActorRegister.h"
//画布类注册函数
#include "CanvasActorRegister.h"
//按钮类注册函数
#include "ButtonActorRegister.h"
//IMGUI类注册函数
#include "ImguiLayerActorRegister.h"
//线程类注册函数
#include "ThreadRegister.h"


wchar_t* char2wchar(const char* cchar)
{
    wchar_t* m_wchar;
    int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0);
    m_wchar = new wchar_t[len + 1];
    MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len);
    m_wchar[len] = '\0';
    return m_wchar;
}

wchar_t* SquirrelW2W(const wchar_t* Str)
{
    size_t len = 0;
    char* wbuffer = (char*)(Str);
    while (true)
    {
        if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break;
        ++len;
    }
    char* cbuffer = new char[len / 2 + 1];
    int k = 0;
    for (size_t i = 0; i < len; i++)
    {
        if (i % 2 == 0)
        {
            cbuffer[k] = wbuffer[i];
            ++k;
        }
    }
    cbuffer[len / 2] = '\0';
    wchar_t* str = char2wchar(cbuffer);
    delete[]cbuffer;
    return str;
}

//原生输出函数
void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* s, ...)
{
    va_list vl;
    va_start(vl, s);
    vfprintf(stdout, (char*)s, vl);
    va_end(vl);
    std::cout << std::endl;
}

void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* s, ...)
{
    va_list vl;
    va_start(vl, s);
    vfprintf(stderr, (char*)s, vl);
    va_end(vl);
}




//构造函数
SquirrelClassEx::SquirrelClassEx()
{
    
}

void SquirrelClassEx::LoadingListScript()
{
    //读取时装List
    std::ifstream AvatarStream("Script/Avatar/Avatar.ylst");
    nlohmann::json AvatarList = nlohmann::json::parse(AvatarStream);
    AvatarStream.close();
    for (nlohmann::json::iterator it = AvatarList.begin(); it != AvatarList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GameAvatarList[std::atoi(it.key().c_str())] = Path;
    }

    //读取装备List
    std::ifstream EquipmentStream("Script/Equipment/Equipment.ylst");
    nlohmann::json EquipmentList = nlohmann::json::parse(EquipmentStream);
    EquipmentStream.close();
    for (nlohmann::json::iterator it = EquipmentList.begin(); it != EquipmentList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GameEquipmentList[std::atoi(it.key().c_str())] = Path;
    }

    //读取地图List
    std::ifstream MapStream("Script/Map/Map.ylst");
    nlohmann::json MapList = nlohmann::json::parse(MapStream);
    MapStream.close();
    for (nlohmann::json::iterator it = MapList.begin(); it != MapList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GameMapList[std::atoi(it.key().c_str())] = Path;
    }

    //读取怪物List
    std::ifstream MonsterStream("Script/Monster/Monster.ylst");
    nlohmann::json MonsterList = nlohmann::json::parse(MonsterStream);
    MonsterStream.close();
    for (nlohmann::json::iterator it = MonsterList.begin(); it != MonsterList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GameMonsterList[std::atoi(it.key().c_str())] = Path;
    }

    //读取被动对象List
    std::ifstream PassobjectStream("Script/PassObject/PassObject.ylst");
    nlohmann::json PassobjectList = nlohmann::json::parse(PassobjectStream);
    PassobjectStream.close();
    for (nlohmann::json::iterator it = PassobjectList.begin(); it != PassobjectList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GamePassobjectList[std::atoi(it.key().c_str())] = Path;
    }

    //读取音频List
    std::ifstream AudioStream("Script/Audio/Audio.ylst");
    nlohmann::json AudioList = nlohmann::json::parse(AudioStream);
    AudioStream.close();
    for (nlohmann::json::iterator it = AudioList.begin(); it != AudioList.end(); ++it) {
        std::string Path = it.value().dump();
        Path = Path.substr(1, Path.size() - 2);
        GameAudioList[it.key().c_str()] = Path;
    }
}

//初始化
void SquirrelClassEx::Init()
{
    //初始化NPK表
    npk = new NPK_M();
    npk->init();

    v = sq_open(4096); //创建虚拟机，其栈的初始大小为1024
    sq_setprintfunc(v, printfunc, errorfunc);

    sq_pushroottable(v);

    sqstd_register_bloblib(v);
    sqstd_register_iolib(v);
    sqstd_register_systemlib(v);
    sqstd_register_mathlib(v);
    sqstd_register_stringlib(v);
    sqstd_seterrorhandlers(v);

    R_Register_Nut(v);
    
    //输出版本信息
    scfprintf(stdout, _SC("%s %s (%d bits)\n"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8);

    sqstd_dofile(v, _SST("Sqr/BaseTool/BaseTool.nut"), false, true);

    //第一次加载脚本
    ReloadingScript();

    sqstd_dofile(v, _SST("Sqr/Run.nut"), false, true);
}

int SquirrelClassEx::Sout(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    const SQChar* OutPutBuffer;
    sq_getstring(v, 2, &OutPutBuffer);

    char* OutPutText = SquirrelU2W((char*)OutPutBuffer);

    std::vector<std::string> Data;
    Split(OutPutText, Data, "%L");
    delete[]OutPutText;

    if (Top != Data.size() + 1)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    size_t Fnum = Data.size();
    if (Fnum > 1)Fnum -= 1;
    std::string Text = "";
    for (size_t i = 0; i < Fnum; i++)
    {
        std::string Parameter;
        //获取值的类型
        int ValueType = sq_gettype(v, 3 + i);
        //判断值类型
        switch (ValueType)
        {
        case OT_INTEGER://int类型
        {
            SQInteger Value;
            sq_getinteger(v, 3 + i, &Value);
            Parameter = std::to_string(Value);
            break;
        }
        case OT_FLOAT://float类型
        {
            FLOAT Value;
            sq_getfloat(v, 3 + i, &Value);
            std::ostringstream oss;
            oss << Value;
            std::string str(oss.str());
            Parameter = str;
            break;
        }
        case OT_BOOL://bool类型
        {
            SQBool Value;
            sq_getbool(v, 3 + i, &Value);
            switch (Value)
            {
            case true:
                Parameter = "true";
                break;
            case false:
                Parameter = "false";
                break;
            }
            //Parameter = std::to_string(Value);
            break;
        }
        case OT_STRING://string类型
        {
            const SQChar* Value;
            sq_getstring(v, 3 + i, &Value);
            char* str = SquirrelU2W((char*)Value);
            Parameter = str;
            delete[]str;
            break;
        }
        default:
            Parameter = " ";
            break;
        }
        Text += Data[i];
        Text += Parameter;
    }
    std::cout << Text << std::endl;
    return 0;
}

int SquirrelClassEx::Error(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    const SQChar* OutPutBuffer;
    sq_getstring(v, 2, &OutPutBuffer);

    char* OutPutText = SquirrelU2W((char*)OutPutBuffer);

    std::vector<std::string> Data;
    Split(OutPutText, Data, "%L");
    delete[]OutPutText;

    if (Top != Data.size() + 1)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    size_t Fnum = Data.size();
    if (Fnum > 1)Fnum -= 1;
    std::string Text = "";
    for (size_t i = 0; i < Fnum; i++)
    {
        std::string Parameter;
        //获取值的类型
        int ValueType = sq_gettype(v, 3 + i);
        //判断值类型
        switch (ValueType)
        {
        case OT_INTEGER://int类型
        {
            SQInteger Value;
            sq_getinteger(v, 3 + i, &Value);
            Parameter = std::to_string(Value);
            break;
        }
        case OT_FLOAT://float类型
        {
            FLOAT Value;
            sq_getfloat(v, 3 + i, &Value);
            std::ostringstream oss;
            oss << Value;
            std::string str(oss.str());
            Parameter = str;
            break;
        }
        case OT_BOOL://bool类型
        {
            SQBool Value;
            sq_getbool(v, 3 + i, &Value);
            switch (Value)
            {
            case true:
                Parameter = "true";
                break;
            case false:
                Parameter = "false";
                break;
            }
            //Parameter = std::to_string(Value);
            break;
        }
        case OT_STRING://string类型
        {
            const SQChar* Value;
            sq_getstring(v, 3 + i, &Value);
            char* str = SquirrelU2W((char*)Value);
            Parameter = str;
            delete[]str;
            break;
        }
        default:
            Parameter = " ";
            break;
        }
        Text += Data[i];
        Text += Parameter;
    }
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //获取缓冲区句柄
    SetConsoleTextAttribute(hCon, FOREGROUND_RED); //设置文本及背景色
    std::cout << "[Squirrel Error]  :  " << Text << std::endl;
    return 0;
}

char* SquirrelClassEx::U8ToUnicode(const char* szU8)
{
    //UTF8 to Unicode
    //预转换，得到所需空间的大小
    int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
    //分配空间要给'\0'留个空间，MultiByteToWideChar不会给'\0'空间
    wchar_t* wszString = new wchar_t[wcsLen + 1];
    //转换
    ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
    //最后加上'\0'
    wszString[wcsLen] = '\0';

    char* m_char;
    int len = WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
    m_char = new char[len + 1];
    WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), m_char, len, NULL, NULL);
    delete[]wszString;
    m_char[len] = '\0';
    return m_char;
}

char* SquirrelClassEx::SquirrelU2W(const char* Str)
{
    size_t len = 0;
    char* wbuffer = (char*)(Str);
    while (true)
    {
        if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break;
        ++len;
    }
    char* cbuffer = new char[len + 1];

    for (size_t i = 0; i < len; i++)
    {
         cbuffer[i] = wbuffer[i];
         //std::cout << std::hex << (int)cbuffer[i] << std::endl;
    }
    cbuffer[len] = '\0';
    char* Text = U8ToUnicode(cbuffer);
    //std::cout << Text << std::endl;
    delete[]cbuffer;
    return Text;
}

void SquirrelClassEx::Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
{
    std::string str = src;
    std::string substring;
    std::string::size_type start = 0, index;
    dest.clear();
    index = str.find_first_of(separator, start);
    do
    {
        if (index != std::string::npos)
        {
            substring = str.substr(start, index - start);
            dest.push_back(substring);
            start = index + separator.size();
            index = str.find(separator, start);
            if (start == std::string::npos) break;
        }
    } while (index != std::string::npos);

    //the last part
    substring = str.substr(start);
    dest.push_back(substring);
}

void SquirrelClassEx::RegisterNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
{
    sq_pushroottable(v);
    sq_pushstring(v, funcName, -1);
    sq_newclosure(v, (SQFUNCTION)funcAddr, 0);
    sq_newslot(v, -3, false);
    sq_poptop(v);
}

TexturePtr SquirrelClassEx::GetTexturePtrByImg(const std::string ImgPath, const int Frame) {

    if (ImageRecObject.count(ImgPath) && ImageRecObject[ImgPath].count(Frame)) {
        return ImageRecObject[ImgPath][Frame];
    }
    else {
        IMG* img = npk->ReadNpkTable(ImgPath);
        DWORD Height = img->lp_lplist[Frame].Height;
        DWORD Width = img->lp_lplist[Frame].Width;
        BYTE* Data = img->lp_lplist[Frame].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[Frame]);
        ImageRecObject[ImgPath][Frame] = t;
        return t;
    }
}

void SquirrelClassEx::ReleaseTextureByImg(const std::string ImgPath)
{
    IMG* img = npk->ReadNpkTable(ImgPath);
    for (size_t i = 0; i < img->png_sum; i++)
    {
        std::string RealTextureName = ImgPath;
        ImageRecObject.erase(RealTextureName);
    }
}

std::map<std::string, std::string> FileFirst;
std::map<std::string, std::string> FileLast;
void ReloadingSquirrelScript(const TCHAR* directory)
{
    WIN32_FIND_DATA fileInfo;
    TCHAR buffer[MAX_PATH];

    // 构建搜索路径
    _tcscpy_s(buffer, directory);
    _tcscat_s(buffer, _T("\\*.*"));


    // 查找第一个文件/目录
    HANDLE hFind = FindFirstFile(buffer, &fileInfo);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        do
        {
            // 排除 "." 和 ".."
            if (_tcscmp(fileInfo.cFileName, _T(".")) != 0 && _tcscmp(fileInfo.cFileName, _T("..")) != 0)
            {
                // 如果是目录，则递归遍历子目录
                if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    _tcscpy_s(buffer, directory);
                    _tcscat_s(buffer, _T("\\"));
                    _tcscat_s(buffer, fileInfo.cFileName);
                    ReloadingSquirrelScript(buffer);
                }
                else {

                    char output[1024];
                    sprintf(output, "%ws\\%ws", directory, fileInfo.cFileName);
                    std::string path = output;
                    if (path.find(".nut") != std::string::npos && path.find("Run.nut") == std::string::npos) {
                        std::replace(path.begin(), path.end(), '\\', '/');

                        std::fstream F;
                        F.open(path,std::ios::in);
                        std::stringstream ContentStringStream;
                        ContentStringStream << F.rdbuf();
                        /*while (!F.eof())
                        {
                            F >> ContentString;
                        }*/
                        std::string ContentString(ContentStringStream.str());
                        F.close();

                        if (ContentString.find("extends") != std::string::npos) {
                            FileLast[path] = ContentString;
                        }
                        else {
                            FileFirst[path] = ContentString;
                        }
                        
                        //sqstd_dofile(v, _SST(path.c_str()), false, true);
                    }
                }
            }
        } while (FindNextFile(hFind, &fileInfo));

        FindClose(hFind);
    }


    /*
                            sq_pushroottable(v);
                        sq_pushstring(v, _SST("PushReloadingNameToRootTab"), -1);
                        sq_get(v, -2);
                        sq_pushroottable(v);
                        sq_pushstring(v, _SST(path.c_str()), -1);
                        sq_call(v, 2, 0, 1);
                        sq_pop(v, 2);
                        */
}
SQInteger SquirrelClassEx::ReloadingScript()
{
    ReloadingSquirrelScript(L"Sqr");

    std::map<std::string, std::string>FailMap;

    for (auto it = FileFirst.begin(); it != FileFirst.end(); it++) {
        std::string Sourcename = it->first;
        std::string ContentString = it->second;

        if (SQ_SUCCEEDED(sq_compilebuffer(v, _SST(ContentString.c_str()), ContentString.length(), _SST(Sourcename.c_str()), true))) {
            sq_pushroottable(v);
            sq_call(v, 1, 1, 1);
            sq_pop(v, 1);
        };
    }

    for (auto it = FileLast.begin(); it != FileLast.end(); it++) {
        std::string Sourcename = it->first;
        std::string ContentString = it->second;

        if (SQ_SUCCEEDED(sq_compilebuffer(v, _SST(ContentString.c_str()), ContentString.length(), _SST(Sourcename.c_str()), true))) {
            sq_pushroottable(v);
            if (SQ_FAILED(sq_call(v, 1, 1, 0))) {
                FailMap[Sourcename] = ContentString;
            };
            sq_pop(v, 1);
        };
    }

    while (FailMap.size() > 0)
    {
        std::map<std::string, std::string>FailMapBuffer;
        for (auto it = FailMap.begin(); it != FailMap.end(); it++) {
            std::string Sourcename = it->first;
            std::string ContentString = it->second;

            if (SQ_SUCCEEDED(sq_compilebuffer(v, _SST(ContentString.c_str()), ContentString.length(), _SST(Sourcename.c_str()), true))) {
                sq_pushroottable(v);
                if (SQ_FAILED(sq_call(v, 1, 1, 1))) {
                    FailMapBuffer[Sourcename] = ContentString;
                };
                sq_pop(v, 1);
            };
        }

        FailMap.clear();
        if (FailMapBuffer.size() > 0) {
            for (auto it = FailMapBuffer.begin(); it != FailMapBuffer.end(); it++) {
                std::string Sourcename = it->first;
                std::string ContentString = it->second;
                FailMap[Sourcename] = ContentString;
            }
        }
    }
    return 0;
}
SQInteger SquirrelClassEx::Exit(HSQUIRRELVM v)
{
    Application::GetInstance().Quit();
    return 0;
}

SQInteger SquirrelClassEx::Cmd(HSQUIRRELVM v)
{
    const SQChar* Command;
    sq_getstring(v, 2, &Command);

    system((char*)Command);

    return 0;
}

//替换字符串
static SQInteger String_Replace(HSQUIRRELVM v)
{
    const SQChar* F_String;
    sq_getstring(v, 2, &F_String);

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

    const SQChar* R_String;
    sq_getstring(v, 4, &R_String);

    std::string Fstring = (char*)F_String;
    std::string Bstring = (char*)B_String;
    std::string Rstring = (char*)R_String;

    Fstring.replace(Fstring.find(Bstring), Bstring.length(), Rstring);

    sq_pushstring(v, _SST(Fstring.c_str()), -1);

    return 1;
}


//Nut闭包释放纹理资源
static SQInteger ReleaseTextureByImg_n(HSQUIRRELVM v)
{
    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);

    for (auto it = ImgList.begin(); it != ImgList.end(); ++it) {
        std::string Iname = *it;
        ImageRecObject.erase(Iname);
        //SquirrelClassEx::ReleaseTextureByImg(Iname);
    }

    return 0;
}

//读取时装路径By时装ID
static SQInteger GetAvatarPathByIndex()
{
    SQInteger Index;
    sq_getinteger(v, 2, &Index);

    if (GameAvatarList.count(Index)) {
        sq_pushstring(v, _SST(GameAvatarList[Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }
   
    return 1;
}


//读取装备路径By装备ID
static SQInteger GetEquipmentPathByIndex()
{
    SQInteger Index;
    sq_getinteger(v, 2, &Index);

    if (GameEquipmentList.count(Index)) {
        sq_pushstring(v, _SST(GameEquipmentList[Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }

    return 1;
}

//读取地图路径By地图ID
static SQInteger GetMapPathByIndex()
{
    SQInteger Index;
    sq_getinteger(v, 2, &Index);

    if (GameMapList.count(Index)) {
        sq_pushstring(v, _SST(GameMapList[Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }

    return 1;
}


//读取怪物路径By怪物ID
static SQInteger GetMonsterPathByIndex()
{
    SQInteger Index;
    sq_getinteger(v, 2, &Index);

    if (GameMonsterList.count(Index)) {
        sq_pushstring(v, _SST(GameMonsterList[Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }

    return 1;
}

//读取被动对象路径By被动对象ID
static SQInteger GetPassobjectPathByIndex()
{
    SQInteger Index;
    sq_getinteger(v, 2, &Index);

    if (GamePassobjectList.count(Index)) {
        sq_pushstring(v, _SST(GamePassobjectList[Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }

    return 1;
}



//读取音频路径By音频ID
static SQInteger GetAudioPathByIndex()
{
    const SQChar* Index;
    sq_getstring(v, 2, &Index);

    if (GameAudioList.count((char*)Index)) {
        sq_pushstring(v, _SST(GameAudioList[(char*)Index].c_str()), -1);
    }
    else {
        sq_pushnull(v);
    }

    return 1;
}

//寻找字符串子串最后位置
static SQInteger String_Find_Last()
{
    const SQChar* F_String;
    sq_getstring(v, 2, &F_String);

    const SQChar* R_String;
    sq_getstring(v, 4, &R_String);

    std::string Fstring = (char*)F_String;
    std::string Rstring = (char*)R_String;

    SQInteger Index = Fstring.find_last_of(Rstring);

    sq_pushinteger(v, Index);
    return 1;
}
void SquirrelClassEx::RunSceneScript(std::string FuncName, SquirrelStagePtr scene)
{
    //std::cout << "栈空间大小: " << sq_gettop(v) << std::endl;
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, scene->GetObjectID());
    sq_call(v, 2, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunSceneScript(std::string FuncName, SquirrelStagePtr scene,SQInteger dt)
{
    //std::cout << "栈空间大小: " << sq_gettop(v) << std::endl;
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, scene->GetObjectID());
    sq_pushinteger(v, dt);
    sq_call(v, 3, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunSceneScript(std::string FuncName, SquirrelStagePtr scene, SQFloat dt)
{
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, scene->GetObjectID());
    sq_pushfloat(v, dt);
    sq_call(v, 3, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunSceneScript(std::string FuncName, SquirrelTownStagePtr scene)
{
    //std::cout << "栈空间大小: " << sq_gettop(v) << std::endl;
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, scene->GetObjectID());
    sq_call(v, 2, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunUpdateScript(std::string FuncName, SQInteger ObjectIdx)
{
    //std::cout << "栈空间大小: " << sq_gettop(v) << std::endl;
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, ObjectIdx);
    sq_call(v, 2, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunUpdateScript(std::string FuncName, std::string string)
{
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushstring(v, _SST(string.c_str()),-1);
    sq_call(v, 2, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunUpdateScript(std::string FuncName, SQInteger ObjectIdx,SQInteger Buf)
{
    //std::cout << "栈空间大小: " << sq_gettop(v) << std::endl;
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, ObjectIdx);
    sq_pushinteger(v, Buf);
    sq_call(v, 3, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunUpdateScript(std::string FuncName, SQInteger ObjectIdx, SQInteger Buf, SQInteger Buf2)
{
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, ObjectIdx);
    sq_pushinteger(v, Buf);
    sq_pushinteger(v, Buf2);
    sq_call(v, 3, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::RunUpdateScriptPlayer(std::string FuncName, SQInteger ObjectIdx, SQFloat Buf)
{
    sq_pushroottable(v);
    sq_pushstring(v, _SST(FuncName.c_str()), -1);
    sq_get(v, -2);
    sq_pushroottable(v);
    sq_pushinteger(v, ObjectIdx);
    sq_pushfloat(v, Buf);
    sq_call(v, 3, 0, 1);
    sq_pop(v, 2);
}

void SquirrelClassEx::PushLayerActorPtrToMap(LayerActorPtr Ptr) {
    ActorPtrMapObject[Ptr->GetObjectID()] = Ptr;
}

static SQInteger RGBA(HSQUIRRELVM v)
{
    SQInteger R;
    sq_getinteger(v, 2, &R);

    SQInteger G;
    sq_getinteger(v, 3, &G);

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

    SQInteger A;
    sq_getinteger(v, 5, &A);

    SQInteger _Color = ((R & 0xff) << 24) + ((G & 0xff) << 16) + ((B & 0xff) << 8)
        + (A & 0xff);

    sq_pushinteger(v, _Color);
    return 1;
}






//获取对象
static ActorPtr GetActorObjectByMap(const size_t Hash_Name) {
    //基础对象智能指针Map
    if (ActorPtrMapObject.count(Hash_Name))return ActorPtrMapObject[Hash_Name];
    return nullptr;
}

//销毁对象
static SQInteger ReleaseActor(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    //基础对象智能指针Map
    if (ActorPtrMapObject.count(ActorUUID)) {
        ActorPtrMapObject.erase(ActorUUID);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}


//析构函数数据包
struct SquirrelClassObjectAbli
{
    int Id;
};
static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{
    SquirrelClassObjectAbli* Abli = (SquirrelClassObjectAbli*)p;
    std::cout << "C++对象: " << Abli->Id << std::endl;
    std::cout << "对象已被释放" << std::endl;
    delete Abli;
    return 0;
}
//注册析构函数
static SQInteger Register_Destruction(HSQUIRRELVM v)
{
    //析构函数测试    
    SQInteger Idx;
    sq_getinteger(v, 2, &Idx);

    SquirrelClassObjectAbli* Abli = new SquirrelClassObjectAbli();
    Abli->Id = Idx;

    sq_setinstanceup(v, 3, Abli);
    sq_setreleasehook(v, 3, _file_releasehook);
    return 0;
}


int TestCallC(HSQUIRRELVM v)
{



    //sq_newarray(v, 0);

    //const wchar_t* str = _SST("测试中文");

    //for (size_t i = 0; i < 5; i++)
    //{
    //    sq_pushstring(v, str, -1);
    //    sq_arrayappend(v, -2);
    //}
    /*
    sq_pushnull(v);  // null iterator
    while (SQ_SUCCEEDED(sq_next(v, 2)))
    {
        const SQChar* path;
        sq_getstring(v, -1, &path);
        std::cout << (char*)path << std::endl;
        //这里-1是值，-2是键
        sq_pop(v, 2); //在下一次迭代之前弹出键和值
    }
    sq_pop(v, 1);
    
    sq_pushnull(v);  // null iterator
    while (SQ_SUCCEEDED(sq_next(v, 3)))
    {
        SQInteger idx;
        sq_getinteger(v, -1, &idx);
        std::cout << idx << std::endl;
        //这里-1是值，-2是键
        sq_pop(v, 2); //在下一次迭代之前弹出键和值
    }
    sq_pop(v, 1);
    */


    //Application::GetInstance().Quit();
    return 0;
}

//创建基础对象
static SQInteger Create_BaseAct(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    // 创建一个基础角色
    ActorPtr Act = new Actor();

    //获取对象的UUID
    uint64_t UUID = Act->GetObjectID();
    
    //将对象存入Map管理
    ActorPtrMapObject[UUID] = Act;

    sq_pushinteger(v, UUID);

    return 1;
}

//创建摄像机对象
static SQInteger Create_CameraObjectAct(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    // 创建一个摄像机角色
    SquirrelCameraPtr Act = new SquirrelCamera();

    //获取对象的UUID
    uint64_t UUID = Act->GetObjectID();

    //将对象存入Map管理
    ActorPtrMapObject[UUID] = Act;

    sq_pushinteger(v, UUID);

    return 1;
}

//设置RotateAnimotion  旋转动画
static SQInteger Set_RotateAnimotion(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    SQInteger Duration;
    sq_getinteger(v, 3, &Duration);
    SQFloat Rotation;
    sq_getfloat(v, 4, &Rotation);

    //通过时间和角度设置动画
    auto rotate_by = animation::RotateBy(Duration, Rotation);
    //设置无限循环
    rotate_by.Loops(-1);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->StartAnimation(rotate_by);
        sq_pushbool(v,true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 设置锚点
static SQInteger SetActorAnchor(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQFloat X_Anchor;
    sq_getfloat(v, 3, &X_Anchor);
    SQFloat Y_Anchor;
    sq_getfloat(v, 4, &Y_Anchor);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetAnchor(X_Anchor, Y_Anchor);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;

}

//Actor 设置X坐标
static SQInteger SetActorXPos(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQFloat Xpos;
    sq_getfloat(v, 3, &Xpos);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetPositionX(Xpos);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;

}

//Actor 设置Y坐标
static SQInteger SetActorYPos(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQFloat Ypos;
    sq_getfloat(v, 3, &Ypos);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetPositionY(Ypos);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 设置角色渲染边框
static SQInteger SetActorShowBorder(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQBool Type;
    sq_getbool(v, 3, &Type);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->ShowBorder(Type);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 获取X坐标
static SQInteger GetActorXPos(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        sq_pushfloat(v, Act->GetPositionX());
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 获取Y坐标
static SQInteger GetActorYPos(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        sq_pushfloat(v, Act->GetPositionY());
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 设置坐标
static SQInteger SetActorPosition(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQFloat Xpos;
    sq_getfloat(v, 3, &Xpos);
    SQFloat Ypos;
    sq_getfloat(v, 4, &Ypos);


    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetPosition(Xpos, Ypos);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 设置缩放比例
static SQInteger SetActorScale(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQFloat Xrate;
    sq_getfloat(v, 3, &Xrate);
    SQFloat Yrate;
    sq_getfloat(v, 4, &Yrate);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetScale(Xrate, Yrate);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 设置Z轴层级
static SQInteger SetActorSetZOrder(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQInteger Z;
    sq_getinteger(v, 3, &Z);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetZOrder(Z);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 获取Z轴层级
static SQInteger GetActorSetZOrder(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);
    SQInteger Z;
    sq_getinteger(v, 3, &Z);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->GetZOrder();
        sq_pushinteger(v, Act->GetZOrder());
    }
    else {
        sq_pushbool(v, false);
    }
    return 1;
}

//Actor 获取宽度
static SQInteger GetActorWidth(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        SQFloat WidthValue = Act->GetWidth();

        sq_pushfloat(v, WidthValue);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 获取高度
static SQInteger GetActorHeight(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        SQFloat HeightValue = Act->GetHeight();
        sq_pushfloat(v, HeightValue);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 获取名称 获取名字
static SQInteger GetActorName(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        std::string ActName = Act->GetName();
        sq_pushstring(v, (SQChar*)ActName.c_str(), -1);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 设置名称 设置名字
static SQInteger SetActorName(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

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

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetName((char*)OutPutBuffer);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 设置透明度
static SQInteger SetActorOpacity(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger ActorUUID;
    sq_getinteger(v, 2, &ActorUUID);

    SQFloat Opacity;
    sq_getfloat(v, 3, &Opacity);

    ActorPtr Act = GetActorObjectByMap(ActorUUID);
    if (Act) {
        Act->SetOpacity(Opacity);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 设置子对象
static SQInteger SetActorChild(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger gFActor;
    sq_getinteger(v, 2, &gFActor);

    SQInteger gCActor;
    sq_getinteger(v, 3, &gCActor);

    ActorPtr FActor = GetActorObjectByMap(gFActor);
    ActorPtr CActor = GetActorObjectByMap(gCActor);

    if (FActor && CActor) {
        FActor->AddChild(CActor);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 获取子对象ByName
static SQInteger GetChildByName(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger gFActor;
    sq_getinteger(v, 2, &gFActor);
    ActorPtr FActor = GetActorObjectByMap(gFActor);

    const SQChar* OutPutBuffer;
    sq_getstring(v, 3, &OutPutBuffer);
    //此操作会New出一个字符串需要手动销毁
    char* OutPutText = SquirrelClassEx::SquirrelU2W((char*)OutPutBuffer);

    std::string Name = (char*)OutPutText;

    //销毁New出来的字符串
    delete[]OutPutText;

    if (FActor) {
        ActorPtr CAct = FActor->GetChild(Name);
        if (CAct) {
            sq_pushinteger(v, CAct->GetObjectID());
        }
        else sq_pushnull(v);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 移除子对象
static SQInteger RemoveActorChild(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger gFActor;
    sq_getinteger(v, 2, &gFActor);

    SQInteger gCActor;
    sq_getinteger(v, 3, &gCActor);

    ActorPtr FActor = GetActorObjectByMap(gFActor);
    ActorPtr CActor = GetActorObjectByMap(gCActor);

    if (FActor && CActor) {
        FActor->RemoveChild(CActor);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}
//Actor 设置大小
static SQInteger SetSize(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger gActor;
    sq_getinteger(v, 2, &gActor);


    SQFloat gXsize;
    sq_getfloat(v, 3, &gXsize);


    SQFloat gYsize;
    sq_getfloat(v, 4, &gYsize);

    ActorPtr Actor = GetActorObjectByMap(gActor);

    if (Actor) {
        Actor->SetSize(gXsize, gYsize);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 设置旋转
static SQInteger SetRotate(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger gActor;
    sq_getinteger(v, 2, &gActor);


    SQFloat gRotation;
    sq_getfloat(v, 3, &gRotation);


    ActorPtr Actor = GetActorObjectByMap(gActor);

    if (Actor) {
        Actor->SetRotation(gRotation);
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//Actor 移除父对象
static SQInteger RemoveActorParent(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger gCActor;
    sq_getinteger(v, 2, &gCActor);

    ActorPtr CActor = GetActorObjectByMap(gCActor);

    if ( CActor) {
        CActor->RemoveFromParent();
        sq_pushbool(v, true);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}


//Actor 获取父对象
static SQInteger GetActorParent(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    SQInteger gCActor;
    sq_getinteger(v, 2, &gCActor);

    ActorPtr CActor = GetActorObjectByMap(gCActor);

    if (CActor) {
        SQInteger F =  CActor->GetParent()->GetObjectID();
        sq_pushinteger(v, F);
    }
    else {
        sq_pushbool(v, false);
    }

    return 1;
}

//判断Key单击
static SQInteger Key_Pressed(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger Type;
    sq_getinteger(v, 2, &Type);

    SQInteger Key;
    sq_getinteger(v, 3, &Key);

    Input& input = Input::GetInstance();

    //判断是 鼠标模式 还是 键盘模式
    bool KeyPressed;
    switch (Type)
    {
    case 0:
        KeyPressed = input.WasPressed((MouseButton)Key);
        break;
    case 1:
        KeyPressed = input.WasPressed((KeyCode)Key);
        break;
    default:
        break;
    }

    sq_pushbool(v, KeyPressed);
    return 1;
}

//判断Key按下
static SQInteger Key_Is_Down(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger Type;
    sq_getinteger(v, 2, &Type);

    SQInteger Key;
    sq_getinteger(v, 3, &Key);

    Input& input = Input::GetInstance();

    //判断是 鼠标模式 还是 键盘模式
    bool KeyPressed;
    switch (Type)
    {
    case 0:
        KeyPressed = input.IsDown((MouseButton)Key);
        break;
    case 1:
        KeyPressed = input.IsDown((KeyCode)Key);
        break;
    default:
        break;
    }

    sq_pushbool(v, KeyPressed);
    return 1;
}

//判断Key刚抬起
static SQInteger Key_WasReleased(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    SQInteger Type;
    sq_getinteger(v, 2, &Type);

    SQInteger Key;
    sq_getinteger(v, 3, &Key);

    Input& input = Input::GetInstance();

    //判断是 鼠标模式 还是 键盘模式
    bool KeyPressed;
    switch (Type)
    {
    case 0:
        KeyPressed = input.WasReleased((MouseButton)Key);
        break;
    case 1:
        KeyPressed = input.WasReleased((KeyCode)Key);
        break;
    default:
        break;
    }

    sq_pushbool(v, KeyPressed);
    return 1;
}

//同步鼠标指针坐标
static SQInteger Sync_CursorPos(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }
    
    //获取"鼠标"对象
    SQUserPointer gCursor;
    sq_getuserpointer(v, 2, &gCursor);
    //转换Actor类
    Actor* Cursor = (Actor*)gCursor;
    //鼠标对象在有父对象的时候才同步坐标
    if (Cursor->GetParent()) {
        //获取输入
        Input& input = Input::GetInstance();
        //设置"鼠标"对象坐标等于鼠标坐标
        Cursor->SetPosition(input.GetMousePos());
    }


    return 0;
}

extern Cursor* Mouse_Object;
//设置鼠标对象工作
static SQInteger SetCursor_Task(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }


    const SQChar* Img;
    sq_getstring(v, 2, &Img);

    SQInteger Frame;
    sq_getinteger(v, 3, &Frame);

    TexturePtr T = SquirrelClassEx::GetTexturePtrByImg((char*)Img, Frame);
    Mouse_Object->SetFrame(T);

    return 0;
}

//获取鼠标
static SQInteger Get_Cursor(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    uint32_t ObjectId = Mouse_Object->GetObjectID();
    //如果全局表里没有鼠标对象就添加
    if (!ActorPtrMapObject.count(ObjectId)) {
        Mouse_Object->Retain();
        ActorPtrMapObject[ObjectId] = Mouse_Object;
    }
    sq_pushinteger(v, ObjectId);
    return 1;
}


//创建图层
static SQInteger Create_Layer(HSQUIRRELVM v)
{
    SQInteger Top = sq_gettop(v);
    if (Top <= 0)
    {
        sq_throwerror(v, _SST("Incorrect function argument"));
        return 0;
    }

    //const SQChar* gLayer;
    //sq_getstring(v, 2, &gLayer);

    ////此操作会New出一个字符串需要手动销毁
    //char* gLayerbuf = SquirrelClassEx::SquirrelU2W((char*)gLayer);

    //std::string Layer = gLayerbuf;

    ////销毁New出来的字符串
    //delete[]gLayerbuf;

    //创建图层对象
    LayerActorPtr MouseUiLayer = new LayerActor();


    uint32_t ObjectId = MouseUiLayer->GetObjectID();


    ActorPtrMapObject[ObjectId] = MouseUiLayer;

    sq_pushinteger(v, ObjectId);
    return 1;
}


void SquirrelClassEx::R_Register_Nut(HSQUIRRELVM v)
{
    RegisterNutApi(_SST("C_API"), TestCallC, v);
    RegisterNutApi(_SST("Sout"), Sout, v);
    RegisterNutApi(_SST("Error"), Error, v);
    RegisterNutApi(_SST("Test"), TestCallC, v);
    RegisterNutApi(_SST("sq_RGBA"), RGBA, v);
    RegisterNutApi(_SST("sq_ReloadingScript"), ReloadingScript, v);
    RegisterNutApi(_SST("sq_Exit"), Exit, v);
    RegisterNutApi(_SST("sq_Cmd"), Cmd, v);
    RegisterNutApi(_SST("sq_String_Replace"), String_Replace, v);
    RegisterNutApi(_SST("sq_Register_Destruction"), Register_Destruction, v);

    //使用子线程预加载NPK
    RegisterNutApi(_SST("sq_ThreadPreloadImg"), ThreadPreloadImg, v);

    //根据Img路径释放纹理资源
    RegisterNutApi(_SST("sq_ReleaseTextureByImg"), ReleaseTextureByImg_n, v);
    
    //读取时装路径By 时装Index
    RegisterNutApi(_SST("sq_GetAvatarPathByIndex"), GetAvatarPathByIndex, v);
    //读取装备路径By 装备Index
    RegisterNutApi(_SST("sq_GetEquipmentPathByIndex"), GetEquipmentPathByIndex, v);
    //读取地图路径By 地图Index
    RegisterNutApi(_SST("sq_GetMapPathByIndex"), GetMapPathByIndex, v);
    //读取怪物路径By 怪物Index
    RegisterNutApi(_SST("sq_GetMonsterPathByIndex"), GetMonsterPathByIndex, v);
    //读取被动对象路径By 被动对象Index
    RegisterNutApi(_SST("sq_GetPassobjectPathByIndex"), GetPassobjectPathByIndex, v);
    //读取音频路径By 音频Index
    RegisterNutApi(_SST("sq_GetAudioPathByIndex"), GetAudioPathByIndex, v);



    ////////////////Actor类////////////////

    RegisterNutApi(_SST("sq_Create_CameraObjectAct"), Create_CameraObjectAct, v);//创建摄像机对象


    //文字类
    R_Register_Nut_Text();

    //图层类
    RegisterNutApi(_SST("sq_Create_Layer"), Create_Layer, v);//创建图层

    RegisterNutApi(_SST("sq_Create_BaseAct"), Create_BaseAct, v);//创建基础对象
    RegisterNutApi(_SST("sq_ReleaseActor"), ReleaseActor, v);//销毁对象
    RegisterNutApi(_SST("sq_Create_Image"), Create_Image, v);//创建Image对象
    RegisterNutApi(_SST("sq_Set_Image_CropRect"), Set_Image_CropRect, v);//裁切Image对象
    RegisterNutApi(_SST("sq_Create_ImageEx"), Create_ImageEx, v);//创建ExImage对象
    RegisterNutApi(_SST("sq_Set_ImageEx_Mode"), Set_ImageEx_Mode, v);//设置ExImage对象混合模式
    RegisterNutApi(_SST("sq_Set_ImageEx_Frame"), Set_ImageEx_Frame, v);//设置ExImage对象帧
    RegisterNutApi(_SST("sq_Set_ImageEx_Alpha"), Set_ImageEx_Alpha, v);//设置ExImage透明度
    RegisterNutApi(_SST("sq_Set_ImageEx_FrameInfo"), Set_ImageEx_FrameInfo, v);//设置ExImage帧信息
    RegisterNutApi(_SST("sq_Set_ImageEx_PlayAnimotion"), Set_ImageEx_PlayAnimotion, v);//设置ExImage 播放动画
    RegisterNutApi(_SST("sq_Set_ImageEx_Animotion_Frame"), Set_ImageEx_Animotion_Frame, v);//设置ExImage Ani帧
    RegisterNutApi(_SST("sq_Set_ImageEx_Shadow"), Set_ImageEx_Shadow, v);//设置ExImage 阴影


    RegisterNutApi(_SST("sq_SetRotateAnimotion"), Set_RotateAnimotion, v);//设置旋转动画
    RegisterNutApi(_SST("sq_SetAnchor"), SetActorAnchor, v);//设置锚点
    RegisterNutApi(_SST("sq_SetXPos"), SetActorXPos, v);//设置X坐标
    RegisterNutApi(_SST("sq_SetYPos"), SetActorYPos, v);//设置Y坐标
    RegisterNutApi(_SST("sq_GetXPos"), GetActorXPos, v);//设置X坐标
    RegisterNutApi(_SST("sq_SetActorShowBorder"), SetActorShowBorder, v);//渲染对象边框
    RegisterNutApi(_SST("sq_GetYPos"), GetActorYPos, v);//设置Y坐标
    RegisterNutApi(_SST("sq_SetPosition"), SetActorPosition, v);//设置坐标X,Y
    RegisterNutApi(_SST("sq_SetScale"), SetActorScale, v);//设置缩放比例
    RegisterNutApi(_SST("sq_SetZOrder"), SetActorSetZOrder, v);//设置Z轴层级
    RegisterNutApi(_SST("sq_GetZOrder"), GetActorSetZOrder, v);//获取Z轴层级
    RegisterNutApi(_SST("sq_GetWidth"), GetActorWidth, v);//获取宽度
    RegisterNutApi(_SST("sq_GetHeight"), GetActorHeight, v);//获取高度
    RegisterNutApi(_SST("sq_GetName"), GetActorName, v);//获取名字
    RegisterNutApi(_SST("sq_SetName"), SetActorName, v);//设置名字
    RegisterNutApi(_SST("sq_SetActorOpacity"), SetActorOpacity, v);//设置透明度
    RegisterNutApi(_SST("sq_SetChild"), SetActorChild, v);//设置子对象
    RegisterNutApi(_SST("sq_GetChildByName"), GetChildByName, v);//获取子对象ByName
    RegisterNutApi(_SST("sq_RemoveChild"), RemoveActorChild, v);//移除子对象
    RegisterNutApi(_SST("sq_RemoveParent"), RemoveActorParent, v);//移除父对象
    RegisterNutApi(_SST("sq_GetParent"), GetActorParent, v);//移除父对象
    RegisterNutApi(_SST("sq_SetSize"), SetSize, v);//设置大小
    RegisterNutApi(_SST("sq_SetRotate"), SetRotate, v);//设置旋转


    //Sound类
    RegisterNutApi(_SST("sq_Create_Sound"), Create_Sound, v);//创建声音对象
    RegisterNutApi(_SST("sq_Set_Sound_Task"), Set_Sound_Task, v);//设置声音对象工作
    RegisterNutApi(_SST("sq_Get_Sound_Volume"), Get_Sound_Volume, v);//获取声音对象音量
    RegisterNutApi(_SST("sq_Set_Sound_Volume"), Set_Sound_Volume, v);//设置声音对象音量

    RegisterNutApi(_SST("sq_PlaySoundEffect"), Squirrel_PlaySoundEffect, v);//设置声音对象音量
    RegisterNutApi(_SST("sq_ReleseSoundEffect"), Squirrel_ReleseSoundEffect, v);//设置声音对象音量

    //Input类
    RegisterNutApi(_SST("sq_Key_Pressed"), Key_Pressed, v);//判断键值输入  鼠标和键盘都有
    RegisterNutApi(_SST("sq_Key_Is_Down"), Key_Is_Down, v);//判断键值按下   鼠标和键盘都有
    RegisterNutApi(_SST("sq_Key_WasReleased"), Key_WasReleased, v);//判断键值刚抬起   鼠标和键盘都有


    //场景类
    RegisterNutApi(_SST("sq_Reset_Scene"), Reset_Scene, v);//重置场景
    RegisterNutApi(_SST("sq_Create_Scene"), Create_Scene, v);//创建场景
    RegisterNutApi(_SST("sq_Get_SceneByName"), Get_SceneByName, v);//根据名字获取场景   如果不存在会自动创建
    RegisterNutApi(_SST("sq_Get_TownSceneByName"), Get_TownSceneByName, v);//根据名字获取城镇场景   如果不存在会自动创建




    //导演类
    RegisterNutApi(_SST("sq_EnterStage"), Director_EnterStage, v);//导演切换场景
    RegisterNutApi(_SST("sq_PushStage"), Director_PushStage, v);//导演切换场景并将当前场景Push入场景栈
    RegisterNutApi(_SST("sq_PopStage"), Director_PopStage, v);//导演退出当前场景并切换到上一个场景
    RegisterNutApi(_SST("sq_GetScene"), Director_GetScene, v);//导演获取当前场景
    RegisterNutApi(_SST("sq_ClearStages"), Director_ClearStages, v);//导演退出当前场景并清空场景栈

    //场景过渡动画类
    RegisterNutApi(_SST("sq_Create_FadeTransition"), Creat_FadeTransition, v);//创建淡入淡出过渡动画

    //鼠标指针类
    RegisterNutApi(_SST("sq_SetCursor_Task"), SetCursor_Task, v);//创建淡入淡出过渡动画
    RegisterNutApi(_SST("sq_Sync_CursorPos"), Sync_CursorPos, v);//同步鼠标坐标
    RegisterNutApi(_SST("sq_Get_Cursor"), Get_Cursor, v);//获取鼠标

    //UI类
    //UI类-按钮类
    RegisterNutApi(_SST("sq_Create_Button"), Create_Button, v);//创建按钮对象
    RegisterNutApi(_SST("sq_Button_Load_Texture"), Button_Load_Texture, v);//设置按钮状态纹理
    RegisterNutApi(_SST("sq_Button_Init"), Button_Init, v);//设置按钮状态纹理
    RegisterNutApi(_SST("sq_Button_IsPress"), Button_IsPress, v);//获取按钮是否被点击
    RegisterNutApi(_SST("sq_Button_IsHover"), Button_IsHover, v);//获取按钮是否被点击
    RegisterNutApi(_SST("sq_Button_RemoveZorder"), Button_RemoveZorder, v);//移除自己的Z轴序列

    //UI类-画布类
    RegisterNutApi(_SST("sq_Create_Canvas"), Create_Canvas, v);//创建画布
    RegisterNutApi(_SST("sq_Canvas_BeginDraw"), Canvas_BeginDraw, v);//画布开始渲染
    RegisterNutApi(_SST("sq_Canvas_EndDraw"), Canvas_EndDraw, v);//画布结束渲染
    RegisterNutApi(_SST("sq_Canvas_DrawTexture"), Canvas_DrawTexture, v);//画布绘制纹理
    RegisterNutApi(_SST("sq_Canvas_DrawText"), Canvas_DrawText, v);//画布绘制文字

    ////IMGUI
    //RegisterNutApi(_SST("sq_Create_ImguiLayer"), Create_ImguiLayer, v);//创建Imgui图层
    //RegisterNutApi(_SST("sq_Imgui_Text"), Imgui_Text, v);//Imgui 文字
    //RegisterNutApi(_SST("sq_Imgui_InputText"), Imgui_InputText, v);//Imgui 输入框
    //RegisterNutApi(_SST("sq_Imgui_SetWindowSize"), Imgui_SetWindowSize, v);//Imgui 设置窗口大小
    //RegisterNutApi(_SST("sq_Imgui_SetWindowPos"), Imgui_SetWindowPos, v);//Imgui 设置窗口大小

}

void SquirrelClassEx::Run()
{


}

void SquirrelClassEx::Close()
{
    sq_close(v);
}


