-- Rush Duel 辅助函数
RushDuel = RushDuel or {}

-- 设置Cost标签, 无视Cost发动效果需做额外判断时使用
function RushDuel.SetCostLabel(e)
    e:SetLabel(1)
end
-- 重置Cost标签, 无视Cost发动效果需做额外判断时使用
function RushDuel.ResetCostLabel(e)
    e:SetLabel(0)
end
-- 是否设置了Cost标签
function RushDuel.IsCostLabel(e)
    return e:GetLabel() == 1
end
-- 为效果设置标签
function RushDuel.SetLabelAndObject(effect, target, set_label, set_object)
    if effect ~= nil and target ~= nil then
        if set_label ~= nil then
            effect:SetLabel(set_label(target))
        end
        if set_object ~= nil then
            effect:SetLabelObject(set_object(target))
        end
    end
end

-- 带有额外参数的过滤器
function RushDuel.Filter(filter, ...)
    local args = {...}
    return function(c)
        return filter(c, table.unpack(args))
    end
end
-- 带有额外参数的检测器
function RushDuel.Check(check, ...)
    local args = {...}
    return function(g)
        return check(g, table.unpack(args))
    end
end

-- 对卡片组里的全部卡片作位或运算
function RushDuel.GroupBor(g, func, ...)
    local result = 0
    local args = {...}
    g:ForEach(function(tc)
        result = result | func(tc, table.unpack(args))
    end)
    return result
end

-- 显示选择动画, 或者展示卡片组
function RushDuel.HintOrConfirm(group, hint_selection, confirm, target_player)
    if hint_selection then
        Duel.HintSelection(group)
    elseif confirm then
        Duel.ConfirmCards(target_player, group)
    end
end

-- 将 卡片组/卡片/效果 转化为卡片组, 对于极大怪兽, 其素材也包含其中
function RushDuel.ToMaximunGroup(target)
    local type = aux.GetValueType(target)
    local g = Group.CreateGroup()
    if type == "Group" then
        g:Merge(target)
    elseif type == "Card" then
        g:AddCard(target)
    elseif type == "Effect" then
        g:AddCard(target:GetHandler())
    end
    local overlay = Group.CreateGroup()
    g:ForEach(function(tc)
        if RushDuel.IsMaximumMode(tc) then
            overlay:Merge(tc:GetOverlayGroup())
        end
    end)
    g:Merge(overlay)
    return g
end

-- 获取可用的主要怪兽区域数量
function RushDuel.GetMZoneCount(player, max)
    local ct = Duel.GetLocationCount(player, LOCATION_MZONE)
    if Duel.IsPlayerAffectedByEffect(player, 59822133) then
        ct = math.min(ct, 1)
    end
    return math.min(ct, max)
end
-- 获取可用的魔法与陷阱区域数量
function RushDuel.GetSZoneCount(player, max)
    local ct = Duel.GetLocationCount(player, LOCATION_SZONE)
    return math.min(ct, max)
end

-- 将玩家卡组最上面的N张卡移到卡组最下面
function RushDuel.SendDeckTopToBottom(player, count)
    for i = 1, count do
        Duel.MoveSequence(Duel.GetDecktopGroup(player, 1):GetFirst(), 1)
    end
end
-- 将玩家卡组最下面的N张卡移到卡组最上面
function RushDuel.SendDeckBottomToTop(player, count)
    local g = Duel.GetFieldGroup(player, LOCATION_DECK, 0)
    for i = 1, count do
        Duel.MoveSequence(g:GetMinGroup(Card.GetSequence):GetFirst(), 0)
    end
end
-- 获取卡组底的N张卡
function RushDuel.GetDeckBottomGroup(player, count)
    local dg = Duel.GetFieldGroup(player, LOCATION_DECK, 0)
    local ct = dg:GetCount()
    if (count < ct) then
        local top = Duel.GetDecktopGroup(player, ct - count)
        dg:Sub(top)
    end
    return dg
end

-- 返回卡组并排序
function RushDuel.SendToDeckSort(target, sequence, reason, sort_player, target_player)
    local g = RushDuel.ToMaximunGroup(target)
    if g:GetCount() > 1 and sequence == SEQ_DECKBOTTOM then
        Duel.SendtoDeck(g, nil, SEQ_DECKTOP, reason)
    else
        Duel.SendtoDeck(g, nil, sequence, reason)
    end
    local og = Duel.GetOperatedGroup()
    local ct = og:FilterCount(Card.IsLocation, nil, LOCATION_DECK)
    if sequence == SEQ_DECKTOP and ct > 1 then
        Duel.SortDecktop(sort_player, target_player, ct)
    elseif sequence == SEQ_DECKBOTTOM then
        if ct > 1 then
            Duel.SortDecktop(sort_player, target_player, ct)
        end
        RushDuel.SendDeckTopToBottom(target_player, ct)
    end
    return og, ct
end

-- 获取被上级召唤解放时的基础攻击力
function RushDuel.GetBaseAttackOnTribute(c)
    local atk
    if RushDuel.IsMaximumMode(c) then
        atk = c.maximum_attack
    else
        atk = c:GetTextAttack()
    end
    return math.max(0, atk)
end
