-----------------------------------------------------
--fonction générales sur les units --
-------------------------------------------------------------

--similaire  à l'assert sauf que ca affiche la popup avec call stackfunction AssertPopup(cond,message)
function AssertPopup(cond,message)
    --on vérifie débug option
	--sécurité sur le nil depuis la version 1.5
    if (DebugOptions ~= nil and DebugOptions["ShowErrorPopup"] == false) then
        return
    end

    --attention à ne pas mettre de load ou enable ds cette fonction
    if not cond then
		if PopupError.Enabled then -- si la popup est déjà là on reste sur la première erreur
			return
		end
		
        OPUnitFactory.GetUnit("PopupError","Sprite").Enabled=true
       
        local callstack

        callstack = OPLua.GetCallstack()
        callstack = string.gsub(callstack,"\\","\\\\")
        callstack = string.gsub(callstack,"<","\r\t<")
        local pos = string.find(callstack,"script")
        local path
        if pos ~= nil then
            path = string.sub(callstack,0,pos+6)
        else
            path = callstack
        end

        callstack = string.gsub(callstack,path,"")
		
		local tokenPos = string.find(callstack, "in")
		if tokenPos ~= nil then
			callstack = string.gsub(callstack,"in","\r\tin")
		end
		
        message = message.."\r CallStack : \r"..callstack
        OPUnitFactory.GetUnit("PopupErrorText","Text").Text=message  
        
    end    
end

--Le load qui surcharge Le GetUnit
-- s : nom de l'unit
-- c : classe
-- silent : indique si on teste si l'appel est valide ou pas
function Load(s,c,silent)

    --OPLog.Log(_VERSION)
    local ut,b
    b=true
    if (s==nil and silent ~= true) then
        AssertPopup( false, 'mauvais appel de load dans '..self.Name)
        return ut,false
    end
    
    --on force l'utilisation de la classe
    AssertPopup(type(s) == "string" and type(c) == "string" ,"Erreur sur les parametres de load" )
    
    ut=OPUnitFactory.GetUnit(s,c)
    
    if (ut== nil and silent ~= true) then
        if (s == nil) then
            AssertPopup( false, 'ERROR : Load : unit null')
        else
            if (type(s) == 'table') then
                --AssertPopup( false, 'ERROR : Load : unit null (table) : '.. table.getn(s) .. ' éléments')
                --OPLog.Log('ERROR : Load : unit null (table) : '.. table.getn(s) .. ' éléments')
                --OPLog.Log('               s[1] = ' .. s[1])
            else
                AssertPopup( false, 'ERROR : Load : unit null : '..s)
            end
        end
        b=false
    end
    return ut,b
    
end


--cache l'unit, même paramètre que Load
function Hide(s,c,silent)
    return ChangeVisibilityState(s,c,false,silent)
end

function ChangeVisibilityState(s,c,newstate,silent)
    local ut
    if type(s) == "string" then
        ut=Load(s,c,silent)
    else
        ut = s
    end
    AssertPopup( (ut ~= nil ) or silent , "Erreur Unit Null sur le ChangeVisibility	! ")
    if ut ~= nil then
        ut.Flags_Visible=newstate
        --ut.Flags_EditorVisible=newstate cet attribut à disparu dans la version 20 d'opalium
    end
    return ut
end


--rend visible l'unit
function Show(s,c, silent)
    return ChangeVisibilityState(s,c,true,silent)
end


function IsVisible(ut)
    return ut.Flags_Visible
end

--similaire au Load, sauf qu'on active  l'unit en même tps
function Enable(s,c)
    
    local ut = nil
    if (type(s) == 'string') then
        ut=Load(s,c)
		--OPLog.Log('enable '..s.." "..ut.Name)
	elseif (type(s) == 'table') then
		ut = s
		--OPLog.Log('enable '..ut.Name)
    else 
            ut=s
        end
    if (ut~= nil) then
        ut.Enabled=true
    end
    return ut
end


--similaire au Load, sauf qu'on désactive  l'unit en même tps
function Disable(s,c)
    local ut
    if (type(s) == 'string') then
             ut=Load(s,c)
    else 
            ut=s
    end
    
    AssertPopup(ut ~= nil , "ErreurDisable")
    
    if (ut~= nil) then
        ut.Enabled=false
    end
    return ut
end

--fonction qui permet d'appeler une fonction pour tous les élément d'une classe
-- class : nom de la classe
-- fct : fonction passée en paramétre qu'on applique sur les units
function ApplyToClass(class,fct)

    --applique la fct a tous les units de cette classe
    AssertPopup(type(fct)=="function" , "Erreur Param ApplyClass ! ")
    local compteur = 0
    local unit,b=OPUnitFactory.GetFirstUnit(class,1)
    while (unit ~= nil and compteur < 100) do
		-- if unit.Opl ~= "Dynamic" and fct == OPUnitFactory	 then
			-- --OPLog.Log("applytoclass "..tostring(unit).." "..tostring(unit.Name))
			-- return
		-- end
        fct(unit)
        unit=OPUnitFactory.GetNextUnit(b)
		compteur = compteur + 1
    end
    if compteur >= 100 then
		AssertPopup(false,  "Erreur Boucle ApplyClass ! ")
	end
end

function ApplyToChildren(ut,fct)

    --applique la fct a tous les units de cette classe
    AssertPopup(type(ut) == "table" and type(fct)=="function" , "Erreur Param ApplyChildren ! ")
    
    local unit = ut.Children[0]
    local compteur = 0
    while (unit ~= nil and compteur < 100) do --le 100 est pour sécurité
        --OPLog.Log("applytochild "..unit.Name)
        fct(unit)
        compteur = compteur+1
        unit=ut.Children[compteur]
    end    
	
	if compteur >= 100 then
		AssertPopup(false,  "Erreur Boucle ApplyChildren ! ")
	end
end


-- fonction quis'occupe de fermer l'unit créee dynamiquement
function KillUnit(unit)
	if unit~=nil then
		OPUnitFactory.CloseUnit(unit)
	end
    unit = nil
end

--setvariables reparti  entre system et globaldata
function SetVariables(s,val)
	GameVariables.Set(s,val)
end

--les fonctions qui suivent sont des racourcis pour accéder aux dataarrays
function GetVariables(s)
    if GameVariables.IsRegistered(s) then
        return GameVariables.Get(s)
    end    
end
function IsEqualVariables(s,val)
    if GameVariables.IsRegistered(s) then
        return GameVariables.IsEqual(s,val)
	else
		AssertPopup(false, "attention "..s.." pas défini !!")
    end
end 

function GetCurrentLevelData()

	return SampleLevel
end



function GetLevelData(s)
	ut_LevelDatas=GetCurrentLevelData()
	if ut_LevelDatas ~=nil then
		if ut_LevelDatas.IsRegistered(s) then
			return ut_LevelDatas.Get(s)
		else
		AssertPopup(false, "attention "..s.." pas défini !!")
		end
	else
		AssertPopup(false, "Impossible d'accéder au LevelData depuis cette phase de jeu")
	end
end

function SetLevelData(s,val)
	ut_LevelDatas=GetCurrentLevelData()
	if ut_LevelDatas ~=nil then
			 ut_LevelDatas.Set(s, val)
	else
		AssertPopup(false, "Impossible d'accéder au LevelData depuis cette phase de jeu")
	end
end

function IsEqualDatas(s, val)
	ut_LevelDatas=GetCurrentLevelData()
	if ut_LevelDatas ~=nil then
		if ut_LevelDatas.IsRegistered(s) then
			return ut_LevelDatas.IsEqual(s, val)
		else
		AssertPopup(false, "attention "..s.." pas défini !!")
		end
	else
		AssertPopup(false, "Impossible d'accéder au LevelData depuis cette phase de jeu")
	end
end

function GetUserData(s)
    return UserData.Get(s,val)
end

function SetUserData(s,val)
    UserData.Set(s,val)
end

function IsEqualUserData(s, val)
	return UserData.IsEqual(s,val)
end
---------------------------------
--  function sur les tableaux  --
---------------------------------


--indique si X est dans tabin
function IsIn(tabin, x)
	return GlobalFunctions.IsInFct(tabin,x)
end

-------------------------------------------------
-------------------------son---------------------
-------------------------------------------------

function PlaySoundEffect(s,erase,delay, UnitNotify, loop)

    SoundPlayer.Play(s,erase,delay, loop)
	local soundUnit = Load(s,'SimpleSound',true)
	if UnitNotify~=nil and UnitNotify.OnSoundEnd~=nil then
		if soundUnit ~= nil and soundUnit~= nil then
			soundUnit.SetUserUnitNotify(UnitNotify)
		else
			UnitNotify.OnSoundEnd(s,true)
		end
	end
    return soundUnit -- On retourne l'unit pour pouvoir lui faire un setnotify
end

function PlayRandomSound(tab,erase,delay)
	SoundPlayer.PlayRandom(tab,erase,delay)
end

function OnSimpleSoundEnd(Name)
    return
end


--****************************************--
--****************************************--
--****************************************--

--fonction générique 
-- premier argument les event pour la version PC
-- second argument les events pour la version Wii 
-- on peut pas le sortir de l'unitmanager, il faut appeler le registerlistener sur l'unit en cours
function RegisterListenerGen( eventsforpc, eventsforwii)
	--OPLog.Log("RegisterListener "..self.Name)

	if (OPCore.GetPlatform() == "Wii")  then
		OPInput.RegisterListener(self,eventsforwii)
	else
		OPInput.RegisterListener(self,eventsforpc)
	end
end

--TODOà cleaner
function EnableRemotePointerGen( pad, value )
	--[[if OPCore.GetPlatform() == "Wii" then
		OPWii.EnableRemotePointer( pad, value )
	end
	
	if pad == 1 then
		Cursor.Flags_Visible = value
		Cursor.IsActive = value
	end]]
end

--on ne met pas l'unit notify par défaut
--le click n'est bloqué que si on met un utnotify
-- length = -1 signifie que l'on laisse le texte indéfiniment (consigne par exemple)
function DisplaySimpleText(keyword,length,utnotify)
	if length == nil then
		length = DEFAULTDISPLAYTIME
	end

	SubtitlesDisplay.Enabled = true
	SubtitlesDisplay.DisplaySubtitlesForSound(nil,length,keyword,false,utnotify)
end

DEFAULTDISPLAYTIME = 4 --temps d'affichage du text par défaut -> 3s

-- ------------------------------------------------------------------------
--  Get current manager
-- ------------------------------------------------------------------------
function GetCurrentManager()
	ut = OPUnitFactory.GetUnit(GetVariables("currentNavManager"))
	AssertPopup(ut ~= nil, "prob sur le getcurrentmanager")
	return ut
end
