---
--- Date         : 2020-07-23 16:41:43
--- Author       : LICHAO7
--- LastEditors  : LICHAO7
--- LastEditTime : 2020-08-18 17:39:01
--- Description  : Assemble Dataset mgr
---

local LAssembleFactoryModule = ReLoadScript("ugc_common/script/pc/assemble/assemble_factory.lua");
local ASSEMBLE_PATH          = FS.Path.Join(FS.GetCwd(), "UGCSource/assembles");
local ASSEMBLE_TEMPLATE_PATH = FS.Path.Join(FS.GetCwd(), "UGCSource/assembles/template");
local ASSEMBLE_USERDATA_PATH = FS.Path.Join(FS.GetCwd(), "UGCSource/assembles/userdata");
local ASSEMBLE_PART_PATH     = FS.Path.Join(FS.GetCwd(), "UGCSource/assembles/parts");
local ASSEMBLE_TRASH_DIR     = FS.Path.Join(ASSEMBLE_USERDATA_PATH, ".trash");
local ASSEMBLE_PART_EXT      = ".mesh";
local ASSEMBLE_EXT           = ".assemble";
local TEMPLATE_LIST          = {
    FLIGHT = FS.Path.Join(ASSEMBLE_TEMPLATE_PATH, "Flight", "FlightTemplate.assemble");
    CAR    = FS.Path.Join(ASSEMBLE_TEMPLATE_PATH, "Car",    "CarTemplate.assemble");
};

LAssembleFactory    = LAssembleFactoryModule.LAssembleFactory;
LAssembleRegistered = LAssembleFactoryModule.LAssembleRegistered;

GetModels = function(mtype)
    local umodels = {};

    -- Templates
    for key, item in pairs(TEMPLATE_LIST) do
        if FS.Path.Exists(item) then
            local assemble = LAssembleFactory(item, mtype);
            if assemble then
                table.insert(umodels, assemble);
            end
        end
    end

    -- UserModel
    FS.Walk(ASSEMBLE_USERDATA_PATH, function(current, dirs, files)
        while true do
            if current == ASSEMBLE_TRASH_DIR then break end

            local file = table.remove(files, 1);
            if file and string.lower(FS.Path.SplitExt(file)) == ASSEMBLE_EXT then
                local path     = FS.Path.Join(current, file);
                local assemble = LAssembleFactory(path, mtype);
                if assemble then
                    table.insert(umodels, assemble);
                end
            end
            if file == nil then
                break;
            end
        end
    end);
    return umodels;
end

GetParts = function()
    local vparts = {};
    FS.Walk(ASSEMBLE_PART_PATH, function(current, dirs, files)
        while true do
            local file = table.remove(files, 1);
            if file and string.lower(FS.Path.SplitExt(file)) == ASSEMBLE_PART_EXT then
                local path  = FS.Path.Join(current, file);
                local vpart = LAssembleFactory("LComponentAssemble");
                vpart:InitFromParams({
                    Name   = util.a2u8(string.replace(FS.Path.SplitFile(path), FS.Path.SplitExt(path), "")),
                    Type   = "ChildComponent",
                    Params = "",
                    Path   = "",
                    Asset  = path,
                    Socket = "ChildComponent",
                    Root   = false,
                });
                table.insert(vparts, vpart);
            end
            if file == nil then
                break;
            end
        end
    end);
    return vparts;
end

GetTemplates = function()
    local templates = {};
    FS.Walk(ASSEMBLE_TEMPLATE_PATH, function(current, dirs, files)
        while true do
            local file = table.remove(files, 1);
            if file and string.lower(FS.Path.SplitExt(file)) == ASSEMBLE_EXT then
                local path     = FS.Path.Join(current, file);
                local assemble = LAssembleFactory(path);
                if assemble then
                    table.insert(templates, assemble);
                end
            end
            if file == nil then
                break;
            end
        end
    end);
    return templates;
end

---
--- Save assemble to assemble file.
---
--- @param assemble LBaseAssemble
--- @param name string
--- @return boolean
---
Save = function(assemble, name)
    local path = FS.Path.Join(ASSEMBLE_USERDATA_PATH, string.format("%s.assemble", name));
    assemble:ToFile(path);
    if not FS.Path.Exists(path) then
        return false;
    end
    return true;
    -- return LAssembleFactory(path);
end

---
--- Move assemble file to trash.
---
--- @param assemble LBaseAssemble
--- @return boolean
---
RemoveModel = function(assemble)
    local trashFile = FS.Path.Join(ASSEMBLE_TRASH_DIR, FS.Path.SplitFile(assemble.m_strPath));
    if not FS.Path.Exists(ASSEMBLE_TRASH_DIR) then
        FS.MakeDir(ASSEMBLE_TRASH_DIR);
    end
    if FS.Path.Exists(trashFile) then
        FS.RemoveFile(trashFile);
    end
    return FS.Move(assemble.m_strPath, trashFile);
end
