local _,spell1,spell2,notInterruptible1,notInterruptible2
local currentspell = { ["spell"] = nil, ["rank"] = nil, ["target"] = nil }
local failedMaps = {}

local events = {}

function events:UNIT_SPELLCAST_SENT(a1,a2,a3,a4)
	 if a1 == "player" then
		currentspell.spell = a2
		currentspell.rank = a3
		currentspell.target = a4
	end
end	
function events:UI_ERROR_MESSAGE(a1,a2,a3,a4,a5,a6,a7,a8)
	-- we only reach here if we didn't hit the default "else"
	if currentspell.target then
		--print(a2,currentspell.target,FindUnitFor(currentspell.target));
		if not failedMaps[a2] then
			failedMaps[a2] = {};
		end
		failedMaps[a2][FindUnitFor(currentspell.target)] = GetTime();
          currentspell.spell = nil
          currentspell.rank = nil
          currentspell.target = nil
	end
end	



local function EventFunc(self, event, ...)
	events[event](event, ...)
end
local eventHandler = CreateFrame("Frame", nil, WorldFrame)
eventHandler:SetScript("OnEvent", EventFunc)
for eventname in pairs(events) do eventHandler:RegisterEvent(eventname) end	



function FindUnitFor(who)
  local i, size

  -- second parameter ("true" on these) indicates whether or not
  -- to give names qualified with -servername for players from
  -- other servers
  if GetUnitName("player", true) == who then return "player" end
  if GetUnitName("target", true) == who then return "target" end
  if GetUnitName("focus", true) == who then return "focus" end
  if GetUnitName("pet", true) == who then return "pet" end

  size = GetNumSubgroupMembers()
  if size > 0 then
    for i=1, size do
      if GetUnitName("party"..i, true) == who then return "party"..i end
      if GetUnitName("party"..i.."target", true) == who then return "party"..i.."target" end
    end
  end
  size = GetNumGroupMembers()
  if size > 0 then
    for i=1, size do
      if GetUnitName("raid"..i, true) == who then return "raid"..i end
      if GetUnitName("raid"..i.."target", true) == who then return "raid"..i.."target" end
    end
  end

  -- couldn't find a unit, just return what we were passed
  return who
end


WhatsNext:AddConditionalStatement("Target Out Of Sight",{
	category = "Casting",
	test = function(checkTable) 
	
		if not failedMaps["Target not in line of sight"] then
			return false;
		end
		
		for k, v in pairs(failedMaps["Target not in line of sight"]) do
			if UnitIsUnit(checkTable.unit,k) and failedMaps["Target not in line of sight"][k] + checkTable.seconds >= GetTime() then
				return true;
			end
		end
		return false;
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " was out of sight in the last " .. WhatsNext:GetNumberDisplay(checkTable.seconds) .. " second(s)."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		seconds = {label = "Seconds", type = "integer", default = 3, min = 1, max = 60}
	}
})
WhatsNext:AddConditionalStatement("Target Is Interruptable",{
	category = "Casting",
	test = function(checkTable) 
		spell1, _, _, _, _, _, _, _, notInterruptible1  = UnitCastingInfo(tostring(checkTable.unit))
		spell2, _, _, _, _, _, _, notInterruptible2  = UnitChannelInfo(tostring(checkTable.unit))
		return (spell1 and not notInterruptible1)  or (spell2 and not notInterruptible2)
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " is casting an interruptable spell."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})

WhatsNext:AddConditionalStatement("Target Is Uninterruptable",{
	category = "Casting",
	test = function(checkTable) 
		spell1, _, _, _, _, _, _, _, notInterruptible1  = UnitCastingInfo(tostring(checkTable.unit))
		spell2, _, _, _, _, _, _, notInterruptible2  = UnitChannelInfo(tostring(checkTable.unit))
		return (spell1 and notInterruptible1)  or (spell2 and notInterruptible2)
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " is casting an uninterruptable spell."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})

WhatsNext:AddConditionalStatement("Target Is Casting",{
	category = "Casting",
	test = function(checkTable) 
		return UnitCastingInfo(tostring(checkTable.unit)) or UnitChannelInfo(tostring(checkTable.unit))
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " is casting a spell."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})

WhatsNext:AddConditionalStatement("Target Is Casting Specific",{
	category = "Casting",
	test = function(checkTable) 
		return UnitCastingInfo(tostring(checkTable.unit)) == WhatsNext:GetSpellName(checkTable.spellName) or UnitChannelInfo(tostring(checkTable.unit)) == WhatsNext:GetSpellName(checkTable.spellName)
	end,
	text = function(checkTable) 
		return WhatsNext:GetUnitDisplay(checkTable.unit) .. " is casting " .. WhatsNext:GetSpellDisplay(checkTable.spellName)  .. "."
	end,
	arguments = {
		unit = {label = "Unit", type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
		spellName = {label = "Spell", type = "spell", default = ""}
	}
})