-- Rush Duel 召唤
RushDuel = RushDuel or {}

SUMMON_VALUE_ZERO = 0x20 -- 不用解放的妥协召唤
SUMMON_VALUE_ONE = 0x40 -- 解放1只的妥协召唤
SUMMON_VALUE_TWO = 0x80 -- 解放2只的妥协召唤
SUMMON_VALUE_THREE = 0x100 -- 解放3只的妥协召唤

-- 内部方法: 获取上级召唤的可解放怪兽
function RushDuel._private_get_tribute_group(filter, ...)
    if filter == nil then
        return nil
    else
        return Duel.GetMatchingGroup(filter, 0, LOCATION_MZONE, LOCATION_MZONE, nil, ...)
    end
end

-- 添加不用解放的妥协召唤手续
function RushDuel.AddSummonProcedureZero(card, desc, condition, operation)
    local e1 = Effect.CreateEffect(card)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_SINGLE)
    e1:SetCode(EFFECT_SUMMON_PROC)
    e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    e1:SetCondition(RushDuel.SummonProcedureConditionZero(condition))
    if operation ~= nil then
        e1:SetOperation(operation)
    end
    e1:SetValue(SUMMON_VALUE_ZERO)
    card:RegisterEffect(e1)
    return e1
end
function RushDuel.SummonProcedureConditionZero(condition)
    return function(e, c, minc)
        if c == nil then
            return true
        end
        local tp = c:GetControler()
        return minc == 0 and c:IsLevelAbove(5) and Duel.GetLocationCount(tp, LOCATION_MZONE) > 0 and (not condition or condition(c, e, tp))
    end
end

-- 添加解放1只的妥协召唤手续
function RushDuel.AddSummonProcedureOne(card, desc, condition, filter, operation)
    local e1 = Effect.CreateEffect(card)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_SINGLE)
    e1:SetCode(EFFECT_SUMMON_PROC)
    e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    e1:SetCondition(RushDuel.SummonProcedureConditionOne(filter, condition))
    e1:SetOperation(RushDuel.SummonProcedureOperationOne(filter, operation))
    e1:SetValue(SUMMON_TYPE_ADVANCE + SUMMON_VALUE_ONE)
    card:RegisterEffect(e1)
    return e1
end
function RushDuel.SummonProcedureConditionOne(filter, condition)
    return function(e, c, minc)
        if c == nil then
            return true
        end
        local tp = c:GetControler()
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        return c:IsLevelAbove(7) and minc <= 1 and Duel.CheckTribute(c, 1, 1, mg) and (not condition or condition(c, e, tp))
    end
end
function RushDuel.SummonProcedureOperationOne(filter, operation)
    return function(e, tp, eg, ep, ev, re, r, rp, c)
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        local sg = Duel.SelectTribute(tp, c, 1, 1, mg)
        c:SetMaterial(sg)
        Duel.Release(sg, REASON_SUMMON + REASON_MATERIAL)
        if operation then
            operation(e, tp, eg, ep, ev, re, r, rp, c, sg)
        end
    end
end

-- 添加解放2只的妥协召唤手续
function RushDuel.AddSummonProcedureTwo(card, desc, condition, filter, operation)
    local e1 = Effect.CreateEffect(card)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_SINGLE)
    e1:SetCode(EFFECT_SUMMON_PROC)
    e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    e1:SetCondition(RushDuel.SummonProcedureConditionTwo(filter, condition))
    e1:SetOperation(RushDuel.SummonProcedureOperationTwo(filter, operation))
    e1:SetValue(SUMMON_TYPE_ADVANCE + SUMMON_VALUE_TWO)
    card:RegisterEffect(e1)
    return e1
end
function RushDuel.SummonProcedureConditionTwo(filter, condition)
    return function(e, c, minc)
        if c == nil then
            return true
        end
        local tp = c:GetControler()
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        return minc <= 2 and Duel.CheckTribute(c, 2, 2, mg) and (not condition or condition(c, e, tp))
    end
end
function RushDuel.SummonProcedureOperationTwo(filter, operation)
    return function(e, tp, eg, ep, ev, re, r, rp, c)
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        local sg = Duel.SelectTribute(tp, c, 2, 2, mg)
        c:SetMaterial(sg)
        Duel.Release(sg, REASON_SUMMON + REASON_MATERIAL)
        if operation then
            operation(e, tp, eg, ep, ev, re, r, rp, c, sg)
        end
    end
end

-- 添加解放3只的妥协召唤手续
function RushDuel.AddSummonProcedureThree(card, desc, condition, filter, operation)
    local e1 = Effect.CreateEffect(card)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_SINGLE)
    e1:SetCode(EFFECT_SUMMON_PROC)
    e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    e1:SetCondition(RushDuel.SummonProcedureConditionThree(filter, condition))
    e1:SetOperation(RushDuel.SummonProcedureOperationThree(filter, operation))
    e1:SetValue(SUMMON_TYPE_ADVANCE + SUMMON_VALUE_THREE)
    card:RegisterEffect(e1)
    local mt = getmetatable(card)
    if mt.is_can_triple_tribute == nil then
        mt.is_can_triple_tribute = true
    end
    return e1
end
function RushDuel.SummonProcedureConditionThree(filter, condition)
    return function(e, c, minc)
        if c == nil then
            return true
        end
        local tp = c:GetControler()
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        return minc <= 3 and Duel.CheckTribute(c, 3, 3, mg) and (not condition or condition(c, e, tp))
    end
end
function RushDuel.SummonProcedureOperationThree(filter, operation)
    return function(e, tp, eg, ep, ev, re, r, rp, c)
        local mg = RushDuel._private_get_tribute_group(filter, e, tp)
        local sg = Duel.SelectTribute(tp, c, 3, 3, mg)
        c:SetMaterial(sg)
        Duel.Release(sg, REASON_SUMMON + REASON_MATERIAL)
        if operation then
            operation(e, tp, eg, ep, ev, re, r, rp, c, sg)
        end
    end
end

-- 上级召唤时的解放怪兽检测
function RushDuel.CreateAdvanceCheck(card, filter, count, flag)
    local e1 = Effect.CreateEffect(card)
    e1:SetType(EFFECT_TYPE_SINGLE)
    e1:SetCode(EFFECT_MATERIAL_CHECK)
    e1:SetValue(function(e, c)
        local mg = c:GetMaterial()
        local ct = math.min(count, mg:GetCount())
        local label = 0
        if c:IsLevelBelow(6) and count == 2 then
            -- 当前等级小于解放要求
        elseif ct > 0 and mg:IsExists(filter, ct, nil, e) then
            label = flag
        end
        e:SetLabel(label)
    end)
    card:RegisterEffect(e1)
    local e2 = Effect.CreateEffect(card)
    e2:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_CONTINUOUS)
    e2:SetCode(EVENT_SUMMON_SUCCESS)
    e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE)
    e2:SetLabelObject(e1)
    e2:SetCondition(RushDuel.AdvanceCheckCondition)
    e2:SetOperation(RushDuel.AdvanceCheckOperation)
    card:RegisterEffect(e2)
    return e1, e2
end
function RushDuel.AdvanceCheckCondition(e, tp, eg, ep, ev, re, r, rp)
    return e:GetLabelObject():GetLabel() ~= 0 and e:GetHandler():IsSummonType(SUMMON_TYPE_ADVANCE)
end
function RushDuel.AdvanceCheckOperation(e, tp, eg, ep, ev, re, r, rp)
    e:GetHandler():RegisterFlagEffect(e:GetLabelObject():GetLabel(), RESET_EVENT + RESETS_STANDARD, 0, 1)
end

-- 获取召唤的解放数量
function RushDuel.GetTributeCount(card, advance)
    if card:IsSummonType(SUMMON_VALUE_ZERO) then
        return 0
    elseif card:IsSummonType(SUMMON_VALUE_ONE) then
        return 1
    elseif card:IsSummonType(SUMMON_VALUE_TWO) then
        return 2
    elseif card:IsSummonType(SUMMON_VALUE_THREE) then
        return 3
    elseif card:IsSummonType(SUMMON_TYPE_ADVANCE) then
        return advance
    else
        return 0
    end
end

-- 分割上级召唤的解放怪兽
function RushDuel.SplitTribute(card, group)
    local g = group or card:GetMaterial()
    local normal, double = Group.CreateGroup(), Group.CreateGroup()
    g:ForEach(function(tc)
        if RushDuel.IsCanDoubleTribute(tc, card) then
            double:AddCard(tc)
        else
            normal:AddCard(tc)
        end
    end)
    return normal, double
end

-- 记录攻击表示上级召唤的状态
function RushDuel.CreateAdvanceSummonFlag(card, flag)
    local e1 = Effect.CreateEffect(card)
    e1:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_CONTINUOUS)
    e1:SetCode(EVENT_SUMMON_SUCCESS)
    e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE)
    e1:SetLabel(flag)
    e1:SetCondition(RushDuel.AdvanceSummonFlagCondition)
    e1:SetOperation(RushDuel.AdvanceSummonFlagOperation)
    card:RegisterEffect(e1)
    return e1
end
function RushDuel.AdvanceSummonFlagCondition(e, tp, eg, ep, ev, re, r, rp)
    return e:GetHandler():IsSummonType(SUMMON_TYPE_ADVANCE)
end
function RushDuel.AdvanceSummonFlagOperation(e, tp, eg, ep, ev, re, r, rp)
    e:GetHandler():RegisterFlagEffect(e:GetLabel(), RESET_EVENT + RESETS_STANDARD, 0, 1)
end

-- 三重解放 (临时处理方法)
function RushDuel.CreateTripleTribute(source, card, desc, value, forced)
    local e1 = Effect.CreateEffect(source)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_FIELD)
    e1:SetCode(EFFECT_SUMMON_PROC)
    e1:SetRange(LOCATION_MZONE)
    e1:SetTargetRange(LOCATION_HAND, 0)
    e1:SetCondition(RushDuel.TripleTributeCondition)
    e1:SetTarget(RushDuel.TripleTributeTarget(value))
    e1:SetOperation(RushDuel.TripleTributeOperation)
    e1:SetValue(SUMMON_TYPE_ADVANCE + SUMMON_VALUE_THREE)
    card:RegisterEffect(e1, forced)
    return e1
end
function RushDuel.TripleTributeCondition(e, c, minc)
    if c == nil then
        return true
    end
    local tc = e:GetHandler()
    local tp = c:GetControler()
    local mg = Duel.GetTributeGroup(c)
    return minc <= 3 and mg:IsContains(tc) and Duel.GetMZoneCount(tp, tc) > 0
end
function RushDuel.TripleTributeTarget(value)
    return function(e, c)
        return value(e, c) and c.is_can_triple_tribute
    end
end
function RushDuel.TripleTributeOperation(e, tp, eg, ep, ev, re, r, rp, c)
    local mg = Group.FromCards(e:GetHandler())
    c:SetMaterial(mg)
    Duel.Release(mg, REASON_SUMMON + REASON_MATERIAL)
end

-- 添加手卡特殊召唤手续
function RushDuel.AddHandSpecialSummonProcedure(card, desc, condition, target, operation, value, position)
    local e1 = Effect.CreateEffect(card)
    e1:SetDescription(desc)
    e1:SetType(EFFECT_TYPE_FIELD)
    e1:SetCode(EFFECT_SPSUMMON_PROC)
    if position == nil then
        e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    else
        e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE + EFFECT_FLAG_SPSUM_PARAM)
        e1:SetTargetRange(position, 0)
    end
    e1:SetRange(LOCATION_HAND)
    if condition ~= nil then
        e1:SetCondition(condition)
    end
    if target ~= nil then
        e1:SetTarget(target)
    end
    if operation ~= nil then
        e1:SetOperation(operation)
    end
    if value ~= nil then
        e1:SetValue(value)
    end
    card:RegisterEffect(e1)
    return e1
end
