local _
local name, spellId, unit

local raidRanges, unitRange = {}
local rx, ry, px, py, zx1, zy1, zx2, zy2, dx, dy
local function GetRangeToRaidMember(unit)
	unitRange = raidRanges[unit] 
	if not unitRange then
		unitRange = { dist = 100000, time = 0}
		raidRanges[unit] = unitRange
	end
	if not WorldMapFrame:IsVisible() and unitRange.time < GetTime() then
		_, zx1, zy1, zx2, zy2 = GetCurrentMapZone();
		rx, ry = GetPlayerMapPosition(unit);
		px, py = GetPlayerMapPosition("player");
		if (rx == 0 and ry == 0) or (px == 0 and py == 0) or not ( zx1 and zx2 and zy1 and zy2) then
			unitRange.dist = 100000
		else
			dx,dy = math.abs(px - rx) * (zx1 - zx2), math.abs(py - ry) * (zy1 - zy2)
			unitRange.dist = math.sqrt(dx*dx + dy*dy)
		end
	end
	return unitRange.dist
end

local expirationTime,count,unit,unit2
WhatsNext:AddConditionalStatement("Player Need Buff From Player",{
	category = "Buff",
	test = function(checkTable) 
		for i=1,40 do
			name, _, _, count, _, _, expirationTime, unit = UnitBuff(tostring(checkTable.unit1),i) 
			if WhatsNext:GetSpellName(checkTable.buffName) == name and unit and UnitIsUnit(unit,tostring(checkTable.unit2)) then
				return math.max(count,1) < tonumber(checkTable.count or 1) or expirationTime - tonumber(checkTable.time) < GetTime()
			end			
		end
		return true
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit1) .. " does not have " .. WhatsNext:GetNumberDisplay(checkTable.count or 1) .. " stack(s) of " .. WhatsNext:GetSpellDisplay(checkTable.buffName) .. " from " .. WhatsNext:GetUnitDisplay(checkTable.unit2) .. " or they will drop off within " .. WhatsNext:GetNumberDisplay(checkTable.time) .. " seconds." 
	end,
	arguments = {
		unit1 = {label = "Unit 1",type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		unit2 = {label = "Unit 2", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		buffName = {label = "Buff", type = "spell", default = ""},
		time = {label = "Seconds", type = "integer", default = 3, min=1,max=60},
		count = {label = "Stack Count",type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Player Need Buff",{
	category = "Buff",
	test = function(checkTable) 
		for i=1,40 do
			name, _, _, count, _, _, expirationTime = UnitBuff(tostring(checkTable.unit),i) 
			if WhatsNext:GetSpellName(checkTable.buffName) == name then
				return math.max(count,1) < tonumber(checkTable.count or 1) or expirationTime - tonumber(checkTable.time) < GetTime()
			end			
		end
		return true
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " does not have " .. tostring(checkTable.count or 1) .. " stack(s) of " .. WhatsNext:GetSpellDisplay(checkTable.buffName) .. " or they will drop off within " .. WhatsNext:GetNumberDisplay(checkTable.time) .. " seconds." 
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		buffName = {label = "Buff", type = "spell", default = ""},
		time = {label = "Seconds", type = "integer", default = 3, min = 1, max = 60},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Player Buffed",{
	category = "Buff",
	test = function(checkTable) 
		name, _, _, count, _, _, _, unit = UnitBuff(tostring(checkTable.unit), WhatsNext:GetSpellName(checkTable.buffName)) 
		return name and math.max(count,1) >=  tonumber(checkTable.count or 1) 
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " has " .. WhatsNext:GetNumberDisplay(checkTable.count or 1) .. " stack(s) of the " .. WhatsNext:GetSpellDisplay(checkTable.buffName) .. " buff."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		buffName = {label = "Buff", type = "spell", default = ""},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Player Buffed By Player",{
	category = "Buff",
	test = function(checkTable) 
		name, _, _, count, _, _, _, unit = UnitBuff(tostring(checkTable.unit1), WhatsNext:GetSpellName(checkTable.buffName)) 
		return name and unit and UnitIsUnit(unit,tostring(checkTable.unit2)) and math.max(count,1) >=  tonumber(checkTable.count or 1) 
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit1) .. " has " .. WhatsNext:GetNumberDisplay(checkTable.count or 1) .. " stack(s) of the " .. WhatsNext:GetSpellDisplay(checkTable.buffName) .. " buff from " .. WhatsNext:GetUnitDisplay(checkTable.unit2) .. "."
	end,
	arguments = {
		unit1 = {label = "Unit 1", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		unit2 = {label = "Unit 2", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		buffName = {label = "Buff", type = "spell", default = ""},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Target Has Debuff",{
	category = "Debuff",
	test = function(checkTable)
		name, _, _, count, _, _, _  = UnitDebuff(tostring(checkTable.unit), WhatsNext:GetSpellName(checkTable.debuffName))
		return UnitName(tostring(checkTable.unit)) and name and math.max(count,1) >= tonumber(checkTable.count or 1)
	end,
	text = function(checkTable)
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " has " .. WhatsNext:GetNumberDisplay(checkTable.count  or 1) .. " stack(s) of the " .. WhatsNext:GetSpellDisplay(checkTable.debuffName) .. " debuff."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		debuffName = {label = "Debuff", type = "spell", default = ""},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Target Need Debuff",{
	category = "Debuff",
	test = function(checkTable) 
		name, _, _, count, _, _, expirationTime  = UnitDebuff(tostring(checkTable.unit), WhatsNext:GetSpellName(checkTable.debuffName))
		return UnitName(tostring(checkTable.unit)) and (not name or (math.max(count,1) < tonumber(checkTable.count or 1)) or expirationTime - tonumber(checkTable.time) < GetTime())
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " does not have " .. WhatsNext:GetNumberDisplay(checkTable.count or 1) .. " stack(s) of " .. WhatsNext:GetSpellDisplay(checkTable.debuffName) .. " or it will drop off within " .. WhatsNext:GetNumberDisplay(checkTable.time) .. " seconds." 
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		debuffName = {label = "Debuff", type = "spell", default = ""},
		time = {label = "Seconds", type = "integer", default = 3, min = 1, max = 60},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})

WhatsNext:AddConditionalStatement("Target Has Debuff From Player",{
	category = "Debuff",
	test = function(checkTable)
		for i=1,40 do
			name, _, _, count, _, _, _, unit  = UnitDebuff(tostring(checkTable.unit1), i)
			if WhatsNext:GetSpellName(checkTable.debuffName) == name and unit and UnitIsUnit(unit,tostring(checkTable.unit2)) then
				return math.max(count,1) >= tonumber(checkTable.count or 1)
			end			
		end
	end,
	text = function(checkTable)
		return WhatsNext:GetUnitDisplay(checkTable.unit1) .. " has " .. WhatsNext:GetNumberDisplay(checkTable.count  or 1) .. " stack(s) of the " .. WhatsNext:GetSpellDisplay(checkTable.debuffName) .. " debuff from " .. WhatsNext:GetUnitDisplay(checkTable.unit2) .. "."
	end,
	arguments = {
		unit1 = {label = "Unit 1", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		unit2 = {label = "Unit 2", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		debuffName = {label = "Debuff", type = "spell", default = ""},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})


WhatsNext:AddConditionalStatement("Target Need Debuff From Player",{
	category = "Debuff",
	test = function(checkTable) 
		for i=1,40 do
			name, _, _, count, _, _, expirationTime, unit  = UnitDebuff(tostring(checkTable.unit1), i)
			if name and WhatsNext:GetSpellName(checkTable.debuffName) == name and unit and UnitIsUnit(unit,tostring(checkTable.unit2)) then
				return math.max(count,1) < tonumber(checkTable.count or 1) or expirationTime - tonumber(checkTable.time) < GetTime()
			end			
		end
		return true
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit1) .. " does not have " .. WhatsNext:GetNumberDisplay(checkTable.count or 1) .. " stack(s) of " .. WhatsNext:GetSpellDisplay(checkTable.debuffName) .. " from " .. WhatsNext:GetUnitDisplay(checkTable.unit2) .. " or they will drop off within " .. WhatsNext:GetNumberDisplay(checkTable.time) .. " seconds." 
	end,
	arguments = {
		unit1 = {label = "Unit 1", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		unit2 = {label = "Unit 2", type = "dropdown", default = "player", possibleValues = WhatsNext.valueLists.unitAny},
		debuffName = {label = "Debuff", type = "spell", default = ""},
		time = {label = "Seconds", type = "integer", default = 3, min = 1, max = 60},
		count = {label = "Stack Count", type = "integer", default = 1, min = 1, max = 100}
	}
})