local Root = CoolLevelUp;

local Trainer = Root.GetOrNewModule("Trainer");

-- --------------------------------------------------------------------
-- **                             Locals                             **
-- --------------------------------------------------------------------

-- --------------------------------------------------------------------
-- **                            Methods                             **
-- --------------------------------------------------------------------

Trainer.GetNumResults = function(self)
    --[[ To debug
    return 4;
    ]]
    return #self.list;
end

Trainer.GetResultInfo = function(self, index)
    --[[ To debug
    if ( index == 1 ) then return "Eclat lunaire", 5, "Equilibre", 30; end
    if ( index == 2 ) then return "Récupération", 4, "Restoration", 21; end
    if ( index == 3 ) then return "Mutilation (ours)", 2, "Combat farouche", 60; end
    if ( index == 4 ) then return "Berserker", 0, "Combat farouche", 80; end
    ]]
    local info = self.list[index] or '';
    local name, rank, classTree, reqLevel = strsplit("`", info, 4);
    return name or nil, tonumber(rank or 0), classTree or nil, tonumber(reqLevel or 0);
end

Trainer.ListSkillsAtLevel = function(self, level)
    local index, info;
    for index, info in ipairs(self.list) do
        self.list[index] = nil;
    end

    local myClass = select(2, UnitClass("player"));
    local classDB = Root.Database.Get("trainer", myClass);

    if ( not classDB ) then return; end

    local i;
    for i=1, #classDB do
        local _, _, _, reqLevel = strsplit("`", classDB[i] or '', 4);
        if ( reqLevel ) and ( tonumber(reqLevel) == level ) then
            self.list[#self.list+1] = classDB[i];
        end
    end
end

-- --------------------------------------------------------------------
-- **                            Handlers                            **
-- --------------------------------------------------------------------

Trainer.OnStart = function(self)
    self.list = { };
end

local addList = { };
local affectedTrees = { };
Trainer.OnTrainerVisit = function(self)
    if IsTradeskillTrainer() then return; end

    -- Reveal all available services

    local availableStatus   = GetTrainerServiceTypeFilter("available");
    local unavailableStatus = GetTrainerServiceTypeFilter("unavailable");
    local alreadyStatus     = GetTrainerServiceTypeFilter("used");

    SetTrainerServiceTypeFilter("available", 1);
    SetTrainerServiceTypeFilter("unavailable", 1);
    SetTrainerServiceTypeFilter("used", 1);

    ExpandTrainerSkillLine(0);

    -- Prepare database update

    local myClass = select(2, UnitClass("player"));
    local classDB = Root.Database.Get("trainer", myClass) or { };
    local index, info, i, ii;

    --for index, info in pairs(classDB) do
    --    classDB[index] = nil;
    --end

    for index, info in pairs(addList) do addList[index] = nil; end
    for index, info in pairs(affectedTrees) do affectedTrees[index] = nil; end

    -- Now grab infos

    for i=1, GetNumTrainerServices() do
        local name, rank, category, expanded = GetTrainerServiceInfo(i);
        local classTree = GetTrainerServiceSkillLine(i);
        _, _, rank = string.find(rank, "(%d+)");
        rank = rank or 0;
        if ( category ~= "header" and classTree ) then
            local reqLevel = GetTrainerServiceLevelReq(i) or 0;
            if ( reqLevel > 0 ) then
                addList[#addList+1] = name.."`"..rank.."`"..classTree.."`"..reqLevel;
                affectedTrees[classTree] = true;
            end
        end
    end

    -- Remove skills belonging to the affected trees, 'cause they get refreshed.

    for i=#classDB, 1, -1 do
        local name, rank, classTree, reqLevel = strsplit("`", classDB[i], 4);
        if ( classTree and affectedTrees[classTree] ) then
            for ii=i, #classDB-1 do
                classDB[ii] = classDB[ii+1];
            end
            classDB[i] = nil;
        end
    end

    -- Put skills

    for i=1, #addList do
        classDB[#classDB+1] = addList[i];
    end

    -- Terminate database update

    Root.Database.Set("trainer", myClass, classDB);

    -- Restore old filters

    CollapseTrainerSkillLine(0);

    SetTrainerServiceTypeFilter("available", availableStatus or 0);
    SetTrainerServiceTypeFilter("unavailable", unavailableStatus or 0);
    SetTrainerServiceTypeFilter("used", alreadyStatus or 0);
end

