--------------------------------------------------------------------------------
 --GLOBALS
--------------------------------------------------------------------------------
Global("wtMainPanel", nil)
Global("wtTextView", nil)  

Global("wtRText", nil)
Global("wtGText", nil) 
Global("wtYText", nil)

Global("Reactor", nil)
Global("Select", nil)

Global( "isAddon", false )

Global( "TargetID", nil )
Global( "LastTargetID", nil )
Global("RTarget", nil)

Global( "GlobalCt", 0 )
Global( "Timer", 0 )

Global( "Index", 0 )

Global( "UnitID",{})
Global( "Wid",{})

Global( "W",{})
Global( "Rd",{})
Global( "G",{})
Global( "Y",{})

Global( "GIPNOZ",{})
Global( "MP",{})

Global( "R",{})
Global( "Status",{})

	-- Статусы:
	-- 1. Моб законтролен
	-- 2. Сугроб сбит
	-- nil еще не контролили\мертв
	-- 3... 

Global( "BuffID",{})
Global( "Time",{})
Global( "Ct",{})

Global( "LOC",nil)
Global( "LastTime",{})

local inControl = false
--------------------------------------------------------------------------------
 --STRIHGS
--------------------------------------------------------------------------------
Global( "abIcyGrave",{})
abIcyGrave["rus"] = "Сугроб"
abIcyGrave["fra"] = "Tombeau de glace"
abIcyGrave["ger"] = "Eisiges Grab"
abIcyGrave["eng"] = "Icy Grave" -- Mage's spell (Found on allodsbase.com)
Global( "abPlague",{})
abPlague["rus"] = "Мир Призраков" 
abPlague["fra"] = "Faiblesse" 
abPlague["ger"] = "Lahmende Plage" 
abPlague["eng"] = "Debilitating Plague" -- Summoner's talent, from Summoner's talent grid (Found on allodsbase.com)
Global( "abPotion",{})
abPotion["rus"] = "Сонное зелье"
abPotion["eng"] = "Lethargy Potion" -- Warden's spell (Found on allodsbase.com)
abPotion["fra"]   = "Potion de lethargie"
abPotion["ger"] = "Lethargietrank"
Global( "abBlock",{})
abBlock["rus"] = "Ментальный блок" --= -- Psionicist's ... (Can't find! Its translation is ~ "Mental Block", but not sure. It somehow related to "Will Suppression" and "Contact's Target". )
abBlock["ger"] = "Hypnose"
abBlock["fra"]   = "Lien Mental"
abBlock["eng"] = "Mental Link"
Global( "abSuppression",{})
abSuppression["rus"] = "Подавление воли"
abSuppression["eng"] = "Will Suppression" -- Psiocinist's spell (Found on allodsbase.com)
abSuppression["ger"] = "Willensunterdruckung"
abSuppression["fra"] = "Abolition de la volonte"
Global( "stOver",{})
stOver["rus"] = ". Атакует!"
stOver["eng"] = ". Time is over"
stOver["fra"] = ". Temps йcoulй"
stOver["ger"] =  ". Zeit abgelaufen"
Global( "stWait",{})
stWait["rus"] = "Подождите.."
stWait["eng"] = "Wait.."
stWait["fra"] = "Patientez..."
stWait["ger"] = "Warten..."
Global( "stINTERRUPTED",{})
stINTERRUPTED["rus"] = ". CБИЛ "
stINTERRUPTED["eng"] = ". INTERRUPTED by "
stINTERRUPTED["fra"] = ". INTERROMPU par"
stINTERRUPTED["ger"] = ". Unterbrochen durch "
Global( "stKill",{})
stKill["rus"] = ". Убил " 
stKill["eng"] = ". Killed by "
stKill["fra"] = ". Tuй par "
stKill["ger"] = ". getotet durch "
Global( "stSec",{})
stSec["rus"] = " сек."
stSec["eng"] = " sec"
stSec["fra"] = " sec"
stSec["ger"] = " sec"
Global( "stPreviousT",{})
stPreviousT["rus"] = "Прошлая цель"
stPreviousT["eng"] = "Previous target"
stPreviousT["fra"] = "Cible prйcйdente"
stPreviousT["ger"] = "Vorheriges Ziel"
Global( "stIce",{})
stIce["rus"] = ". Сугроб: "
stIce["eng"] = ". Ice: "
stIce["fra"] =". Glace: "
stIce["ger"] = ". Eisgrab: "
Global( "stPlague",{})
stPlague["rus"] = ". Мир: "
stPlague["eng"] = ". Plague: "
stPlague["fra"] = ". Faiblesse: "
stPlague["ger"] = ". Plage: "
Global( "stLethargy",{})
stLethargy["rus"] = ". Сон: "
stLethargy["eng"] = ". Lethargy: "
stLethargy["fra"] = ". Lйthargie: "
stLethargy["ger"] = ". Lethargie: "
Global( "stHypnosis",{})
stHypnosis["rus"] = ". Гипноз: "
stHypnosis["eng"] = ". Hypnosis: "
stHypnosis["fra"] = ". Hypnose: "
stHypnosis["ger"] = ". Hypnose: "
--[[
--------------------------------------------------------------------------------
-- Drag&Drop
--------------------------------------------------------------------------------
-- Drag&Drop by SLA, version 2010-06-19. и сохранение координат от DarkMaster

-- Drag&Drop
function DNDInit( wtReacting, wtMovable, ID )
	Global( "DragNDrop", {} )
	DragNDrop.ID = ID
	DragNDrop.wtReacting = wtReacting
	DragNDrop.wtMovable = wtMovable
	DragNDrop.IsPicked = false
	common.RegisterEventHandler( OnEventDNDPickAttempt, "EVENT_DND_PICK_ATTEMPT" )
	common.RegisterEventHandler( OnEventDNDDragTo, "EVENT_DND_DRAG_TO" )
	common.RegisterEventHandler( OnEventDNDDropAttempt, "EVENT_DND_DROP_ATTEMPT" )
	
------------- загрузка позиции
	local NewDNDWidgetInfo = wtMovable:GetPlacementPlain()
	local AddonName = common.GetAddonName()
	local SectionName = AddonName .. "_Widget"
	NewDNDWidgetInfo = userMods.GetGlobalConfigSection( SectionName ) or mainForm:GetPlacementPlain()
	mainForm:SetPlacementPlain( NewDNDWidgetInfo )
-------------	
	
	DNDReg()
end
function DNDReg()
 if mission.GetLocalTimeHMS then -- AO 2.0.01+
	mission.DNDRegister( DragNDrop.wtReacting, DragNDrop.ID * DND_CONTAINER_STEP + DND_WIDGET_MOVE, true )
 else -- AO 1.1.02-2.0.00
	mission.DNDRegister( DragNDrop.wtReacting, DND_WIDGET_MOVE * DND_CONTAINER_STEP + DragNDrop.ID, true )
 end
end
function DNDUnreg()
	mission.DNDUnregister( DragNDrop.wtReacting )
end
function OnEventDNDPickAttempt( params )
	local DnDiD = 1
	if mission.GetLocalTimeHMS then -- AO 2.0.01+
	  DnDiD = ( params.srcId - DND_WIDGET_MOVE ) / DND_CONTAINER_STEP
	else -- AO 1.1.02-2.0.00
	  DnDiD = math.mod( params.srcId, DND_CONTAINER_STEP )
	end
	if DnDiD == DragNDrop.ID then
		DragNDrop.Screen = widgetsSystem:GetPosConverterParams()
		DragNDrop.Place = DragNDrop.wtMovable:GetPlacementPlain()
		DragNDrop.DeltaX = math.ceil( params.posX * DragNDrop.Screen.fullVirtualSizeX / DragNDrop.Screen.realSizeX - DragNDrop.Place.posX )
		DragNDrop.DeltaY = math.ceil( params.posY * DragNDrop.Screen.fullVirtualSizeY / DragNDrop.Screen.realSizeY - DragNDrop.Place.posY )
		common.SetCursor( "drag" )
		DragNDrop.IsPicked = true
	end
end
function OnEventDNDDragTo( params )
	if DragNDrop.IsPicked then
		DragNDrop.Place.posX = math.ceil( params.posX * DragNDrop.Screen.fullVirtualSizeX / DragNDrop.Screen.realSizeX - DragNDrop.DeltaX )
		DragNDrop.Place.posY = math.ceil( params.posY * DragNDrop.Screen.fullVirtualSizeY / DragNDrop.Screen.realSizeY - DragNDrop.DeltaY )
		DragNDrop.wtMovable:SetPlacementPlain( DragNDrop.Place )
		common.SetCursor( "drag" )
	end
end
function OnEventDNDDropAttempt( params )
	if DragNDrop.IsPicked then
		mission.DNDConfirmDropAttempt()
		common.SetCursor( "default" )
		DragNDrop.IsPicked = false
------------ сохранение позиции
		local AddonName = common.GetAddonName()
		local SectionName = AddonName .. "_Widget"
		userMods.SetGlobalConfigSection( SectionName, mainForm:GetPlacementPlain() )
------------
	end
end
--]]

--------------------------------------------------------------------------------
-- EVENT HANDLERS
--------------------------------------------------------------------------------

function OnEventBuffChange( params )
  --if params.units then
     --local unitID = params.units.key      --- New\old API
	--for i in params.units do
	for i in params.objects do
      	if i then
		--local unitID = i
			--for x in params.units[i] do
			for x in params.objects[i] do
			--local index = x
				ChekBuff({ u = i, inx = x})
			end
      	end 
     end
	 
  --[[else
     local unitID = params.unitId
     local index = params.index
     ChekBuff({ u = unitID, inx = index})
  end--]]
end


function ChekBuff(params)
  
  --local Buff = unit.GetBuff(params.u, params.inx )
  local Buff = object.GetBuffInfo( params.inx )
  
  if Status[params.u] == 1 then
     local ab = userMods.FromWString( Buff.name )
     if Buff.producer.casterId == avatar.GetId() and ( ab == abIcyGrave[LOC] or ab ==  abPlague[LOC] or ab ==  abPotion[LOC] or ab ==  abBlock[LOC]) then
		inControl = true
 	BuffID[params.u] = params.inx
	Time[params.u]=math.ceil(Buff.remainingMs/1000)	

	if Time[params.u] <= 1 then Time[params.u] = LastTime[params.u] end	

	if Time[params.u] > 16 then 
		Wid[params.u] = G[params.u]
		W[params.u]:Show(false)
		Rd[params.u]:Show(false)
		G[params.u]:Show(true)
		Y[params.u]:Show(false)
	else 
		if Time[params.u] > 6 then
			Wid[params.u] = Y[params.u]
			W[params.u]:Show(false)
			Rd[params.u]:Show(false)
			Y[params.u]:Show(true)
			G[params.u]:Show(false)
		else
			Wid[params.u] = Rd[params.u]
			W[params.u]:Show(false)
			G[params.u]:Show(false)
			Rd[params.u]:Show(true)
			Y[params.u]:Show(false)
		end
	end

	if ab == abIcyGrave[LOC] then Wid[params.u]:SetVal( "time", userMods.ToWString( (Ct[params.u]+1) .. stIce[LOC] .. Time[params.u] .. stSec[LOC])) end
	if ab == abPlague[LOC] then Wid[params.u]:SetVal( "time", userMods.ToWString( (Ct[params.u]+1) .. stPlague[LOC] .. Time[params.u] .. stSec[LOC])) end
 	if ab == abPotion[LOC] then Wid[params.u]:SetVal( "time", userMods.ToWString( (Ct[params.u]+1) .. stLethargy[LOC] .. Time[params.u] .. stSec[LOC])) end
 	
	if ab == abBlock[LOC] then		
 		--local BuffsC = unit.GetBuffCount(params.u)
		local BuffsC = object.GetBuffs( params.u )
 		local findLoc = 0
		if BuffsC > 0 then
  			--for i = 0, BuffsC-1 do
			for buffId in BuffsC do
   				--Buff = unit.GetBuff(params.u, i )
				Buff = object.GetBuffInfo( buffId )
 				if Buff.producer.casterId == avatar.GetId() and userMods.FromWString( Buff.name ) == abSuppression[LOC] then
 					Wid[params.u]:SetVal( "time", userMods.ToWString( (Ct[params.u]+1) .. stHypnosis[LOC] .. Time[params.u] .. "|" .. math.ceil(Buff.remainingMs/1000)-1 .. stSec[LOC]))
					findLoc = 1
				end						
 			end
 		end
		if findLoc == 0 then
			Wid[params.u]:SetVal( "time", userMods.ToWString( (Ct[params.u]+1) .. stHypnosis[LOC] .. Time[params.u] .. stSec[LOC]))
		end				
 	end
     end
  end
end

-- "EVENT_UNIT_BUFF_ADDED" -- RU:obsolete
-- EVENT_OBJECT_BUFF_ADDED
function OnEventUnitBuffAdded(par)
	--local Buff = unit.GetBuff( par.unitId, par.index )
	local Buff = object.GetBuffInfo( par.buffId )
     	local ab = userMods.FromWString( Buff.name )
		par.unitId = par.objectId
		par.index = par.buffId
     	if Buff.producer.casterId == avatar.GetId() and ( ab == abIcyGrave[LOC] or ab ==  abPlague[LOC] or ab ==  abPotion[LOC] or ab ==  abBlock[LOC]) then
	    if Status[par.unitId] == 2 then
		Status[par.unitId] = 1
		Wid[par.unitId]:SetVal( "time", userMods.ToWString( stWait[LOC] ))
		BuffID[par.unitId] = par.index
		Time[par.unitId] = 30
	    else
	      if Status[par.unitId] == nil then

	        if ab ==  abPlague[LOC]  then MP[par.unitId] = 1 end
		if ab ==  abBlock[LOC] then GIPNOZ[par.unitId] = 1 end
		UnitID[par.unitId] = par.unitId			
			
			local desc = wtTextView:GetWidgetDesc()           	
			W[par.unitId] = mainForm:CreateWidgetByDesc( desc )
			W[par.unitId]:SetName( "w" .. par.unitId )
			mainForm:AddChild( W[par.unitId] )
			
			local desc = wtRText:GetWidgetDesc()           	
			Rd[par.unitId] = mainForm:CreateWidgetByDesc( desc )
			Rd[par.unitId]:SetName( "r" .. par.unitId )
			mainForm:AddChild( Rd[par.unitId] )
			
			local desc = wtGText:GetWidgetDesc()           	
			G[par.unitId] = mainForm:CreateWidgetByDesc( desc )
			G[par.unitId]:SetName( "g" .. par.unitId )
			mainForm:AddChild( G[par.unitId] )
			
			local desc = wtYText:GetWidgetDesc()           	
			Y[par.unitId] = mainForm:CreateWidgetByDesc( desc )
			Y[par.unitId]:SetName( "y" .. par.unitId )
			mainForm:AddChild( Y[par.unitId] )
			
			Wid[par.unitId] = W[par.unitId]			
			
			Wid[par.unitId]:SetVal( "time", userMods.ToWString( stWait[LOC] ))
		
			local placement = wtTextView:GetPlacementPlain()
				
           		placement.posY = placement.posY + (GlobalCt * 30 ) + 30
			Ct[par.unitId] = GlobalCt			
			GlobalCt = GlobalCt + 1


			Status[par.unitId] = 1
			BuffID[par.unitId] = par.index
		
			Select:SetPlacementPlain(placement)
			Select:Show(true)
			
			desc = Reactor:GetWidgetDesc()
			R[par.unitId] = mainForm:CreateWidgetByDesc( desc )
			R[par.unitId]:SetName( "" .. par.unitId )
			mainForm:AddChild( R[par.unitId] )
			R[par.unitId]:SetPlacementPlain(placement)
			R[par.unitId]:Show(true)

			placement.posY = placement.posY + 1

			W[par.unitId]:SetPlacementPlain(placement)
			Rd[par.unitId]:SetPlacementPlain(placement)
			G[par.unitId]:SetPlacementPlain(placement)
			Y[par.unitId]:SetPlacementPlain(placement)
			
			Wid[par.unitId]:Show(true)
	     end	
				
	     if mainForm:IsVisible() == false then
		mainForm:Show(true)	
		--DNDReg()
	     end			   
	  end		
	end
end

-- Targets changed
function OnEventTargetsChanged()
	LastTargetID = TargetID

	local MeID = avatar.GetId()
	TargetID = unit.GetPrimaryTarget(MeID)

	local flag = nil
	for i in Status do
		if i == TargetID then
			local placement = R[i]:GetPlacementPlain()
			Select:SetPlacementPlain(placement)
			flag = 1
		end 
	end

	if not flag and RTarget ~= TargetID then  Select:Show(false) end 
end

function OnAvatarCombat(params)
	if params.inCombat == false then
		inControl = params.inCombat
		for i in Wid do
			Status[i]=nil 
			UnitID[i]=nil
			BuffID[i]=nil
			Wid[i]:DestroyWidget()
			R[i]:DestroyWidget()
			
			Rd[i]:DestroyWidget()
			W[i]:DestroyWidget()
			G[i]:DestroyWidget()
			Y[i]:DestroyWidget()
		end

		GlobalCt = 0

		for i in LastTime do LastTime[i]=nil end	
	
		--DNDUnreg()
		mainForm:Show(false)	
				
	
	end
end


function OnEventUnitDamageReceived(params)
	if Status[params.target] == 1 then
	   if MP[params.target] == nil then
		Status[params.target] = 2
		Time[params.target]=nil

		Wid[params.target] = Rd[params.target]
		G[params.target]:Show(false)
		W[params.target]:Show(false)
		Rd[params.target]:Show(true)
		Y[params.target]:Show(false)
		
		Wid[params.target]:SetVal( "time", userMods.ToWString( Ct[params.target]+1 .. stINTERRUPTED[LOC] .. userMods.FromWString(params.sourceName)  ))
	    end
	end
	if Status[params.target] ~= nil then
		if params.lethal then
			---------------------------
			UnitID[params.target]=nil
			BuffID[params.target]=nil
			Time[params.target]=nil
			Status[params.target]=nil
			
			Wid[params.target] = W[params.target]
			G[params.target]:Show(false)
			Rd[params.target]:Show(false)
			W[params.target]:Show(true)
			Y[params.target]:Show(false)
			
			Wid[params.target]:SetVal( "time", userMods.ToWString( Ct[params.target]+1 .. stKill[LOC] .. userMods.FromWString(params.sourceName)  ))	
			R[params.target]:Enable( false )

			---------------------------
		end

	end
end


function OnReaction(params)
	if userMods.FromWString( userMods.ToWString(params.sender)) == "Reac" then
		if LastTargetID == nil then
			avatar.UnselectTarget()
			Select:Show(false)
		else
			avatar.SelectTarget( LastTargetID )
			local flag = nil
			for i in Status do
				if i == LastTargetID then
					flag = 1
				end 
			end
			if not flag then
				local placement = Reactor:GetPlacementPlain()
				Select:SetPlacementPlain(placement)
				RTarget = LastTargetID				
			end
			Select:Show(true)
		end
	else
		local id = common.GetIntFromWString( userMods.ToWString( params.sender ))
		if id == nil then avatar.UnselectTarget()
		else 
			avatar.SelectTarget( id )
			Select:Show(true)
		end
	end
end

function OnTimer( params )
	if mainForm:IsVisible() == true then
		for i in Time do 
			if Time[i] == LastTime[i] and Time[i] < 3 then
				Status[i] = 2
				Wid[i]:SetVal( "time", userMods.ToWString( Ct[i]+1 .. stOver[LOC] ))

			else
				LastTime[i] = Time[i]
			end
		end	
	end
end
--------------------------------------------------------------------------------
function DeliteW(params)
	Status[params]=2
	UnitID[params]=nil
	BuffID[params]=nil
	Time[params]=nil
	Wid[params]:DestroyWidget() 	
	R[params]:DestroyWidget() 
	Rd[params]:DestroyWidget()
	W[params]:DestroyWidget()
	G[params]:DestroyWidget()
	Y[params]:DestroyWidget()
end

-- AO game Localization detection by SLA. Version 2011-02-10.
function GetGameLocalization()
local B = cartographer.GetMapBlocks()
local T = { rus="\203\232\227\224", eng="Holy Land", ger="Heiliges Land",
fra="Terre Sacr\233e"}      -- , br="Terra Sagrada", jpn="\131\74\131\106\131\65" }
for b in B do for l,t in T do
if userMods.FromWString( cartographer.GetMapBlockInfo(B [b] ).name ) == t
then return l end; end; end; return "eng"
end

function onAvatar( params )
	LOC = GetGameLocalization()
	wtTextView:SetVal( "time", userMods.ToWString( stPreviousT[LOC] ))
end
------------ for AddonManager-----------------------
function onAddonManagerMEM( params )
    userMods.SendEvent( "U_EVENT_ADDON_MEM_USAGE_RESPONSE", { sender = common.GetAddonName(), memUsage = gcinfo() } )
end
function onAddonManagerDND( params )
    if params.target == common.GetAddonName() then
		DnD:Enable( mainForm, params.state )
    end
end

function onAddonManagerUI( params )
	mainForm:Show( inControl and params.visible )
end

function OnInfo( params )
	if params.target == common.GetAddonName() then
		local Desc = "It shows the countdowns for your control skils" 
		if LOC and LOC == "rus" then Desc = "Таймеры контролирующих заклинаний"  end
		userMods.SendEvent( "SCRIPT_ADDON_INFO_RESPONSE", {
		sender = params.target,
		desc = Desc
		} )
	end
end
--------------------------------------------------------------------------------
-- INITIALIZATION
--------------------------------------------------------------------------------
function Init()  
	  
	common.RegisterEventHandler( OnEventTargetsChanged, "EVENT_AVATAR_PRIMARY_TARGET_CHANGED" )
	--common.RegisterEventHandler( OnEventBuffChange, "EVENT_UNIT_BUFFS_ELEMENT_CHANGED")
	common.RegisterEventHandler( OnEventBuffChange, "EVENT_OBJECT_BUFFS_ELEMENT_CHANGED")
	
	--common.RegisterEventHandler( OnEventUnitBuffAdded, "EVENT_UNIT_BUFF_ADDED" )
	common.RegisterEventHandler( OnEventUnitBuffAdded, "EVENT_OBJECT_BUFF_ADDED" )
	
	common.RegisterEventHandler( OnEventUnitDamageReceived, "EVENT_UNIT_DAMAGE_RECEIVED" )	
	common.RegisterEventHandler( OnAvatarCombat, "EVENT_AVATAR_COMBAT_STATUS_CHANGED" )
	common.RegisterEventHandler( OnTimer, "EVENT_SECOND_TIMER" )

	-----------AddonManager
	common.RegisterEventHandler( OnInfo, "SCRIPT_ADDON_INFO_REQUEST" )
	common.RegisterEventHandler(onAddonManagerMEM, "U_EVENT_ADDON_MEM_USAGE_REQUEST")
	common.RegisterEventHandler(onAddonManagerDND, "U_EVENT_TOGGLE_DND")
	common.RegisterEventHandler(onAddonManagerDND, "SCRIPT_TOGGLE_DND")
	common.RegisterEventHandler(onAddonManagerUI, "SCRIPT_TOGGLE_UI")
	---
	Reactor = mainForm:GetChildChecked( "Reac", false )

	wtTextView = mainForm:GetChildChecked( "Time", false )
	wtRText = mainForm:GetChildChecked( "RTime", false )
	wtGText = mainForm:GetChildChecked( "GTime", false )
	wtYText = mainForm:GetChildChecked( "YTime", false )
	Select = mainForm:GetChildChecked( "Select", false )

------------------
	local placement = wtTextView:GetPlacementPlain()
	Reactor:SetPlacementPlain(placement)
------------------
	Select:Show(false)
	wtRText:Show(false)
	wtGText:Show(false)
	wtYText:Show(false)
		
	common.RegisterReactionHandler( OnReaction, "ReactionClick" )

	DnD:Init( 567, Reactor, mainForm, true )
	mainForm:Show(false)	
	--DNDUnreg()

	common.RegisterEventHandler(onAvatar, "EVENT_AVATAR_CREATED")
	if avatar.IsExist() then onAvatar() end
end
--------------------------------------------------------------------------------
Init()
--------------------------------------------------------------------------------
