

if r2.Translator == nil
then
	r2.Translator={}
end

local Translator = r2.Translator

Translator.PredatorEnemyFaction = "Player|guard|bandit|herbivore|karavan";

-- Namespace global
function printMsg(str)	
	messageBox(str)	
	debugInfo(colorTag(255,255,0)..str)
	local ucStringMsg = ucstring()
	ucStringMsg:fromUtf8(str)	
	displaySystemInfo(ucStringMsg, "BC")
	messageBox(str)
end

function printError( str)
	local msg = "Translation WRN:"
	debugInfo(colorTag(255,0,0)..msg..str)
--	local ucStringMsg = ucstring()
--	ucStringMsg:fromUtf8(str)
--	displaySystemInfo(ucStringMsg, "BC")
	--messageBox(str)
	assert(nil)
end

r2.Translator.MultilineBc = {}

function Translator.updateEachSecond()
	if table.getn( Translator.MultilineBc ) > 0 then
		local msg=table.remove(Translator.MultilineBc, 1)
		if msg then 
			local ucStringMsg = ucstring()
			ucStringMsg:fromUtf8(msg)	
			displaySystemInfo(ucStringMsg, "BC")
		end
	end
end

function printMsgML(str)
	local strs = r2.split(str, "\n")
	for k,v in pairs(strs) do
		table.insert(Translator.MultilineBc, v)
	end
end
--local devMode = false
local devMode =   config.R2EDExtendedDebug
local dataDevMode = false

function printWarning( str)
	local msg = "Translation Error:"..str
	debugInfo(colorTag(255,0,0)..msg)
	-- msg will be displayed when client is back to edition

 	-- Just report the last error
 	if (r2.LastTranslationErrorMsg  == nil) then
		r2.LastTranslationErrorMsg = str
		local ucStringMsg = ucstring("Translation Error")
		-- ucStringMsg:fromUtf8(r2.LastTranslationErrorMsg)
		displaySystemInfo(ucStringMsg, "BC")
	 	messageBox(str)
	end
	if devMode then
		assert(nil)
	else
		error(str) -- force to exit current translation
	end
end

function BOMB_IF(condition, str)
	if ( not condition) then
		printWarning(str)
	end
end

-- Namespace r2
function r2:getScenarioId()
	local str = r2:getNamespace()
	str = string.gsub(str, "r2_", "")
	str = string.gsub(str, "_", "")
	local  sessionId = tonumber(str)
	return sessionId
end


function r2:getActId(actIn)
	assert(actIn)
	local index = -1
	local actId, act = next(r2.Scenario.Acts)
	while actId do
		index = index + 1
		if (tostring(act.InstanceId) == tostring(actIn.InstanceId)) then return index end
		actId, act = next(r2.Scenario.Acts, actId)

	end
	assert(nil)
	return -1
end


-- Namespace Translator
function Translator.getRtGroup(context, instanceId)
	assert(context.RtAct)
	assert( context ~= nil and type(context)=="table")
	assert( instanceId ~= nil and type(instanceId) == "string")

	if context.RtGroups[instanceId]==nil
	then
		context.RtGroups[instanceId] = r2.newComponent("RtNpcGrp")
		context.RtGroups[instanceId].Name = context.RtGroups[instanceId].Id
		table.insert(context.RtAct.NpcGrps, context.RtGroups[instanceId])
	end
	return context.RtGroups[instanceId]
end

function Translator.getRtStatesNames(context, instanceId)
	local rtNpcGrp = Translator.getRtGroup(context, instanceId)

	local statesNames = context.GroupStatesName[rtNpcGrp.Name]
	return statesNames
end

r2.doTranslateFeatures = function(scenario)
	return Translator.doTranslateFeatures(scenario.InstanceId)
end

r2.translateFeature = function(context)
	local component = context.Feature
	if (component == nil)  then return end

	if component.translate ~= nil then
		component:translate(context)
	end
end


r2.translateFeatures = function(scenario)

	local rtScenario = r2.doTranslateFeatures(scenario)
	r2.requestUpdateRtScenario(rtScenario)
end



-- creat a context (mainly RtComponent)
Translator.createContext = function(scenario)
	local context = {}
	context.Scenario = scenario
	context.RtScenario = r2.newComponent("RtScenario")
	context.TextTranslateId={}
	context.Feature=scenario -- obsloete to remove
	context.GroupStatesName = {}
	context.GroupTriggeredActions = {}
	context.Events = {}
	context.ActivityStates = {}
	context.RtGrps={}
	context.RtGroups={}
	context.CounterNames={}
	context.RtCounters = {}
	--context.EasterEggUniqId = {} -- RtGrpId to uniqId
	context.ActIdToRtAct  = {}
	context.InteractingSceneryObjects = {}
	return context
end

-- return the equipment of a rtNpc by looking at the visual properties of an hlNpc
Translator.translateEquipment = function(hlNpc)
	local instanceId = hlNpc.InstanceId
	local equipment = ""
	local instance = r2:getInstanceFromId(instanceId)

	if instance:isKindOf("NpcCustom") then
		equipment = equipment..r2.getVisualPropertiesFromInstanceId(instanceId);
	end

	if equipment == nil then
		equipment = ""
	end

	local isFauna = hlNpc.IsFauna
	if isFauna ~= nil and isFauna == 1 then
		-- Npc with default name use default translation system name
		local basename = hlNpc.Base
		if basename then basename = r2.PaletteIdToTranslation[ basename ] end
		if basename == nil or basename ~= hlNpc.Name  then
			equipment = equipment .. "FAUNA_BOT_USE_BOTNAME\n"
		end
	end
	return equipment
end

-- get an rtNpc aiActivity from an hlNpc eg "civil" -> "normal"
Translator.getAiActivity = function(hlNpc)
	assert(hlNpc and type(hlNpc) == "userdata")
	local aiActivity = hlNpc.AiActivity
	local profile =  hlNpc.Profile
	local str = "no_change"

	if profile then return "" end

	if profile  ~= nil then
		if profile == "bandit" then str = "bandit" end
		if profile == "guard"  then str = "guard" end
		if profile == "civil"  then str = "normal" end
	elseif aiActivity  ~= nil then
		str = aiActivity
	end

	return str;
end

--  get rtNpc from hlNpc
Translator.translateNpc = function(hlNpc, context)

	local function findInTable(instanceId)
		for k, v in pairs(context.InteractingSceneryObjects) do
			if v == instanceId then return true end
		end
		return false
	end
	
	
	assert(hlNpc and type(hlNpc) == "userdata")
	local RtNpc = r2.newComponent("RtNpc")
	

	RtNpc.Name = hlNpc.Name
	
	
	RtNpc.SheetClient = hlNpc.SheetClient
	
	
	RtNpc.Sheet = hlNpc.Sheet
	if RtNpc.Sheet == nil then RtNpc.Sheet = "" end

	

	if hlNpc:isBotObject() and context and context.InteractingSceneryObjects
		and findInTable(hlNpc.InstanceId) then
			RtNpc.IsStuck = 0
			RtNpc.Sheet = "object_chest_wisdom_std_sel.creature"
	else
		RtNpc.IsStuck = hlNpc.IsStuck
	end

	RtNpc.Pt = r2.getWorldPos(hlNpc)
	RtNpc.Angle = hlNpc.Angle
	RtNpc.Equipment = Translator.translateEquipment(hlNpc)

	local animProp = 0
	if not hlNpc:getParentAct():isBaseAct() then
		animProp = animProp + 1 -- TODO test if default feature
	end

	if hlNpc.IsBotObject ~= 1 then
		animProp = animProp + 2 -- Living Creature
	end

	if hlNpc.IsBotObject ~= 1 and hlNpc.IsPlant ~= 1 then
		animProp = animProp + 4 -- Controlable creature
	end

	if hlNpc.IsBotObject ~= 1 and hlNpc.IsNpc == 1 then
		animProp = animProp + 8 -- Creature that talk
	end
	RtNpc.DmProperty = animProp
	return RtNpc
end

-- Behavior: the behavior of the npc (or the leader of an group)
-- translate the activitySequences of an npc/group
Translator.translateActivities = function (context, hlComponent, behavior, rtNpcGrp, aiActivity)

	assert(context)
	assert(hlComponent)
	assert(behavior)
	assert(rtNpcGrp)
	assert(aiActivity)

	local initFun = Logic.initGroupActivitiesTranslation
	local translateActivitySequence = Logic.translateActivitySequence
	--all the states names of all the sequences of this group
	local statesNames=""
	local first = true
	--for each group's activity
	local activityIndex = 1

	local firstState =""
	--creation of the group's initial state

	local leader = hlComponent
	if hlComponent:isKindOf("NpcGrpFeature") then
		if table.getn(hlComponent.Components) >= 0 then
			leader = hlComponent.Components[0]
		else
			leader = nil
		end
	end

	if table.getn(behavior.Activities) == 0 then


	

		-- create initial and only state
		local aiState = r2.newComponent("RtAiState")
		statesNames = aiState.Id
		r2.Utils.setState(context, behavior, aiState)
		aiState.Name = hlComponent.InstanceId..".init"
		aiState.AiActivity = aiActivity
		table.insert(context.RtAct.AiStates, aiState)
		table.insert(aiState.Children, rtNpcGrp.Id)
		firstState = aiState.Id
	

	else

		local k, v  = next(behavior.Activities, nil)
		while k do
		
			if (v.Class == "ActivitySequence") then
				initFun(context, hlComponent, v, first, activityIndex, aiActivity, rtNpcGrp)

				if first then
					firstState = Logic.StatesByName
				end
				--translate the activity
	 			translateActivitySequence(context, hlComponent, v, activityIndex, rtNpcGrp)
				statesNames = statesNames..Logic.StatesByName.."\n"
				activityIndex = activityIndex + 1
				first = false
			else
				error("Error while translating '" .. hlComponent.Name .. "' its  " .. tostring(nbActivity) .." ActiviySequence  contains an element of type " .. v.Class)
			end
			k, v = next(behavior.Activities, k)
	
		end
	end


	if leader and not leader:isBotObject() then
		local category = leader.SubCategory
		local aggro = leader.Aggro
		if not category then 
			category = leader.Category
		end

		if category then
			local event = r2.Translator.createEvent("start_of_state", firstState, rtNpcGrp.Id)
			table.insert(context.RtAct.Events, event)
			local action = r2.Translator.createAction("bot_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, leader.PlayerAttackable)
			table.insert(context.RtAct.Actions, action)
			table.insert(event.ActionsId, action.Id)				
		end
	end

	context.GroupStatesName[rtNpcGrp.Name] = statesNames

end



function Translator.initializeFactions(context, leader, rtGrp, aiStateName )
	if leader and not leader:isBotObject() then
		local category = leader.SubCategory
		local aggro = leader.Aggro
		if not category then 
			category = leader.Category
		end

		if category then
			local event = r2.Translator.createEvent("start_of_state", aiStateName, rtGrp.Id)
			table.insert(context.RtAct.Events, event)
			local action = r2.Translator.createAction("faction_init", rtGrp.Id, category, aggro, leader.BotAttackable, leader.PlayerAttackable)
			table.insert(context.RtAct.Actions, action)
			table.insert(event.ActionsId, action.Id)				
		end
	end
end

-- translate an eventHandler defined in the behavior of an npc / group
-- used to implement translateEventHandlers
Translator.translateEventHandler = function(context, hlNpc, eventHandler, rtNpcGrp)

	local getName = function(object, optionalName)
		if optionalName and object.optionalName then return "'"..object.optionalName.."'" end
		if object.Name then return "'"..object.Name.."'" end
		if object.InstanceId then return "("..object.InstanceId..")" end
		return "??"
	end

	local event = nil
	local firstCondition = nil
	local lastCondition = nil

	local target = nil


	target = hlNpc

	if not target then
		printWarning("Error in component '" .. eventHandler.Name.."'")
	end

	if tostring(eventHandler.Event.Type) == "" then return nil end

	if not target.getLogicEvent then
		local eventName =  eventHandler.Name
		printWarning("The component '" .. target.Name .. "' seem to not be able to handle events '")

	end

	event, firstCondition, lastCondition = target.getLogicEvent(target, context, eventHandler)


	if  not event	then
		printWarning("Error in '"..  target.Name.. "' the Event Handler '".. eventHandler:getName() .. "' don't seem to work because the event '"..eventHandler.Event.Type.."' don't seem to be implemented." )

	end



	local kCondition, condition = next(eventHandler.Conditions, nil)
	while kCondition do


		local conditionEntity = r2:getInstanceFromId(condition.Entity)
		if condition.Condition.Type ~= "" and conditionEntity then
			assert(conditionEntity)
			local firstCondition2, lastCondition2 = conditionEntity:getLogicCondition(context, condition)

			if not firstCondition2 or not lastCondition2 then
				printWarning("Unknown Condition '".. condition.Condition.Type .. "' in EventHandler ".. eventHandler:getName().." in component " .. getName(target))
				return nil
			end

	
	
			if not firstCondition then
				firstCondition = firstCondition2
				lastCondition = lastCondition2
			else
				table.insert(lastCondition.Children, firstCondition2)	
				lastCondition = lastCondition2
			end
		end

		kCondition, condition = next(eventHandler.Conditions, kCondition)
	end


	local firstAction = nil
	local lastAction = nil

	if eventHandler.Actions.Size > 0 then

		local multiAction = nil
		if eventHandler.Actions.Size > 1 then
			multiAction = Translator.createAction("multi_actions")
		end

		local kAction, action = next(eventHandler.Actions, nil)
		while kAction do
			local actionEntity = r2:getInstanceFromId(action.Entity)

			if action.Action.Type ~= "" and actionEntity then
				local firstAction2, lastAction2 = actionEntity:getLogicAction(context, action)

				if not firstAction2 or not lastAction2 then
					printWarning("Unknown Action '".. action.Action.Type .. "' in EventHandler ".. eventHandler:getName().." in component " .. getName(target))
				end

				if multiAction then
					table.insert(multiAction.Children, firstAction2)
				else
					firstAction = firstAction2
				end
			end

			kAction, action = next(eventHandler.Actions, kAction)
		end

		if eventHandler.Actions.Size > 1 then
			firstAction = multiAction
		end
	end

	-- if there is actions then the first executed npc_event_handler_action are the dynamic_if from  [firstCondition, lastCondition]
	if lastCondition then
		table.insert(lastCondition.Children, firstAction)
		firstAction = firstCondition
	end

	if event and firstAction then

		local actInstanceId = eventHandler:getLogicActInstanceId()
		
		if (tostring(actInstanceId) == "") then
			debugInfo("Invalid Multi act action:"..eventHandler:getName())
			return
		end


		
		local rtAct2 = context.ActIdToRtAct[actInstanceId]
		local rtAct = context.RtAct
		if rtAct2 ~= rtAct then
			local baseAct = context.Scenario:getBaseAct()
			local index = context.Scenario:getActIndex(actInstanceId)
			if index == -1 then
				printWarning("Invalid Scenario")
			end
			local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
			
			local action = Translator.createAction("test_act", rtNpcGrpBase.Id , index)
			table.insert(action.Children, firstAction)
			firstAction = action
		end

		-- insert a npc_event_handler
		table.insert(rtAct.Events, event) -- TODO use eventHandler->

		-- insert a npc_event_handler_action
		table.insert(event.ActionsId, firstAction.Id)
		table.insert(rtAct.Actions, firstAction)
	end
end


-- translates eventHandlers of a npc/group (eventHandlers are defined in beahvior)
Translator.translateEventHandlers = function(context, hlNpc, eventHandlers, rtNpcGrp)
	assert(rtNpcGrp)
	assert(context)
	if (eventHandlers ~= nil) then
		local k, v = next (eventHandlers, nil)
		while k do
			local caller = nil
			if devMode then
				caller = function (...) arg[1](arg[2], arg[3], arg[4], arg[5]) return true end
		
			else
				caller = pcall			
			end
			if not caller(Translator.translateEventHandler, context, hlNpc, v, rtNpcGrp) then
				local eventType = v.Event.Type
				if eventType == nil then eventType = "" end
				local componentName = hlNpc.Name
				if componentName == nil then componentName = "" end
				printWarning("Error in event handler '"..eventType.."' In component "..componentName)
			end
			k, v = next (eventHandlers, k)
		end	
	end
end





-- translate a scenario
-- scenarioInstanceId the instanceId of the scenario that will be translated to rtData
-- returns rtScenario or nil
Translator.doTranslateFeatures = function(scenarioInstanceId)
	local ok
	local result

	r2.LastTranslationErrorMsg = nil
	ok, result = pcall(Translator.doTranslateFeaturesProtected, scenarioInstanceId)
	if not ok then
		printWarning(result)
	end

	return result
end

function Translator.initStartingActIndex(startingAct)
	local startingAct = r2.Scenario.User.SelectedActInstanceId
	
	local acts = r2.Scenario.Acts


	local actId, act = next(acts, nil)
	local actIndex = 0
	while (actId ~= nil)
	do
		if startingAct and tostring(act.InstanceId) == startingAct then
			r2.setStartingActIndex(actIndex )
		else 
			r2.setStartingActIndex(1)
		end
		actIndex = actIndex + 1
		actId, act = next(acts, actId)
	end
end
Translator.doTranslateFeaturesProtected = function(scenarioInstanceId)
	local scenario = r2:getInstanceFromId(scenarioInstanceId)
	assert(scenario) -- something is broken elsewhere
	assert( r2.Features ~= nil )
	local acts = scenario.Acts
	local context = Translator.createContext(scenario)
	local cost = 0
	local rtScenario = context.RtScenario
	-----------------------------
	--elements counting
	local maxSecondaryActCost = 0
	local baseActCost = 0
	local first=true



	--
	-- Recursive method that call a specific function (ie createGhostComponent, pretranslate) on a component
	-- and every components it contains. Each component level is treated, so that the function needs to be called
	-- only once on the toplevel feature.
	--
	local function recursiveFunctionCall(f,components, param)
		if (components == nil) then
			return
		end
		local k, v = next(components, nil)
		while k do
			if v[f] then
				v[f](v, param)		
			end
			if v.Components then
				recursiveFunctionCall(f, v.Components, param)
			end
			if v.SubComponents then
				recursiveFunctionCall(f, v.SubComponents, param)
			end
	
			k, v = next(components, k)
		end
	end

	local function recursiveTranslate(components, context)
		if (components == nil) then
			return
		end
		local k, v = next(components, nil)
		while k do
			context.Feature= v
			r2.translateFeature(context)
			if v.Components then
				recursiveTranslate(v.Components, context)
			end
			if v.SubComponents then
				recursiveTranslate(v.SubComponents, context)
			end
			k, v = next(components, k)
		end
	end

	local function recursivePretranslate2(components, context)
		if (components == nil) then
			return
		end
		local k, v = next(components, nil)
		while k do
			context.Feature= v
			if v.pretranslate2 then v.pretranslate2(v, context) end

			if v.Components then
				recursivePretranslate2(v.Components, context)
			end
			if v.SubComponents then
				recursivePretranslate2(v.SubComponents, context)
			end
			k, v = next(components, k)
		end
	end


	-- Management of items (Copy from Edition Data to Rt Data)
	do
		local plotItemId, plotItem = next(scenario.PlotItems, nil)
		while plotItemId do

			assert(type(plotItem.SheetId) == "number")
			assert(type(plotItem.Name) == "string")
			assert(type(plotItem.Desc) == "string")
			assert(type(plotItem.Comment) == "string")

			assert(string.len(plotItem.Name) < 256)
			assert(string.len(plotItem.Desc) < 256)
			assert(string.len(plotItem.Comment) < 256)

			local rtPlotItem = r2.newComponent("RtPlotItem")
			rtPlotItem.SheetId = plotItem.SheetId
			
			rtPlotItem.Description = plotItem.Desc
			
			rtPlotItem.Name = plotItem.Name
			rtPlotItem.Comment = plotItem.Comment
			table.insert(rtScenario.PlotItems, rtPlotItem)
			plotItemId, plotItem = next(scenario.PlotItems, plotItemId)
		end

	end


	-- ghost
	do
		local actId, act = next(acts, nil)
		while (actId ~= nil) do	
			local features = act.Features
			recursiveFunctionCall("createGhostComponents", features, act)		

			actId, act = next(acts, actId)
		end
	end

	-- pre Translation
	do

		local actId, act = next(acts, nil)
		while (actId ~= nil) do

			local rtAct = r2.newComponent("RtAct")	
			if act.WeatherValue ~=nil and act.ManualWeather == 1 then
				rtAct.WeatherValue = 1 + act.WeatherValue
			else
				rtAct.WeatherValue = 0
			end
			rtAct.ActDescription = ""
			rtAct.PreActDescription = ""

			if act.ShortDescription then
				rtAct.ActDescription =  act.ShortDescription
			end
			if act.PreActDescription then
				rtAct.PreActDescription = act.PreActDescription
			end
			
	
			context.RtAct = rtAct

			context.ActIdToRtAct[act.InstanceId] = rtAct

			context.Act = act
			context.RtAct = rtAct
			local features = act.Features

			act:pretranslate(context)
			recursiveFunctionCall("pretranslate", features, context)

	

			actId, act = next(acts, actId)
		end
	end

	-----------------------------
	--texts translation
	context.Feature = scenario.Texts
	r2.Features["TextManager"].Translator(context)

	--for each act

	local actId, act = next(acts, nil)
	while (actId ~= nil) do
		cost= 0
		-- debugInfo("Act:: "..act.InstanceId)

		local rtAct = context.ActIdToRtAct[act.InstanceId]
		context.RtAct = rtAct
		context.Act = act
		table.insert(rtScenario.Acts, rtAct)


		local activitiesIds = act:getActivitiesIds()
		--creating states for all the activities of all the groups in this act
		local k, v = next(activitiesIds, nil)
		while k do
			local sequence = r2:getInstanceFromId(v)
			if sequence and sequence.Components
			then
				Logic.createActivityStates(context, sequence)
			end
			k, v = next(activitiesIds, k)
		end

		actId, act = next(acts, actId)
	end

	-- translate activities
	do

		local actId, act = next(acts, nil)
		while (actId ~= nil) do
			local rtAct = context.ActIdToRtAct[act.InstanceId]
			context.RtAct = rtAct
			context.Act = act
		
			local features = act.Features
			recursivePretranslate2(features, context)

	
			actId, act = next(acts, actId)
		end
	end

 	local first = true
	
	actId, act = next(acts, nil)
	while (actId ~= nil) do
		local rtAct = context.ActIdToRtAct[act.InstanceId]
		context.RtAct = rtAct
		context.Act = act

		
		local features = act.Features


		assert(features ~= nil or actId == "Keys")

		recursiveTranslate(features, context)

		context.Feature = act
		act:translate(context);
		-- scenario
		if first then
			first = false
			context.Feature = scenario
			scenario:translate(context);
		end

		actId, act = next(acts, actId)
	end




	-- Location Id
	local locationId, location = next(scenario.Locations)
	local locationIndex = 0
	local locationMap = {}

	locationMap[""] = 0

	while locationId do
		local rtLocation =r2.newComponent("RtLocation")
		rtLocation.Island = location.IslandName
		rtLocation.EntryPoint = location.EntryPoint
		local  enumToInt = {Automatic=0, Spring=1, Summer=2, Autumn=3, Winter=4}
		rtLocation.Season = enumToInt[ location.Season ]
		locationMap[location.InstanceId] = locationIndex

		table.insert(rtScenario.Locations, rtLocation)
		locationIndex = locationIndex + 1
		locationId, location = next(scenario.Locations, locationId)
	end

	local startingAct = r2.Scenario.User.SelectedActInstanceId


	-- Act Name, position
	local actId, act = next(acts, nil)
	local actIndex = 0
	while (actId ~= nil)
	do

		local rtAct = context.ActIdToRtAct[act.InstanceId]
		rtAct.Name = act.Name

		rtAct.LocationId = locationMap[ act.LocationId ]

		if startingAct and tostring(act.InstanceId) == startingAct then
			r2.setStartingActIndex(actIndex )
		else 
			r2.setStartingActIndex(1)
		end
		actIndex = actIndex + 1
		actId, act = next(acts, actId)
	end
	-- Ring accss
	if ( r2.getMustVerifyRingAccessWhileLoadingAnimation()) then
		do
			local ok, level, err = r2.RingAccess.verifyScenario()
			r2.updateScenarioAck(ok, level, err.What)
		end

		local ok, err = r2.RingAccess.verifyRtScenario(rtScenario)
		if not ok then
			printWarning(err.What)
		end
	end
	
--	inspect(rtScenario)
	return rtScenario
end

-- Returns a RtNpcEventHandlerAction if the action is allowed
--first parameter: action type
Translator.createAction = function(...)
	local debug=config.R2EDExtendedDebug
	local function header(toto)

		if debug then
			return "print(\"<"..toto..">\");\n"
		end
		return "//"..toto
	end

	local function footer(toto)

		if debug then
			return "print(\"</"..toto..">\");\n"
		end
		return ""
	end


	local action = r2.newComponent("RtNpcEventHandlerAction")
	local actionType = arg[1]
	action.Action = actionType
	action.Name = actionType

	if actionType == "test_act" then
		assert(type(arg[2])=="string")
		assert(type(arg[3])=="number")
		local rtGrpId = arg[2] -- scenario
		local actId = arg[3] -- actId

		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		
		action.Action = "dynamic_if"
		action.Parameters = prefix.."CurrentAct == "..tostring(actId)
		return action
	end

	if actionType == "wander_destination_reached" then
		assert(type(arg[2])=="string")
		assert(type(arg[3])=="string")
		assert(type(arg[4])=="number")
		assert(type(arg[5])=="number")

		local rtGrpId = arg[2] 
		local states = arg[3]  
		local nextStep = arg[4]  
		local time =  arg[5]  

		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		
		action.Action = "code"

		action.Parameters = 
			"v2 = ".. nextStep..";\n" ..
			"()setTimer("..1+ 10*time..", 0);\n"
		

		return action
	end
	if actionType == "next_road" then
		assert(type(arg[2])=="string")
		assert(type(arg[3])=="string")
		assert(type(arg[4])=="number")
		assert(type(arg[5])=="string")

		action.Action = "code"

		local paramCount = tonumber(arg[5])
		if paramCount == nil then
			paramCount = "0"
		end
		paramCount = tostring(paramCount)

		action.Parameters =
[[//next_road
if (  ParamRepeatCount == 0  || ParamGroup.RoadCountLimit < ParamRepeatCount - 1) {
	if ( ParamRepeatCount != 0) { ParamGroup.RoadCountLimit = ParamGroup.RoadCountLimit + 1; }
	()ParamGroup.postNextState("ParamState");
} else {
	ParamGroup.RoadCountLimit = 0;
	ParamGroup.v2 = ParamActivityIndex;
	()ParamGroup.setTimer(1, 0);
}

]]
		action.Parameters = string.gsub(action.Parameters, "ParamGroup", r2:getNamespace() .. tostring(arg[2]))
		action.Parameters = string.gsub(action.Parameters, "ParamState",  r2:getNamespace() .. tostring(arg[3]))
		action.Parameters = string.gsub(action.Parameters, "ParamActivityIndex", tostring(arg[4]))
		action.Parameters = string.gsub(action.Parameters, "ParamRepeatCount", paramCount)

			

		return action
	end


	if actionType == "trigger_zone_min_player" then
		assert(type(arg[2])=="string")
		assert(type(arg[3])=="string")
		assert(type(arg[4])=="number")
		local rtGrpId = arg[2] 
		local states = arg[3]  
		local nbMinPlayer = arg[4]


		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		
		action.Action = "dynamic_if"
		if nbMinPlayer == 0 then
			action.Parameters = prefix.."Active == 1 && "..prefix.."NbPlayer == 0"
		else
			action.Parameters = prefix.."Active == 1 && "..prefix.."NbPlayer >= "..tostring(nbMinPlayer)
		end

		return action
	end


	if actionType == "on_player_arrived_impl" then
		assert(arg[2])

		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end


			action.Parameters = header(actionType)..
			"if ( "..prefix.."Active == 1 )\n{\n"..
			"\tif ( "..prefix.."Cyclic == 1 )\n"..
			"\t{\n"..
				"\t\t"..prefix.."Enter = 0 ;\n" ..
				"\t\t()"..prefix.."setEvent(1);\n" ..
			"\t}\n"..
			"\telse if ( "..prefix.."Enter == 1 )\n"..
			"\t{\n"..
				"\t\t"..prefix.."Enter = 0;\n"..
				"\t\t".."()"..prefix.."setEvent(1);\n" ..		
			"\t}\n" ..
			"}\n"..
			 footer(actionType)

		action.Action = "code"
		return action
	end

	if actionType == "on_player_left_impl" then
		assert(arg[2])

		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end


			action.Parameters = header(actionType)..
			"if ( "..prefix.."Active == 1 )\n{\n"..
			"\tif ( "..prefix.."Cyclic == 1 )\n"..
			"\t{\n"..
				"\t\t"..prefix.."Leave = 0 ;\n" ..
				"\t\t()"..prefix.."setEvent(2);\n" ..
			"\t}\n"..
			"\telse if ( "..prefix.."Leave == 1 )\n"..
			"\t{\n"..
				"\t\t"..prefix.."Leave = 0;\n"..
				"\t\t".."()"..prefix.."setEvent(2);\n" ..		
			"\t}\n" ..
			"}"
			 ..footer(actionType)

		action.Action = "code"
		return action
	end
	if actionType == "trigger_zone_init" then
		assert(arg[2])
		assert(arg[3])
		assert(arg[4])
		local rtGrpId = arg[2]
		local auto = arg[3]
		local cyclic = arg[4]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end


		action.Parameters = header(actionType)..
		"\t"..prefix.."Active = ".. auto .." ;\n" ..
		"\t"..prefix.."Leave = ".. auto .." ;\n" ..
		"\t"..prefix.."Enter = ".. auto .." ;\n" ..
		"\t"..prefix.."Cyclic = "..tostring(cyclic).." ;\n" ..
		"if ("..prefix.."Active == 1)\n"..
		"{\n"..
		"\t()"..prefix.."setEvent(4);\n" ..
		"}\n"..
		 footer(actionType)

		action.Action = "code"
		return action
	end

	if actionType == "trigger_zone_activates" then
		assert(arg[2])

		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		
		action.Parameters = header(actionType)..
		"if (" ..prefix.."Active == 1)\n"..
		"{"..
		"\t ()" ..prefix.."setEvent(4);\n"..
		"}\n"..
		"else\n"..
		"{\n"..
		"\t"..prefix.."Active = 1 ;\n" ..
		"\t"..prefix.."Leave = 1 ;\n" ..
		"\t"..prefix.."Enter = 1 ;\n" ..
		"()"..prefix.."setEvent(4);\n" ..
		"}\n"..
		footer(actionType)

		action.Action = "code"
		return action
	end

	if actionType == "trigger_zone_deactivates" then
		assert(arg[2])

		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end


		action.Parameters = header(actionType)..
		"\t"..prefix.."Active = 0 ;\n" ..
		"\t"..prefix.."Leave = 0;\n" ..
		"\t"..prefix.."Enter = 0;\n" ..
		"()"..prefix.."setEvent(5);\n" ..
		footer(actionType)

		action.Action = "code"
		return action
	end

	if actionType == "act_starts" then
		assert(arg[2])
		assert(arg[3])
		assert( type(arg[4]) == "number")

		local rtGrpId = arg[2]
	 	local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end


		local rtGrpId2 = arg[3]
		local prefix2=""
		if rtGrpId2 and rtGrpId2 ~= "" then
			prefix2 = r2:getNamespace() .. rtGrpId2.."."
		end


		action.Parameters = header(actionType)..
			"()"..prefix.."setTimer(50,0);\n" .. -- act start in 1 second
			prefix2.."CurrentAct = " .. tostring( arg[4] ) .. ";\n" ..
			"if ( "..prefix2.."v0 == 0 )\n"  .. 
			"{\n"..
				"\t()"..prefix2.."setTimer(50,0);\n"..
				"\t"..prefix2.."v0 = 0;\n"..
				"\t()"..prefix2.."setTimer(150, 1);\n"..
				"\t"..prefix2.."ScenarioPoints = 0;\n"..
			"}\n"..
			
			 footer(actionType)

		action.Action = "code"
		return action
	end
	
	if actionType == "random_chest_activate" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		local eggId =tostring( tonumber(arg[3]))
		local actId =tostring( tonumber(arg[4]))
		local x = tostring(tonumber(arg[5]))
		local y = tostring(tonumber(arg[6]))
		local z = tostring(tonumber(arg[7]))
		local scenario = tostring( r2:getScenarioId())

		local item1Weight	= arg[8]
		local item1Id		= arg[9]
		local item1Qty		= arg[10]
		local item1Str		= ""
		if item1Id and item1Id ~= "" then
			item1Str		= tostring(item1Id)..":"..tostring(item1Qty)
		end

		local item2Weight	= arg[11]
		local item2Id		= arg[12]
		local item2Qty		= arg[13]
		local item2Str		= ""
		if item2Id and item2Id ~= "" then
			item2Str		= tostring(item2Id)..":"..tostring(item2Qty)
		end

		local item3Weight	= arg[14]
		local item3Id		= arg[15]
		local item3Qty		= arg[16]
		local item3Str		= ""
		if item3Id and item3Id ~= "" then
			item3Str		= tostring(item3Id)..":"..tostring(item3Qty)
		end

		local name = arg[17]

		local sum12			= tostring(item1Weight + item2Weight)
		local sum123			= tostring(item1Weight + item2Weight + item3Weight)

		action.Parameters = "//random_chest_activate\n"
			.."(" ..prefix.."r)rndm(0,100);\n"
			.."if (" ..prefix.. "r > 0 && "..prefix.."r <= "..tostring(item1Weight)..")\n"
			.."{\n\t"
			.."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item1Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
			.."}\n"
			.."if (" ..prefix.. "r > "..item1Weight.." && "..prefix.."r <= "..sum12..")\n"
			.."{\n\t"
			.."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item2Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
			.."}\n"
			.."if (" ..prefix.. "r > "..sum12.." && "..prefix.."r <= "..sum123..")\n"
			.."{\n\t"
			.."()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. item3Str.. "\", " .. x.. ", " .. y.. ", " .. z .. ", 0, \""..r2:getNamespace() .. rtGrpId.."\", \""..name.."\", \"\");\n"
			.."}\n"
			.."()"..prefix.."setEvent(4);\n"
		action.Action = "code"
		return action
	end



	if actionType == "easter_egg_activate" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local eggId =tostring( tonumber(arg[3]))
		local actId =tostring( tonumber(arg[4]))

		local items = tostring(arg[5])
		local x = tostring(tonumber(arg[6]))
		local y = tostring(tonumber(arg[7]))
		local z = tostring(tonumber(arg[8]))
		local heading = tostring(tonumber(arg[9]))
		local name = tostring(arg[10])
		if not name then name = "" end
		local look = arg[11]
		if not look then look = "" end
		local scenario =tostring( r2:getScenarioId())



		assert(eggId and scenario and items and x and y and z)
		if not heading then heading = tostring(0) end

		action.Parameters = "//"..actionType.."\n" ..
			"()"..prefix.."activateEasterEgg(" .. eggId .. ", " .. scenario .."," .. actId .. ", \"" .. items.. "\", " .. x.. ", " .. y.. ", " .. z .. "," .. heading .. ", \""..r2:getNamespace() .. rtGrpId.."\", \"".. name .."\", \"".. look .."\");\n"..
			"()"..prefix.."setEvent(4);\n"
		action.Action = "code"
		return action
	end

	if actionType == "easter_egg_deactivate" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local eggId =tostring( tonumber(arg[3]))
		local actId =tostring( tonumber(arg[4]))
		local scenario =tostring( r2:getScenarioId())
		assert(eggId and scenario)
		
		action.Parameters = "//"..actionType.."\n" ..
			"()"..prefix.."deactivateEasterEgg(" .. eggId .. ", " .. scenario.. "," .. actId..");\n"..
			"()"..prefix.."setEvent(5);\n"


		action.Action = "code"
		return action
	end

	if actionType == "dialog_starts" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		action.Parameters=
			"//"..actionType.."\n" ..
			""..prefix.."start=1;\n"  ..
			""..prefix.."v1=0;\n"  .. -- intial time before start of dialog is kind of long because we don't want in a start of state that the targeted npc don't exist
			"()"..prefix.."setTimer(10, ".. Logic.chatTimerId ..");\n" ..
			"()"..prefix.."setEvent(1);" .. "\t//start of dialog\n"

		action.Action = "code"
		return action
	end

	if actionType == "dialog_continues" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		action.Parameters=
			"//"..actionType.."\n" ..
			"if ("..prefix.."break == 1) {\n"  ..
			"\t()"..prefix.."setTimer(1, ".. Logic.chatTimerId ..");\n" ..
			"}\n"

		action.Action = "code"
		return action
	end


	if actionType == "chat_starts" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		assert(type(arg[3]) == "number")
		local index = tonumber(arg[3])
		action.Parameters=
			"//"..actionType.."\n" ..
			""..prefix.."start=1;\n"  ..
			""..prefix.."v1=".. tostring(index+1)..";\n"  ..
			"()"..prefix.."setTimer(1, ".. Logic.chatTimerId ..");\n"

		action.Action = "code"
		return action
	end


	if actionType == "dialog_stops" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		action.Parameters=
			"//"..actionType.."\n" ..
			""..prefix.."start=0;\n"  ..
			"()"..prefix.."setEvent(2);" .. "\t//end of dialog\n"

		action.Action = "code"
		return action
	end

	if actionType == "dialog_deactivate" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() ..rtGrpId.."."
		end
		action.Parameters = prefix.."start = 0;\n"
			..prefix.."Active = 0;\n"

		action.Action = "code"
		return action
	end

	if actionType == "dialog_init" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local mustRepeat = tonumber(arg[3])
		local autoStart = tonumber(arg[4])
		assert(mustRepeat)

		action.Parameters=
			"//"..actionType.."\n" ..
			""..prefix.."repeat=".. mustRepeat..";\n"..
			""..prefix.."AutoStart=".. autoStart..";\n"
			--.."()"..prefix.."setEvent(5); // spawned\n"

		action.Action = "code"
		return action
	end



	if actionType == "chat_step_first" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local initialWait = tonumber(arg[3])
		assert(initialWait)
		action.Parameters =
			"//"..actionType.."\n" ..
			prefix .. Logic.chatStepVar .. " = 1;\n" ..
			"()"..prefix.."setTimer("..tostring(initialWait*10+1) ..", ".. Logic.chatTimerId ..");\n" ..
			"()"..prefix.."setEvent(3);" .. "\t//start of chat\n"

		action.Action = "code"
		return action
	end



	if actionType == "chat_step_last" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId .. "."
		end
		local nbParam = arg[3]
		assert(nbParam and type(nbParam) == "number")

		action.Parameters =
			"//"..actionType.."\n" ..
			prefix..Logic.chatStepVar .. "="..tostring(1+nbParam)..";\n"  .. --set because of setEvent
			"()"..prefix.."setEvent(4);\n" ..
			"if ("..prefix.."repeat == 1) {\n" ..
			"\t"..prefix.."start=1;\n"  ..
			"\t"..prefix..Logic.chatStepVar .. "=0;\n"  ..
			"\t()"..prefix.."setTimer(4, ".. Logic.chatTimerId ..");\n"..
			"\t()"..prefix.."setEvent(2);" .. "\t//end of dialog\n" ..
			"\t()"..prefix.."setEvent(1);" .. "\t//start of dialog\n" ..
			"} else {\n" ..
			"\t"..prefix.."start=0;\n"  ..
			"\t()"..prefix.."setEvent(2);" ..  "\t//end of dialog\n" ..
			"}\n"

		action.Action = "code"
		return action
	end

	if actionType == "chat_step" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local param = arg[3]
		assert(type(param) == "table")


		--local m_action = action
		--m_action.Action = "multi_actions"

		local say =""
		local emote=""
		local facing=""

		local startChat = "()"..prefix.."setTimer(2, 0);\n \n" -- timer 0.4 in on seconde
		-- create facing action
		if param.Facing ~= "" and param.Facing ~= nil and param.Who ~=nil
		then
			facing = "//facing\n" ..
				"(@group1)"..r2:getNamespace()..param.WhoGrp..".context();\n"
				.. "(@group2)"..r2:getNamespace()..param.FacingGrp..".context();\n"
				.. "()"..r2:getNamespace()..rtGrpId..".facing(@group1,\""..param.Who.."\", @group2, \"".. param.Facing.."\");\n \n"
			startChat = "()"..prefix.."setTimer(10, 0);\n \n" -- timer 0.4 in on seconde

		end


		local mustBreak = prefix.."break = "..tostring(param.Break)..";\n" 
		if  param.Break == 0 then
			mustBreak = mustBreak..
				"()"..prefix.."setTimer(" .. tostring(4+10*tonumber(param.Time)).. ", ".. Logic.chatTimerId ..");\n\n"
		else
			mustBreak = mustBreak .."\n"
		end

		do
		--	local action = r2.newComponent("RtNpcEventHandlerAction")
			action.Action = "code"
			action.Parameters =
				"//"..actionType.." - ChatStep ".. tostring(param.Index).." \n" ..
				prefix.."step = " .. tostring(param.Index) ..";\n \n"..
				say..facing..emote..

				"//set next chat step\n" ..
				mustBreak ..
				prefix .. Logic.chatStepVar .. " =  " .. param.Index .. " + 1;\n \n" ..

				startChat..	
				"()"..prefix.."setTimer(25, 2);\n \n".. -- timer 0.9 in on seconde
				"//End of dialog\n"..
				"()"..prefix.."setEvent(4);\n \n"
		--	table.insert(m_action.Children, action)
		end



		return action

	end


	if actionType == "chat_step_end" then

		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local param = arg[3]
		assert(type(param) == "table")

		local baseActRtGrpId = arg[4]
		assert(type(baseActRtGrpId) == "string")

		if (table.getn(param.Emotes) == 0) then	return nil end


		local code =
		"// lauch emote at end of chat step\n \n" ..
		"if ("..prefix.."start == 1)\n" ..
		"{\n"..
		"\tswitch ( ".. prefix.."step )\n"..
		"\t{\n"

		local i = 0
		local n = table.getn(param.Emotes)
		while i ~=  n do
			i = i +1

	
			if  param.WhoNoEntitys[i]  == "_System" or param.WhoNoEntitys[i]  == "_DM" then
				local say = ""				
				who = "System"

				local msg = param.Says[i]
				if not msg then msg = "" end

				if param.WhoNoEntitys[i] == "_DM" then		

					say = "\t\t\t" .. "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage(  "..tostring(r2:getScenarioId()) .. ", "
						.."\"DM\", \"".. who.. "\", \"" .. msg .. "\");\n \n"

				else
					--avoid to display "system :" when a system msg is broadcasted
					who = ""
					say = "\t\t\t" .. "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage(  "..tostring(r2:getScenarioId()) .. ", "
						.."\"SYS\", \"".. who.. "\", \"" .. msg .. "\");\n \n"
				end

				code = code ..
					"\t\t"..	"case "..param.Indexs[i].." :\n" ..
					"\t\t"..	"{\n" ..
					say ..
					"\t\t"..	"}\n \n"
		
			elseif rtGrpId and param.Whos[i] and param.Whos[i] ~= "" and param.Grps[i] and param.Grps[i] ~= "" then
				local say = ""
				if param.Says[i] ~= nil and param.Says[i] ~= "" then
					say = "\t\t\t" .. "()".. r2:getNamespace() .. rtGrpId .. ".npcSay(@group,\"" .. param.Whos[i] .. "\", \"DSS_" .. tostring(r2:getScenarioId()) .. " " .. param.Says[i] .. "\");\n \n"
				end

				local emote = ""
				if param.Emotes[i] ~= "" and param.Emotes[i] ~= nil then
					local behaviorValue = r2.getEmoteBehaviorFromEmoteId(param.Emotes[i])
					emote =  "\t\t\t" .. "()"..r2:getNamespace()..rtGrpId..".emote(@group,\""..param.Whos[i].."\", \""..behaviorValue.."\");\n"
				end

		
	
				code = code ..
					"\t\t"..	"case "..param.Indexs[i].." :\n" ..
					"\t\t"..	"{\n" ..
					"\t\t\t" ..		 "(@group)".. r2:getNamespace() .. param.Grps[i] .. ".context();\n \n" ..
					say ..
					emote ..
					"\t\t"..	"}\n \n"
			end

		end

		code = code .. "\t}\n}"


		action.Action = "code"
		action.Parameters = code

		return action

	end
	
	--BROADCAST
	if actionType == "broadcast_msg" then
		local baseActRtGrpId = arg[2]
		assert(baseActRtGrpId)
		assert(type(baseActRtGrpId) == "string")
		
		local msg = arg[3]
		assert(msg)
		assert(type(msg) == "string")

		local who = ""

		action.Parameters = "()".. r2:getNamespace() .. baseActRtGrpId .. ".dssMessage(  "..tostring(r2:getScenarioId()) .. ", "
						.."\"SYS\", \"".. who.. "\", \"" .. msg .. "\");\n"

		action.Action = "code"
		return action
	end

	--QUEST ACTIONS
	if actionType == "validate_quest_step" then
		local questRtGrpId = arg[2]
		local prefix = ""
		if questRtGrpId and questRtGrpId ~= "" then
			prefix = r2:getNamespace() .. questRtGrpId.."."
		end
				
		local taskRtIds = arg[3]
		local nbTasks = table.getn(taskRtIds)
		
		action.Parameters = 
[[
	if (]] ..prefix.. [[v2 != 0)
	{
		switch(]] ..prefix.. [[v2)
		{
]]
		
		--the case (1) never happens : when the quest begins and when the first task is completed, the step index 
		--is incremented before the action "validate_quest_step"
		--
		local i
		for i = 2, nbTasks do
			action.Parameters = action.Parameters..
[[
		case ]] ..tostring(i).. [[ : 
		{
			if (]]..taskRtIds[i - 1]..[[Active == 1)
			{
				]]..taskRtIds[i - 1]..[[Active = 0;
				()]]..taskRtIds[i - 1]..[[setEvent(5);
			}
			()]] ..taskRtIds[i].. [[setEvent(7);
			]] ..taskRtIds[i].. [[Active = 1;
			()]] ..taskRtIds[i].. [[setEvent(4);
		}
]]
		end
		
		--last task
		action.Parameters = action.Parameters..
[[
	//default is only used by the last step of the quest
		case ]]..tostring(nbTasks + 1) ..[[ : 
		{
			if (]]..taskRtIds[nbTasks]..[[Active == 1)
			{
				]]..taskRtIds[nbTasks]..[[Active = 0;
				()]]..taskRtIds[nbTasks]..[[setEvent(5);
			}
			//if the quest is repeatable
			if (]] ..prefix.. [[v1 == 1)
			{	
				//resetting the index to 1 for first quest step
				]] ..prefix.. [[v2 = 1;
				//()]] ..taskRtIds[1].. [[setEvent(7);
				]] ..taskRtIds[1].. [[Active = 1;
				()]] ..taskRtIds[1].. [[setEvent(4);
			}
			else
			{
				]] ..prefix.. [[v2 = 0;	
			}
			()]] ..prefix.. [[setEvent(8);
		}
	} //!switch
} //!if
]]

		action.Action = "code"
		
		return action
		
	end


	if actionType == "increment_quest_step_index" then
		local currentNamespace = r2:getNamespace()
		
		local questRtGrpId = arg[2]
		local prefix = ""
		if questRtGrpId and questRtGrpId ~= "" then
			prefix = r2:getNamespace() .. questRtGrpId.."."
		end

		local currentTaskIndex = arg[3]

		action.Parameters = "if ("..prefix.."v2 == " ..tostring(currentTaskIndex)..")\n"
			.."{\n"
			.."\t "..prefix.."v2 = " ..prefix.."v2 + 1;\n"
			.."\t ()" ..prefix.."setEvent(9);\n"
			.."}"
			

		action.Action = "code"
		return action
	end
	

	if actionType == "request_item" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local grpName = r2:getNamespace() .. rtGrpId
	
		local items = tostring(arg[3])
		assert(items)

		local phrase = tostring(arg[4])
		assert(phrase)
		if phrase == "" then phrase = "Ok" end
		action.Parameters =
			"// request_item\n"
			.. "(@groupToNotify)".. grpName ..".context();\n"
			.."()receiveMissionItems(\"".. items.."\", \"".. phrase .."\", @groupToNotify);\n"


		action.Action = "code"
		return action

	end


	if actionType == "give_item" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local grpName = r2:getNamespace() .. rtGrpId
	
		local items = tostring(arg[3])
		assert(items)

		local phrase = tostring(arg[4])
		assert(phrase)
		if phrase == "" then phrase = "Ok" end
	
		action.Parameters =
			"// give_item\n"
			.. "(@groupToNotify)".. grpName ..".context();\n"
			.."()giveMissionItems(\"".. items.."\", \"".. phrase .."\", @groupToNotify);\n"


		
		action.Action = "code"
		return action

	end


	if actionType == "give_reward" then
		local rtGiverGrpId = arg[2]
		local rtGiverName = arg[3]
		local rtGiverGrpName = r2:getNamespace()..rtGiverGrpId

		local texts = arg[4]
	
		local rewardText = texts["rewardText"]
		local rareRewardText = texts["rareRewardText"]	
		local inventoryFullText = texts["inventoryFullText"]
		local notEnoughPointsText = texts["notEnoughPointsText"]

		local textsArgs = "\""..rewardText.."\", "
			.."\""..rareRewardText.. "\", "
			.."\""..inventoryFullText.. "\", "
			.."\""..notEnoughPointsText.."\""

		action.Parameters = "//Give reward (giver : '".. rtGiverName.."')\n"
			.."(@groupToNotify)".. rtGiverGrpName..".context();\n"
			.."()giveReward("..textsArgs..", @groupToNotify);\n"

		action.Action = "code"
		return action
	end

	if actionType == "teleport_near" then
		local rtGiverGrpId = arg[2]
		local rtGiverGrpName = r2:getNamespace()..rtGiverGrpId
		local uniqId = arg[3]
		local x = arg[4]
		local y = arg[5]
		local z = arg[6]

		action.Parameters = "//teleport Near\n"
			.."(@groupToNotify)".. rtGiverGrpName..".context();\n"
			.."()teleportNear("..tostring(x)..", "..tostring(y).. ", ".. tostring(z)..", @groupToNotify);\n"

		action.Action = "code"
		return action
	end

	if actionType == "talk_to" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local grpName = r2:getNamespace() .. rtGrpId
	
		local phrase = tostring(arg[3])
		assert(phrase)

		if phrase == "" then phrase = "Ok" end

		action.Parameters =
			"// talk_to\n"
			.. "(@groupToNotify)".. grpName ..".context();\n"
			.."()talkTo(\"".. phrase .."\", @groupToNotify);\n"


		action.Action = "code"
		return action

	end

	if actionType == "set_value" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local variable = tostring(arg[3])
		assert(variable)
		--local variableLen = string.len(variable)
		--assert(variableLen < 8)
		--variable = string.lower(variable)
		local i = 0;

		assert( type(arg[4]) == 'number' or type(arg[4]) == 'string')
		
	 	local value = arg[4]
		action.Parameters = prefix .. variable .. " = " .. value..";\n"
		action.Action = "code"
		return action
	end
	
	--called each time some scenario points
	if actionType == "add_scenario_points" then
		--scenario rtId
		local rtBaseActId = arg[2]
		local points = arg[3]
		local prefix = ""
		if rtBaseActId and rtBaseActId ~= "" then
			prefix = r2:getNamespace()..rtBaseActId.."."
		end

		action.Parameters = prefix.."ScenarioPoints = "..prefix.."ScenarioPoints + " ..tostring(points)..";\n"
							
		action.Action = "code"
		return action
	end
	

	--called every 30 seconds or so to avoid sending network msg each time some points are added
	if actionType == "set_scenario_points" then
		local rtScenarioId = tostring( r2:getScenarioId())
		local rtBaseActId = arg[2]

		local prefix = ""
		if rtBaseActId and rtBaseActId ~= "" then
			prefix = r2:getNamespace()..rtBaseActId.."." 
		end
		
		action.Parameters = "()setScenarioPoints("..rtScenarioId.. ", " ..prefix.."ScenarioPoints);\n"
			.."()"..prefix.."setTimer(300,1);\n"
		action.Action = "code"
		return action
	end

	if actionType == "start_scenario_timing" then
		local rtScenarioId = tostring( r2:getScenarioId())

		action.Parameters = "()startScenarioTiming("..rtScenarioId..");\n"
		action.Action = "code"
		return action
	end

	if actionType == "stop_scenario_timing" then
		local rtScenarioId = tostring( r2:getScenarioId())
		
		action.Parameters = "()endScenarioTiming("..rtScenarioId..");\n"
		action.Action = "code"
		return action
	end

	if actionType == "if_value_equal" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local variable = tostring(arg[3])
		assert(variable)
		local variableLen = string.len(variable)
		--variable = string.lower(variable)
		local i = 0;

		assert( type(arg[4]) == 'number')
		local value = arg[4]
		action.Parameters = prefix..variable .. " == " .. value

		if (arg[5] ~= nil ) then
			assert( type(arg[5]) == 'table')
			local value = arg[4]
			action.Parameters = prefix..variable .. " == " .. value
			table.insert(action.Children, arg[5])
		end


		action.Action = "dynamic_if"

		return action
	end
	
	-- "validate_task" is used when the player completed part of a mission but didn't come back to the mission giver
	if actionType == "validate_task" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		action.Parameters = "//validateTask \n" 
						.."if (" ..prefix.."Active == 1 && " ..prefix.."v2 == 1 )\n"
						.."{"
						.."\n\t" ..prefix.."v2 = 2;\n\t"
						.."()" ..prefix.."setEvent(8);\n"
						.."}"
		action.Action = "code"

		return action
	end
	
	-- "complete_mission" is used when the player comes back to the mission giver after having validated the mission.
	if actionType == "complete_mission" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		action.Parameters = "//complete_mission \n" 
						.."if (" ..prefix.."Active == 1)\n"
						.."{"
						.."\n\t" ..prefix.."v2 = 2;\n\t"
						.."()" ..prefix.."setEvent(9);\n"
						.."}"
		action.Action = "code"

		return action
	end

	if  string.find(actionType, "timer_") ~= nil
	then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local timer = tonumber(arg[3])
		assert(0 <= timer and timer <= 3)

		if actionType == "timer_trigger" then
			action.Parameters = "()"..prefix.."setTimer(4, "..timer..");\n"

		elseif actionType == "timer_disable" then
			action.Parameters = "()"..prefix.."timerDisable("..timer..");\n"
			..prefix.. "Active = 0;"
		elseif actionType == "timer_suspend" then
			action.Parameters = "()"..prefix.."timerSuspend("..timer..");\n"
		elseif actionType == "timer_resume" then
			action.Parameters = "()"..prefix.."timerResume("..timer..");\n"
		elseif actionType == "timer_enable" then
			printWarning("timerEnable is not implemented in AIS!")
			action.Parameters = "()"..prefix.."timerEnable("..timer..");\n" -- !!!NOT IMPLEMENTED IN AIS!!!
		elseif actionType == "timer_is_enable" then
			action.Parameters = "("..prefix.."is_enable"..")"..prefix.."timerIsEnabled("..timer..");\n"
		elseif actionType == "timer_is_suspended" then
			action.Parameters = "("..prefix.."is_suspended"..")"..prefix.."timerIsSuspended("..timer..");\n"
		elseif actionType == "timer_add" or actionType == "timer_sub" then
			local wait = tonumber(arg[4])
			assert(wait and 0<= wait)
			wait = wait*10 + 4
			if  actionType == "timer_sub" then
				action.Parameters = "()"..prefix.."timerAdd("..timer..", " .. -wait  .. ");\n"
			else
				action.Parameters = "()"..prefix.."timerAdd("..timer..", " ..  wait  .. ");\n"
			end
		elseif actionType == "timer_set" then
			local wait = tonumber(arg[4])
			assert(wait and 0<= wait)
			wait = wait*10 + 4
			action.Parameters = "()"..prefix.."setTimer("..wait..", " .. timer .. ");\n"
			..prefix.."Active = 1;\n"

		elseif actionType == "timer_set_daytime" then
			local hours = tonumber(arg[4])
			local minutes = tonumber(arg[5])
			assert(hours and 0<= hours and hours <= 23)
			assert(minutes and 0<= minutes and minutes <= 60)
			action.Parameters = "()"..prefix.."timerSetRyzomDaytime("..timer..", " .. hours .. ", "..minutes..");\n"
		else
			debugInfo(colorTag(255,0,0).."Unhandeld action '" ..actionType .."'")
			assert(nil)
		end
		action.Action = "code"
		return action
	end

	-------------------------------------
	-- Counter feature
	-------------------------------------
	if string.find(actionType, "counter_") ~= nil
	then
		local rtGrpId = arg[2]
		local prefix = ""

		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		--
		-- Action "Init": initializes the counter by storing the initial counter value in v1
		-- and the triggerValue in v2.
		--
		if actionType == "counter_init" then
			local value = arg[3]
			local triggerValue = arg[4]
			action.Parameters = prefix.. "v0 = 1;\n"
			..prefix.."v1 = "..value..";\n"
			..prefix.."v2 = "..triggerValue..";\n"
		end

		--
		-- Action "increment": checks wether the counter is active or not (var v0 used as a boolean),
		-- then increment the counter and enventually checks if the triggerValue (stored in v2) has
		-- been reached to trigger a userEvent.
		--
		if actionType == "counter_inc" then
			action.Name = "counter_inc"
			action.Parameters = "if (" ..prefix.. "v0 == 1)\n"
			.. "{\n\tif (" ..prefix.. "v1 >= 0)\n"
			.. "\t{\n"
			.. "\t\t" .. prefix.. "v1 = " ..prefix.. "v1 + 1;\n"
			.. "\t\tif (" ..prefix.. "v1 == " ..prefix.."v2)\n"
			.. "\t\t{\n"
			.. "\t\t\t" .. prefix.. "e=3;\n"
			.. "\t\t\t ()" ..prefix.. "setEvent(0);\n"
			.. "\t\t}\n"
			.."\t}\n}"
			--.. "()"..prefix..'debug("v0=");'.."\n"
			--.. "()"..prefix..'debug('..prefix..'v0'..');'.."\n"
			--.. "()"..prefix..'debug("v1=");'.."\n"
			--.. "()"..prefix..'debug('..prefix..'v1'..');'.."\n"
			--.. "()"..prefix..'debug("v2=");'.."\n"
			--.. "()"..prefix..'debug('..prefix..'v2'..');'.."\n"
		end

		--
		-- Action "decrement": works the same as increment (checks if the counter can be decremented)
		--
		if actionType == "counter_dec" then
			action.Name = "counter_dec"
			action.Parameters = "if (" ..prefix.. "v0 == 1)\n"
			.. "{\n\tif (" ..prefix.. "v1 > 0)\n"
			.. "\t{\n"
			.. "\t\t" .. prefix.. "v1 = " ..prefix.. "v1 - 1;\n"
			.. "\t\tif (" ..prefix.. "v1 == " ..prefix.. "v2)\n"
			.. "\t\t{ \n"
			.. "\t\t\t" .. prefix.. "e=3;\n"
			.. "\t\t\t()" ..prefix.. "setEvent(0);\n"
			.. "\t\t}\n"
			.."\t}\n}\n"
			.. "()"..prefix..'debug("v0=");'.."\n"
			.. "()"..prefix..'debug('..prefix..'v0'..');'.."\n"
			.. "()"..prefix..'debug("v1=");'.."\n"
			.. "()"..prefix..'debug('..prefix..'v1'..');'.."\n"
			.. "()"..prefix..'debug("v2=");'.."\n"
			.. "()"..prefix..'debug('..prefix..'v2'..');'.."\n"
		end

		if actionType == "counter_enable" then
			action.Name = "counter_enable"
			action.Parameters = prefix.."v0 = 1;\n"
		end

		if actionType == "counter_disable" then
			action.Name = "counter_disable"
			action.Parameters = prefix.."v0 = 0;\n"
		end

		if actionType == "counter_trigger" then
		end

		action.Action = "code"

		if actionType == "counter_is_enable" then
			action.Name =  "counter_is_enable"
			action.Action = "dynamic_if"
			action.Parameters = prefix.. "v0 == 1\n"
		end


		return action
	end

	-------------------------------------
	-- GiveItem Feature
	-------------------------------------

	if string.find(actionType, "giveItem_") ~= nil
	then
		local rtGrpId = arg[2]
		local prefix = ""

		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		if actionType == "giveItem_init" then
			local qty = arg[3]
			--local triggerValue = arg[4]
			action.Parameters = prefix.. "v0 = 1;\n"
			..prefix.."v1 = "..qty..";\n"
			--..prefix.."v2 = "..triggerValue..";\n"
		end

		if actionType == "giveItem_enable" then
			action.Name = "giveItem_enable"
			action.Parameters = prefix.."v0 = 1;\n"
		end

		if actionType == "giveItem_disable" then
			action.Name = "giveItem_disable"
			action.Parameters = prefix.."v0 = 0;\n"
		end

		action.Action = "code"

		if actionType == "giveItem_is_enable" then
			action.Name =  "giveItem_is_enable"
			action.Action = "dynamic_if"
			action.Parameters = prefix.. "v0 == 1\n"
		end

		return action

	end

	-------------------------------------
	-- RequestItem Feature
	-------------------------------------

	if string.find(actionType, "requestItem_") ~= nil
	then
		local rtGrpId = arg[2]
		local prefix = ""

		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		if actionType == "requestItem_init" then
			local qty = arg[3]
			--local triggerValue = arg[4]
			action.Parameters = prefix.. "v0 = 1;\n"
			..prefix.."v1 = "..qty..";\n"
			--..prefix.."v2 = "..triggerValue..";\n"
		end

		if actionType == "requestItem_enable" then
			action.Name = "requestItem_enable"
			action.Parameters = prefix.."v0 = 1;\n"
		end

		if actionType == "requestItem_disable" then
			action.Name = "requestItem_disable"
			action.Parameters = prefix.."v0 = 0;\n"
		end

		action.Action = "code"

		if actionType == "requestItem_is_enable" then
			action.Name =  "requestItem_is_enable"
			action.Action = "dynamic_if"
			action.Parameters = prefix.. "v0 == 1\n"
		end

		return action

	end

	if actionType == "bot_init" then
		function indent(s)
			s = "\t" .. string.gsub(s, "\n", "\n\t")
			return s
		end
		local rtGrpId = arg[2]
		local prefix = ""
			if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		

		assert(type(arg[3]) == "string")
		assert(type(arg[4]) == "number")
		assert(type(arg[5]) == "number")
		assert(type(arg[6]) == "number")

		local category = tostring(arg[3])
		local aggroDist = tonumber(arg[4])
		local botAttackable = tonumber(arg[5]) 
		local playerAttackable = tonumber(arg[6])


		local action = r2.Translator.createAction("faction_init", rtGrpId, category, aggroDist, botAttackable, playerAttackable)
		local code = action.Parameters
		code = 	indent(code)
		action.Parameters = "if ("..prefix.."factInit != 1)\n{\n"..code..prefix.."factInit = 1;\n}\n"

		return action
		
	end
	if actionType == "faction_init" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end
		

		assert(type(arg[3]) == "string")
		assert(type(arg[4]) == "number")
		assert(type(arg[5]) == "number")
		assert(type(arg[6]) == "number")

		local category = tostring(arg[3])
		local aggroDist = tonumber(arg[4])
		local botAttackable = tonumber(arg[5]) 
		local playerAttackable = tonumber(arg[6])
		
		
		local code =""

		code = code.."()"..prefix.."setActivity(\"faction\");\n" 

		if category == "Civil" then
			if botAttackable == 1 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"guard\");\n"	-- don't assist
			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"	-- don't assist
			end
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n" 

		elseif category == "Guard" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n" 

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"guard\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|guard\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|carnivore|kitin\");\n" 

			end

		elseif category =="Karavan" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n" 

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"karavan\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|karavan\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|carnivore|kitin|plant|kitinWorker\");\n" 
			end
		elseif category =="Kami" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n" 

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"kami\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"Player|kami\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"bandit|kitin|kitinWorker\");\n" 
			end
		elseif category == "Bandit" then
			if botAttackable == 0 then
				code = code.."()setFactionProp(\"faction\", \"civil\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				end
			
			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"bandit\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"bandit\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|karavan|kami\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|karavan|kami\");\n"
				end
			end
		elseif category == "Carnivore" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"

				end
			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"carnivore\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|herbivore|karavan\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|herbivore|karavan\");\n"
				end
			end
		elseif category == "Herbivore" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"herbivore\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"

			end
		elseif category == "Plant" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"plant\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"plant\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"

			end
		elseif category == "Degen" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"degen\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"degen\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|plant|herbivore|carnivore|kitin|kitinWorker|kami|karavan\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|plant|herbivore|carnivore|kitin|kitinWorker|kami|karavan\");\n"
				end
			end

		elseif category =="WorkerKitin" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"

			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"kitinWorker\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"kitin|kitinWorker\");\n"
				code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"

			end
		elseif category =="SoldierKitin" then
			if botAttackable == 0 then
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"
				if playerAttackable == 1 then
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
					code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"

				end
			else
				code = code.."()"..prefix.."setFactionProp(\"faction\", \"kitin\");\n"
				code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"kitin|kitinWorker\");\n"
				if playerAttackable == 1 then 
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"Player|guard|bandit|karavan|kami\");\n" 
				else
					code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"guard|bandit|karavan|kami\");\n" 
				end
			end
		else
			code = code.."()"..prefix.."setFactionProp(\"faction\", \"civil\");\n"	-- don't assist
			code = code.."()"..prefix.."setFactionProp(\"ennemyFaction\", \"\");\n"
			code = code.."()"..prefix.."setFactionProp(\"friendFaction\", \"\");\n"
		end	
		code = code .. "()"..prefix.."setAggro("..tostring(aggroDist)..", 20);\n"
		action.Parameters = code
		action.Action = "code"
		return action
	end
	
	--set player_attackable 
	if actionType == "set_player_attackable" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() ..rtGrpId.."."
		end
		
		assert(type(arg[3]) == "number")

		local playerAttackable = arg[3]
		action.Parameters = "()"..prefix.."setPlayerAttackable("..playerAttackable..");"
		action.Action = "code"
		return action
	end

	--set bot_attackable 
	if actionType == "set_bot_attackable" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() ..rtGrpId.."."
		end
		
		assert(type(arg[3]) == "number")

		local botAttackable = arg[3]
		action.Parameters = "()"..prefix.."setBotAttackable("..botAttackable..");"
		action.Action = "code"
		return action
	end
	
	--make a npc run
	if actionType == "set_running_speed" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() ..rtGrpId.. "."
		end

		action.Parameters = "()"..prefix.."addPersistentProfileParameter(\"running\");"
		action.Action = "code"
		return action
	end

	--make a npc walk
	if actionType == "set_walking_speed" then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() ..rtGrpId.. "."
		end

		action.Parameters = "()"..prefix.."removePersistentProfileParameter(\"running\");"
		action.Action = "code"
		return action
	end

	if actionType == "generic_event_trigger"
	then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local eventId = tonumber(arg[3])
		assert(eventId and 0 <= eventId and eventId <= 9)

		action.Parameters = prefix.."e="..eventId..";\n" ..
			"()"..prefix.."setEvent(0);\n"

		action.Action = "code"
		return action
	end

	if actionType == "user_event_trigger"
	then
		local rtGrpId = arg[2]
		local prefix = ""
		if rtGrpId and rtGrpId ~= "" then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local eventId = tonumber(arg[3])
		assert(eventId and 0 <= eventId and eventId <= 9)

		action.Parameters = "()"..prefix.."setEvent(".. eventId..");\n"

		action.Action = "code"
		return action
	end



-- generci_event
--

	if actionType == "dssStartAct" then
		local actId = tonumber(arg[2])
		assert(actId)
		local sessionId = r2:getScenarioId()
		assert(sessionId)
		action.Action = "code"
		action.Parameters = "()dssStartAct(" .. sessionId .. ", " .. actId .. ");\n"
		return action, action
	end

--trigger_event action
	if string.find(actionType, "trigger_event_%d") ~= nil
	then
		action.Parameters = arg[2]
		return action
	end

--spawn/despawn action
	if (actionType == "null_action")
	then
		return action
	end

	if actionType == "spawn" then 
		local rtNpcGrpId = arg[2]
		action.Action = "code"
		local prefix = ""
		if rtNpcGrpId then
			prefix = r2:getNamespace() .. rtNpcGrpId.."."
		end
		action.Parameters = "()"..prefix.. actionType.."();"
		return action
	end

	
	if actionType == "despawn" then 
		local rtNpcGrpId = arg[2]
		action.Action = "code"
		local prefix = ""
		if rtNpcGrpId then
			prefix = r2:getNamespace() .. rtNpcGrpId.."."
		end
		action.Parameters = "()"..prefix.. actionType.."(0);"
		return action
	end


	if (actionType == "sit_down") or (actionType == "stand_up") then
		local rtGrpId = arg[2]
		action.Action = "code"

		local prefix = ""
		if rtGrpId then
			prefix = r2:getNamespace() .. rtGrpId.."."
		end

		local sitting = 0
		if actionType=="sit_down" then
			sitting = 1
		end
		if sitting == 1 then
			action.Parameters =
				"()"..prefix.."sitDown();\n" ..
				"()"..prefix.."setTimer(40,1);\n" -- wait 4 second
				.. prefix.."isSitting = ".. tostring( sitting) .. ";"
		else
			action.Parameters =
				"()"..prefix.."standUp();\n" ..
				"()"..prefix.."setTimer(40,1);\n" -- wait 4 second
				.. prefix.."isSitting = ".. tostring( sitting) .. ";"		

		end
	end

--multi actions
	if actionType == "multi_actions" then
		local actions = arg[2]
		if actions ~= nil then
			local max = table.getn(actions)
			for i=1, max do
				assert(actions[i])
				table.insert(action.Children, actions[i])
			end
		end
		return action
	end

--say action
	if actionType == "say"
	then
		action.Parameters = "say: "..arg[2]
		return action
	end

	if actionType == "switch_actions"
	then
		action.Parameters = arg[2]
		return action
	end

--npc_say action
	if actionType == "npc_say"
	then
		action.Parameters = ""

		local str = arg[2]

		if str == nil then str = "\n" end
		if (string.find(str, "\n") == nil) then
			str = str .. "\n"
		end

		if (table.getn(arg)==3)
		then
			assert(arg[3])
			assert( tostring(arg[3]) )
			action.Parameters = tostring(arg[3]).."\n"
		end
		action.Parameters = action.Parameters..str
		return action
	end
--emot action
	if actionType == "emot"
	then
		local max = table.getn(arg)
		debugInfo(colorTag(255,0,0,255).."action emot")
		local parameters =""
		for i=2, max do
			parameters = parameters .. arg[i]
			parameters = parameters .. "\n"
		end
		action.Parameters = parameters
		return action
	end

--if action
--arg2: expression
--arg3: action if expression is true
--arg4(optional): action if expression false
	if (actionType == "condition_if")or(actionType == "condition_if_else") or (actionType == "dynamic_if")
	then
		local max = table.getn(arg)
		if max == 4 then
		--	action.Action="dynamic_if_else"
			action.Action="dynamic_if"
			table.insert(action.Children, arg[3])
			table.insert(action.Children, arg[4])
		elseif max ==3 	then
			action.Action="dynamic_if"
			table.insert(action.Children, arg[3])
		elseif max ==2 then
			action.Action="dynamic_if"
		else
			return nil
		end

		action.Parameters = arg[2]
		return action
	end

-- waraning
	if actionType == "code"
	then
		action.Parameters = arg[2]
		return action
	end

--random action
	if actionType == "random_select"
	then
		local max = table.getn(arg)
		for i=2, max do
		table.insert(action.Children, arg[i])
		end
		return action
	end

--set timer action
	if string.find(actionType, "set_timer_t") ~= nil
	then
		local max = table.getn(arg)
		parameters=""
		for i=2, max do
			parameters = parameters .. arg[i]
		end
		action.Parameters = parameters
		return action
	end

--modify variable action
	if actionType == "modify_variable"  or actionType == "begin_state"
	then
		action.Parameters = arg[2]
		return action
	end

	if actionType == "punctual_state"
	then
		action.Parameters = arg[2]
		return action
	end

	if (actionType == "stand_up")or(actionType == "sit_down")or(actionType == "punctual_state_end")
	then
		return action
	end
	printWarning("Unhandled action " .. actionType)
	return nil
end


--first param : event type
--second param: StatesByName
--third param : GroupsByName
--then, parameters
Translator.createEvent = function(...)
	local event = r2.newComponent("RtNpcEventHandler")
	local eventType = arg[1]
	event.Event = eventType
	event.StatesByName = arg[2]
	event.GroupsByName = arg[3]
	assert(arg[1])
	assert(arg[2])
	assert(arg[3])

	if eventType == nil then
		debugInfo("Error invalid eventType")
		assert(nil)
		return nil
	end

	if string.find(eventType, "timer_t%d_triggered") ~=nil or string.find(eventType, "user_event_%d")
	then
		return event
	end

	if (eventType == "end_of_state") or (eventType == "start_of_state")
		or (eventType == "group_under_attack") or (eventType == "destination_reached_all")
		or (eventType == "bot_killed") or (eventType == "group_eliminated") or (eventType == "group_under_attack")
		or (eventType == "destination_reached") or (eventType == "variable_changed")
		or (eventType == "group_despawned") or (eventType == "group_spawned") or (eventType == "bot_target_killed")
		or (eventType == "player_target_npc")

		or string.find(eventType, "variable_v%d_changed") ~= nil
	then
		return event
	end

	if (eventType == "on_player_arrived") then
		event.Event = "player_arrived_trigger_zone"
		event.IsTriggerZone = 1
		return event
	end

	if (eventType == "on_player_left")  then
		event.Event = "player_left_trigger_zone"
		event.IsTriggerZone = 1
		return event
	end


	printWarning("Error invalid event ".. eventType)

	return nil
end

-- it adds a new simple activity in zone within the given context
Translator.createSimpleActivityInZone = function(context, zoneName, groupsByName, mode, static, aiScriptDebug)
	local action
	local event
	local code

	-- init when the group arrives in the zone
	code = '()setMode("' .. mode .. '");\n'
	if static then
	code = code .. '()stopMoving();\n';
	end
	if aiScriptDebug then
		code = 'log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- restore things when the group quits the zone
	code = '()setMode("Normal");'
	if aiScriptDebug then
		code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("end_of_state", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)
end

-- it adds a new activity in zone within the given context
Translator.createActivityInZone = function(context, zoneName, groupsByName, mode, timerId, wanderTime, activityTime, aiScriptDebug)
	assert(wanderTime > 0)
	assert(activityTime > 0)

	local action
	local event
	local code
	local timerEventName = "timer_t" .. timerId .. "_triggered"

	-- init start of state
	code = 'nextState = 0;\n'
	if aiScriptDebug then
		code = 'log("start_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("start_of_state", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- init when the group arrives in the zone
	code =
	'if (nextState == 0)\n' ..
	'{\n'
	if aiScriptDebug then
		code = code ..
	'	log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n'
	end
	code = code ..
	'	nextState = 1;\n' ..
	'	()setTimer(1, ' .. timerId .. ');\n' ..
	'}\n'
	event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- activity states
	code =
	'if (nextState == 1) {\n' ..
	'	nextState = 2;\n' ..
	'	()stopMoving();\n' ..
	'	()setMode("' .. mode .. '");\n' ..
	'	()setTimer(' .. activityTime .. ', ' .. timerId .. ');\n' ..
	'} else if (nextState == 2) {\n' ..
	'	nextState = 1;\n' ..
	'	()setMode("Normal");\n' ..
	'	()wander();\n' ..
	'	()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
	'} else {\n' ..
	'	log("unknown state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' ..
	'	()break();\n' ..
	'}\n'
	if aiScriptDebug then
		code = 'log("' .. timerEventName .. ': state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent(timerEventName, zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- restore things when the group quits the zone
	code =
	'()timerDisable(' .. timerId .. ');\n' ..
	'()setMode("Normal");\n'
	if aiScriptDebug then
		code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("end_of_state", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)
end

-- it adds a new hunt activity in zone within the given context
Translator.createHuntActivityInZone = function(context, zoneName, groupsByName, timerId, wanderTime, alertTime, eatTime, aiScriptDebug)
	assert(wanderTime > 0)
	assert(alertTime > 0)
	assert(eatTime > 0)

	local action
	local event
	local code
	local timerEventName = "timer_t" .. timerId .. "_triggered"

	-- init start of state
	code = 'nextState = 0;\n'
	if aiScriptDebug then
		code = 'log("start_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("start_of_state", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- init when the group arrives in the zone
	code =
	'if (nextState == 0)\n' ..
	'{\n'
	if aiScriptDebug then
		code = code ..
	'	log("destination_reached_all: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n'
	end
	code = code ..
	'	nextState = 1;\n' ..
---	'	()setFactionProp("ennemyFaction", "' .. Translator.PredatorEnemyFaction .. '");\n' ..
	'	()setTimer(1, ' .. timerId .. ');\n' ..
	'}\n'
	event = Translator.createEvent("destination_reached_all", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- activity states
	code =
	'if (nextState == 1) {\n' ..
	'	nextState = 2;\n' ..
	'	()stopMoving();\n' ..
	'	()setMode("Alert");\n' ..
	'	()setTimer(' .. alertTime .. ', ' .. timerId .. ');\n' ..
	'} else if (nextState == 2) {\n' ..
	'	nextState = 1;\n' ..
	'	()setMode("Normal");\n' ..
	'	()wander();\n' ..
	'	()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
	'} else if (nextState == 3) {\n' ..
	'	nextState = 1;\n' ..
--	'	()setFactionProp("ennemyFaction", "'.. Translator.PredatorEnemyFaction .. '");\n' ..
	'	()setMode("Normal");\n' ..
	'	()wander();\n' ..
	'	()setTimer(' .. wanderTime .. ', ' .. timerId .. ');\n' ..
	'} else {\n' ..
	'	log("unknown state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' ..
	'	()break();\n' ..
	'}\n'
	if aiScriptDebug then
		code = 'log("' .. timerEventName .. ': state=", nextState, ", zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent(timerEventName, zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- eat the corpse when the target is killed
	code =
	'nextState = 3;\n' ..
--.	'()setFactionProp("ennemyFaction", "");\n' ..
	'()stopMoving();\n' ..
	'()setMode("Eat");\n' ..
	'()setTimer(' .. eatTime .. ', ' .. timerId .. ');\n'
	if aiScriptDebug then
		code = 'log("bot_target_killed: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("bot_target_killed", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)

	-- restore things when the group quits the zone
	code =
	'()timerDisable(' .. timerId .. ');\n' ..
	'()setMode("Normal");\n'
-- ..	'()setFactionProp("ennemyFaction", "Player");\n'
	if aiScriptDebug then
		code = 'log("end_of_state: zone=' .. zoneName .. ', group=' .. groupsByName .. '");\n' .. code
	end
	event = Translator.createEvent("end_of_state", zoneName, groupsByName)
	table.insert(context.RtAct.Events, event)
	action = Translator.createAction("code", code)
	table.insert(context.RtAct.Actions, action)
	table.insert(event.ActionsId, action.Id)
end

-- set GroupParameters of a rt Group by readin a hl Np
-- eg set BotAttackable, aggro_range ..
Translator.setGroupParameters = function(hlNpc, rtNpcGrp)
	assert(hlNpc and type(hlNpc) == "userdata")
	rtNpcGrp.GrpParameters = "ring\n" .. rtNpcGrp.GrpParameters
	rtNpcGrp.AiProfilParams = ""

	local botAttackable = hlNpc.BotAttackable
	if botAttackable == 1
	then
		rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."bot_attackable".. "\n"
	end

	local playerAttackable = hlNpc.PlayerAttackable
	if playerAttackable == 1
	then
		rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."player_attackable".. "\n"
	end

	local aggroRange = hlNpc.Aggro
	if aggroRange ~= nil and aggroRange >= 0
	then
		if (aggroRange > 120) then aggroRange = 120 end
		rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.."aggro range: "..aggroRange.."\n"

	end

	-- if hlNpc.UseFame and hlNpc.UseFame == 1 and hlNpc.Fame then
	-- 	rtNpcGrp.AiProfilParams = rtNpcGrp.AiProfilParams 
	-- 	.. "faction:" .. hlNpc.Fame .. "\n"
	--      ..  "fame_for_guard_attack:-300000\n"
	-- end


	local speed = hlNpc.Speed
	if speed ~= nil and type(speed) == "number" and speed == 1 then
		rtNpcGrp.AiProfilParams = rtNpcGrp.AiProfilParams .. "running\n"
	end

	local autoSpawn = hlNpc.AutoSpawn
	if autoSpawn ~= nil and autoSpawn == 0 then
		rtNpcGrp.AutoSpawn = 0
	end

	local noRespawn = hlNpc.NoRespawn
	if noRespawn ~= nil and noRespawn == 1 then
		rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.. "respawn time:-1\n"
	end

	local isFauna = hlNpc.IsFauna
	if isFauna ~= nil and isFauna == 1 then
		rtNpcGrp.GrpParameters = rtNpcGrp.GrpParameters.. "denied_astar_flags:WaterAndNoGo\n"
	end

end


-- TODO doc



---- EventHandlers

-- Components
--- Condition
Translator.getComponentGenericEvent =function(rtNpcGrp, id)
	assert(rtNpcGrp)
	assert(id)
	
	local prefix = ""
	
	if rtNpcGrp.Id and rtNpcGrp.Id ~= "" then
		prefix = r2:getNamespace() .. rtNpcGrp.Id.."."
	end

	local eventHandler =  Translator.createEvent("user_event_0", "",  rtNpcGrp.Id)

	local condition = prefix.. "e == " .. tostring(id)

	local firstCondition = Translator.createAction("dynamic_if", condition)

	return eventHandler, firstCondition, firstCondition
end

Translator.getComponentUserEvent =function(rtNpcGrp, id)
	assert(rtNpcGrp)
	assert(rtNpcGrp.Id)
	assert(id)

	local eventHandler =  Translator.createEvent("user_event_".. id, "",  rtNpcGrp.Id)

--	local condition = "1 == 1"

--	local firstCondition = Translator.createAction("dynamic_if", condition)

	return eventHandler, nil, nil
--, firstCondition, firstCondition
end



-- NPC
-- Selecter

Translator.getNpcLogicCondition = function(entity, context, condition )
	assert( condition.Class == "ConditionStep")
	local rtNpcGrp = Translator.getRtGroup(context, condition.Entity)
	assert(rtNpcGrp)
	local funs ={}
	funs["is in activity sequence"] =Translator.getNpcLogicConditionIsInActivitySequence
	funs["is in activity step"] = Translator.getNpcLogicConditionIsInActivityStep
	funs["is in chat sequence"] = Translator.getNpcLogicConditionIsInChatSequence
	funs["is in chat step"] = Translator.getNpcLogicConditionIsInChatStep
	funs["is dead"] = Translator.getNpcLogicConditionIsDead
	funs["is alive"] = Translator.getNpcLogicConditionIsAlive


	local fun = funs[ condition.Condition.Type ]
	if fun then
		return fun(entity, context, condition, rtNpcGrp)
	end

	local firstAction, lastAction = nil,nil

	return firstAction, lastAction
end


Translator.getNpcLogicAction = function(entity, context, action)
	assert( action.Class == "ActionStep")
	local rtNpcGrp = Translator.getRtGroup(context, action.Entity)
	assert(rtNpcGrp)
	local funs ={}
	funs["Deactivate"] =Translator.getNpcLogicActionDeactivate
	funs["Activate"] =Translator.getNpcLogicActionActivate
	funs["Kill"] = Translator.getNpcLogicActionKill
	funs["begin activity sequence"] = Translator.getNpcLogicActionBeginActivitySequence
	funs["begin chat sequence"] = Translator.getNpcLogicActionBeginChatSequence
	funs["Stand Up"] = Translator.getNpcLogicActionStandUp
	funs["Sit Down"] = Translator.getNpcLogicActionSitDown
	funs["Fight with player"] = Translator.getNpcLogicActionFightPlayer
	funs["Fight with Npcs"] = Translator.getNpcLogicActionFightNpcs
	funs["Dont fight with player"] = Translator.getNpcLogicActionDontFightPlayer
	funs["Dont fight with Npcs"] = Translator.getNpcLogicActionDontFightNpcs
	funs["Run"] = Translator.getNpcLogicActionRun
	funs["Dont run"] = Translator.getNpcLogicActionDontRun
	funs["emits user event"] = Translator.getNpcLogicActionEmitsUserEvent


	local fun = funs[ action.Action.Type ]
	if fun then
		return fun(entity, context, action, rtNpcGrp)
	end


	local firstAction, lastAction = nil,nil

	return firstAction, lastAction
end




Translator.getNpcLogicEvent = function(entity, context, event)
	assert( event.Class == "LogicEntityAction")
	local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
	assert(rtNpcGrp)

	local funs ={}
	funs["activation"] = Translator.getNpcLogicEventActivation
	funs["desactivation"] = Translator.getNpcLogicEventDesactivation
	funs["death"] = Translator.getNpcLogicEventDeath
	
	funs["end of activity step"] = Translator.getNpcLogicEventEndOfActivityStep
	funs["begin of activity step"] = Translator.getNpcLogicEventBeginOfActivityStep
	
	funs["end of activity sequence"] = Translator.getNpcLogicEventEndOfActivitySequence
	funs["begin of activity sequence"] = Translator.getNpcLogicEventBeginOfActivitySequence

	funs["end of chat step"] = Translator.getNpcLogicEventEndOfChatStep
	funs["end of chat sequence"] = Translator.getNpcLogicEventEndOfChatSequence
	funs["user event emitted"] = Translator.getNpcLogicEventUserEventEmitted



	-- There is also group specific functions

	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	local value = event.Event.Type
	local fun = funs[value ]
	if fun then
		return fun(entity, context, event, rtNpcGrp)
	end

	if value == "member death" then
		local eventHandler =  Translator.createEvent("bot_killed", "",  rtNpcGrp.Id)
		return eventHandler, nil, nil
	elseif value == "group death" then
		local eventHandler =  Translator.createEvent("group_eliminated", "",  rtNpcGrp.Id)
		return eventHandler, nil, nil
	elseif value == "targeted by player" then
		local eventHandler =  Translator.createEvent("player_target_npc", "",  rtNpcGrp.Id)
		return eventHandler, nil, nil
	end

	return  eventHandler, firsCondition, lastCondition
end
--- Event

Translator.getGenericLogicEventDesactivation = function (rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	eventHandler = Translator.createEvent("group_despawned", "",  rtNpcGrp.Id)
	return eventHandler, firsCondition, lastCondition
end



Translator.getNpcLogicEventDesactivation = function (hlComponent, context, event, rtNpcGrp)
	return Translator.getGenericLogicEventDesactivation(rtNpcGrp)
end

Translator.getNpcLogicEventUserEventEmitted = function (hlComponent, context, event, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	value = event.Event.ValueString
	if value then value = tonumber(value) end
	if not value then return end
	return Translator.getComponentGenericEvent(rtNpcGrp, value)
end


Translator.getNpcLogicEventActivation = function (hlComponent, context, event, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	eventHandler = Translator.createEvent("group_spawned", "",  rtNpcGrp.Id)
	return eventHandler, firsCondition, lastCondition
end


Translator.getGenericLogicEventDeath= function(rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	eventHandler = Translator.createEvent("bot_killed", "",  rtNpcGrp.Id)
	return eventHandler, firsCondition, lastCondition
end


Translator.getNpcLogicEventDeath= function(hlComponent, context, event, rtNpcGrp)
	return Translator.getGenericLogicEventDeath(rtNpcGrp)
end


Translator.getGenericLogicEventEndOfActivitySequence = function(hlComponent, value, rtNpcGrp)
	local sequenceInstanceId = tostring(value)
	local sequence  = r2:getInstanceFromId(sequenceInstanceId)
	assert(sequence)

	local n = table.getn(sequence.Components)

	if n > 0 then

		local firstStep = sequence.Components[ n-1 ].InstanceId
		eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)
		local value = tostring(firstStep)
		local tab=Logic.findActivityStepIdByInstanceId(sequence.Parent.Parent.Parent, value)
		local id, id2 = tab[1], tab[2]

		if (id == -1 or id2 == -1) then
			printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
				"': the selected activity step can not be found");
			return nil, nil, nil

		end

		local prefix = ""
		local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id + 1) -- in theory it must be (id-1) +1
		local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
		local firstCondition =	Translator.createAction("dynamic_if", condition1)
		local lastCondition = Translator.createAction("dynamic_if", condition2)
		table.insert(firstCondition.Children, lastCondition)

		return eventHandler, firstCondition, lastCondition

	else

		local eventHandler, firsCondition, lastCondition = nil, nil, nil
		eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)

		local prefix = ""
		local tab=Logic.findActivitySequenceIdByInstanceId(sequence.Parent.Parent.Parent, value)
		local id  = tab[1]
		local condition = prefix .. "currentActivitySequenceVar == ".. tostring(id-1)
		local firstCondition =	Translator.createAction("dynamic_if", condition)
		return eventHandler, firstCondition, firstCondition
	end

end


Translator.getGenericLogicEventStartOfActivitySequence = function(value, rtNpcGrp)
	local sequenceInstanceId = tostring(value)
	local sequence  = r2:getInstanceFromId(sequenceInstanceId)
	assert(sequence)

	local n = table.getn(sequence.Components) 

	if n > 0 then
		local firstStep = sequence.Components[0].InstanceId

		local eventHandler, firsCondition, lastCondition = nil, nil, nil

		eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)
		local value = tostring(firstStep)
		local tab=Logic.findActivityStepIdByInstanceId(sequence.Parent.Parent.Parent, value)
		local id, id2 = tab[1], tab[2]

		if (id == -1 or id2 == -1) then
			printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
				"': the selected activity step can not be found");
			return nil, nil, nil

		end

		local prefix = ""
		local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id ) -- in theory it must be (id-1) +1
		local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
		local firstCondition =	Translator.createAction("dynamic_if", condition1)
		local lastCondition = Translator.createAction("dynamic_if", condition2)
		table.insert(firstCondition.Children, lastCondition)
		return eventHandler, firstCondition, lastCondition
	else

		local eventHandler, firsCondition, lastCondition = nil, nil, nil
		eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)

		local prefix = ""
		local tab=Logic.findActivitySequenceIdByInstanceId(sequence.Parent.Parent.Parent, value)
		local id  = tab[1]
		local condition = prefix .. "currentActivitySequenceVar == ".. tostring(id-1)
		local firstCondition =	Translator.createAction("dynamic_if", condition)
		return eventHandler, firstCondition, firstCondition
	end
end

Translator.getNpcLogicEventBeginOfActivitySequence = function(hlComponent, context, event, rtNpcGrp)
	local value = tostring(event.Event.Value)
	return Translator.getGenericLogicEventStartOfActivitySequence(value, rtNpcGrp)
end


Translator.getNpcLogicEventEndOfActivitySequence = function(hlComponent, context, event, rtNpcGrp)
	local value = tostring(event.Event.Value)
	return Translator.getGenericLogicEventEndOfActivitySequence(hlComponent, value, rtNpcGrp)
end



Translator.getNpcLogicEventEndOfActivityStepImpl = function(value, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil

	eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)

	local step = r2:getInstanceFromId(value)
	assert(step)
	local sequence = step.Parent.Parent
	assert(sequence)
	local hlComponent = sequence.Parent.Parent.Parent
	assert(hlComponent)

	local tab=Logic.findActivityStepIdByInstanceId(hlComponent, value)
	local id, id2 = tab[1], tab[2]

	if (id == -1 or id2 == -1) then
		printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
			"': the selected activity step can not be found");
		return nil, nil, nil

	end

	local prefix = ""
	local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id+1) -- in theory it must be (id-1) +1
	local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
	local firstCondition =	Translator.createAction("dynamic_if", condition1)
	local lastCondition = Translator.createAction("dynamic_if", condition2)
	table.insert(firstCondition.Children, lastCondition)
	return eventHandler, firstCondition, lastCondition
end

Translator.getNpcLogicEventEndOfActivityStep = function(hlComponent, context, event, rtNpcGrp)
	local value = tostring(event.Event.Value)
	return Translator.getNpcLogicEventEndOfActivityStepImpl( value, rtNpcGrp)
end


Translator.getNpcLogicEventBeginOfActivityStepImpl = function(value, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	
	assert(rtNpcGrp)
	local step = r2:getInstanceFromId(value)
	assert(step)
	local sequence = step.Parent.Parent
	assert(sequence)
	local hlComponent = sequence.Parent.Parent.Parent
	assert(hlComponent)
	
	eventHandler = Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)
	
	local tab=Logic.findActivityStepIdByInstanceId(hlComponent, value)
	local id, id2 = tab[1], tab[2]

	if (id == -1 or id2 == -1) then
		printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
			"': the selected activity step can not be found");
		return nil, nil, nil

	end

	local prefix = ""
	local condition1 = prefix .. "oldActivityStepVar2 == ".. tostring(id ) -- in theory it must be (id-1) +1
	local condition2 = prefix .. "currentActivitySequenceVar == ".. tostring(id2-1)
	local firstCondition =	Translator.createAction("dynamic_if", condition1)
	local lastCondition = Translator.createAction("dynamic_if", condition2)
	table.insert(firstCondition.Children, lastCondition)
	return eventHandler, firstCondition, lastCondition
end


Translator.getNpcLogicEventBeginOfActivityStep = function(hlComponent, context, event, rtNpcGrp)
	local value = tostring(event.Event.Value)
	return Translator.getNpcLogicEventBeginOfActivityStepImpl( value, rtNpcGrp)
end




Translator.getNpcLogicEventEndOfChatStepImpl = function(hlComponent, context, event, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil

	eventHandler = Translator.createEvent("timer_t1_triggered", "",  rtNpcGrp.Id)
	local value = tostring(event.Event.Value)

	local tab=Logic.findChatStepIdByInstanceId(hlComponent, value)
	local id, id2 = tab[1], tab[2]



	if (id ==-1 or id2 == -1) then
		printWarning("error in translation: the event '"..event.Name .. "' in component '" .. hlComponent.Name ..
			"': the selected chat step can not be found");
		return nil, nil, nil

	end
	local prefix = ""
	local condition1 = prefix.."oldChatStepVar == ".. tostring(id-1)
	local condition2 = prefix.."v0 == ".. tostring(id2-1)
	local firstCondition =	Translator.createAction("dynamic_if", condition1)
	local lastCondition = Translator.createAction("dynamic_if", condition2)
	table.insert(firstCondition.Children, lastCondition)
	return eventHandler, firstCondition, lastCondition
end


Translator.getNpcLogicEventEndOfChatStep = function(hlComponent, context, event, rtNpcGrp)
	local value = tostring(event.Event.Value)
	return Translator.getNpcLogicEventEndOfChatStepImpl(hlComponent, value, rtNpcGrp)
end
--- Conditions


Translator.getGenericLogicConditionIsInActivitySequence = function(entity, conditionValue, rtNpcGrp)
	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end

	local theValue = conditionValue
	local tab=Logic.findActivitySequenceIdByInstanceId(entity, theValue)
	local id, id2 = tab[1], tab[2]

	assert(id ~= -1)

	local condition1 = prefix.."oldActivitySequenceVar == ".. tostring(id-1)
	local firstCondition =	Translator.createAction("dynamic_if", condition1)
	local lastCondition = firstCondition
	return firstCondition, lastCondition

end

Translator.getNpcLogicConditionIsInActivitySequence = function(entity, context, condition, rtNpcGrp)
	local theValue = condition.Condition.Value
	return Translator.getGenericLogicConditionIsInActivitySequence(entity, theValue, rtNpcGrp)
end

Translator.getGenericLogicConditionIsInActivityStep = function(entity, conditionValue, rtNpcGrp)
	assert(entity and type(entity) == "userdata")
	assert(conditionValue and type(conditionValue) == "string")
	assert(rtNpcGrp and type(rtNpcGrp) == "table")

	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end


	local theValue = conditionValue
	local tab=Logic.findActivityStepIdByInstanceId(entity, theValue)
	local id, id2 = tab[1], tab[2]

	assert(id ~= -1 and id2 ~= -2);

	local condition1 = prefix.."oldActivityStepVar2 == ".. tostring(id)
	local condition2 = prefix.."currentActivitySequenceVar == ".. tostring(id2-1)
	local firstCondition =	Translator.createAction("dynamic_if", condition1)
	local lastCondition = Translator.createAction("dynamic_if", condition2)
	table.insert(firstCondition.Children, lastCondition)
	return firstCondition, lastCondition
end

Translator.getNpcLogicConditionIsInActivityStep = function(entity, context, condition, rtNpcGrp)
	assert(entity and type(entity) == "userdata")
	assert(context and type(context) == "table")
	assert(condition and type(condition) == "userdata" and condition.Class == "ConditionStep")
	assert(rtNpcGrp and type(rtNpcGrp) == "table")

	local conditionValue = condition.Condition.Value
	return Translator.getGenericLogicConditionIsInActivityStep(entity, conditionValue, rtNpcGrp)
end

Translator.getNpcLogicConditionIsDeadOrAlive = function(entity, context, condition, rtNpcGrp, isAlive)
	assert(entity and type(entity) == "userdata")
	assert(context and type(context) == "table")
	assert(condition and type(condition) == "userdata" and condition.Class == "ConditionStep")
	assert(rtNpcGrp and type(rtNpcGrp) == "table")
	
	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end

	local lastCondition = Translator.createAction("dynamic_if", prefix.."alive == "..tonumber(isAlive) )
	local firstCondition =	Translator.createAction("multi_actions", 
		{
			Translator.createAction("code","("..prefix.."alive)"..prefix.."isAlived();" ),
			lastCondition
		})
	return firstCondition, lastCondition

end

Translator.getNpcLogicConditionIsDead = function(entity, context, condition, rtNpcGrp)
	return Translator.getNpcLogicConditionIsDeadOrAlive(entity, context, condition, rtNpcGrp, 0)
end

Translator.getNpcLogicConditionIsAlive = function(entity, context, condition, rtNpcGrp)
	return Translator.getNpcLogicConditionIsDeadOrAlive(entity, context, condition, rtNpcGrp, 1)
end


-- Action

Translator.getNpcLogicActionDeactivate = function(entity, context, action, rtNpcGrp)

	if (not entity or not rtNpcGrp) then
		 return nil
	end

	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end

	local retAction = Translator.createAction("code", "()"..prefix.."despawn(0);", "")
	assert(retAction)
	retAction.Name = "desactivate"
	return retAction, retAction
end




Translator.getNpcLogicActionActivate = function(entity, context, action, rtNpcGrp)

	if (not entity or not rtNpcGrp) then
		 return nil
	end

	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end
--()setAutoSpawn(1);
	local retAction = Translator.createAction("code", "()"..prefix.."spawn();", "")
	assert(retAction)
	retAction.Name = "activate"
	return retAction, retAction
end


Translator.getNpcLogicActionKill = function(entity, context, action, rtNpcGrp)
	local prefix = ""
	if rtNpcGrp then prefix =  r2.getNamespace() ..rtNpcGrp.Id.."." end

	local retAction = Translator.createAction("code", "()"..prefix.."setHPScale(0);")
	assert(retAction)
	retAction.Name = "kill"
	return retAction, retAction
end

Translator.getGenericLogicActionBeginActivitySequence = function(sequenceInstanceId, rtNpcGrp)

	local activityStates = Logic.ActivitiesStates[sequenceInstanceId]
	assert(activityStates)
 	local activityStatesId = activityStates[sequenceInstanceId][1].Id

 	local retAction = Translator.createAction("code", "()"..r2:getNamespace() .. rtNpcGrp.Id .. "." .. "postNextState(\""..r2:getNamespace()..activityStatesId.."\");", rtNpcGrp.Id)
	return retAction, retAction

end
Translator.getNpcLogicActionBeginActivitySequence = function(entity, context, action, rtNpcGrp)
	local sequenceInstanceId = action.Action.Value
	return	 Translator.getGenericLogicActionBeginActivitySequence(sequenceInstanceId, rtNpcGrp)
end


Translator.getNpcLogicActionSitDown = function(entity, context, action, rtNpcGrp)
	local retAction = Translator.createAction("sit_down",  rtNpcGrp.Id)
	assert(retAction)
	retAction.Name = "sitDown"
	return retAction, retAction
end


Translator.getNpcLogicActionStandUp = function(entity, context, action, rtNpcGrp)
	local retAction =Translator.createAction("stand_up",  rtNpcGrp.Id)
	retAction.Name = "standUp"
	return retAction, retAction
end


Translator.getNpcLogicActionFightPlayer = function(entity, context, action, rtNpcGrp)
	local leader = entity
	if entity:isKindOf("NpcGrpFeature") then
		if table.getn(entity.Components) >= 0 then
			leader = entity.Components[0]
		else
			leader = nil
		end
	end
	assert(leader)
	local category = leader.SubCategory
	local aggro = leader.Aggro
	if not category then 
		category = leader.Category
	end 

	local action1 = Translator.createAction("set_player_attackable", rtNpcGrp.Id, 1)
	local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, 1)
	local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
	retAction.Name = "Fight with player"
	return retAction ,retAction	
end

Translator.getNpcLogicActionDontFightPlayer = function(entity, context, action, rtNpcGrp)
	local leader = entity
	if entity:isKindOf("NpcGrpFeature") then
		if table.getn(entity.Components) >= 0 then
			leader = entity.Components[0]
		else
			leader = nil
		end
	end
	assert(leader)
	local category = leader.SubCategory
	local aggro = leader.Aggro
	if not category then 
		category = leader.Category
	end 

	local action1 = Translator.createAction("set_player_attackable", rtNpcGrp.Id, 0)
	local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, leader.BotAttackable, 0)
	local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
	retAction.Name = "Dont fight with player"
	return retAction ,retAction	
end


Translator.getNpcLogicActionFightNpcs = function(entity, context, action, rtNpcGrp)
	local leader = entity
	if entity:isKindOf("NpcGrpFeature") then
		if table.getn(entity.Components) >= 0 then
			leader = entity.Components[0]
		else
			leader = nil
		end
	end
	assert(leader)
	local category = leader.SubCategory
	local aggro = leader.Aggro
	if not category then 
		category = leader.Category
	end 

	local action1 = Translator.createAction("set_bot_attackable", rtNpcGrp.Id, 1)
	local action2 = Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, 1, leader.PlayerAttackable)
	local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
	retAction.Name = "Fight with Npcs"
	--inspect(action2)
	return retAction ,retAction	
end

Translator.getNpcLogicActionDontFightNpcs = function(entity, context, action, rtNpcGrp)
	local leader = entity
	if entity:isKindOf("NpcGrpFeature") then
		if table.getn(entity.Components) >= 0 then
			leader = entity.Components[0]
		else
			leader = nil
		end
	end
	assert(leader)
	local category = leader.SubCategory
	local aggro = leader.Aggro
	if not category then 
		category = leader.Category
	end 

	local action1 = Translator.createAction("set_bot_attackable", rtNpcGrp.Id, 0)
	local action2 = r2.Translator.createAction("faction_init", rtNpcGrp.Id, category, aggro, 0, leader.PlayerAttackable)
	
	local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
	retAction.Name = "Dont fight with Npcs"
	return retAction ,retAction	
end


Translator.getNpcLogicActionRun = function(entity, context, action, rtNpcGrp)
	local action1 = Translator.createAction("set_running_speed", rtNpcGrp.Id)
	action1.Name = "Run"
	return action1, action1
end


Translator.getNpcLogicActionDontRun = function(entity, context, action, rtNpcGrp)
	local action1 = Translator.createAction("set_walking_speed", rtNpcGrp.Id)
	action1.Name = "Dont run"
	return action1, action1
end

Translator.getNpcLogicActionEmitsUserEvent = function(entity, context, action, rtNpcGrp)
	if not action.Action.ValueString then return end
	local value = tostring(action.Action.ValueString)

	local action1 = Translator.createAction("generic_event_trigger", rtNpcGrp.Id, value)
	action1.Name = "Trigger User Event"
	return action1, action1
end
-- TODO to up
-- Register an RtNpcGrp to a specific instanceId
Translator.registerManager = function(context, comp)
	local rtNpcGrp = r2.newComponent("RtNpcGrp")
	table.insert(context.RtAct.NpcGrps, rtNpcGrp)
	context.RtGroups[tostring(comp.InstanceId)] = rtNpcGrp
	rtNpcGrp.Name = rtNpcGrp.Id
end


function Translator.createAiGroup(entity,  context)
	local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
	rtNpcGrp.GrpParameters = "ring\n".. rtNpcGrp.GrpParameters

	rtNpcGrp.AutoSpawn = 0

	local aiState = r2.newComponent("RtAiState")

	aiState.AiActivity = "normal"
	table.insert(context.RtAct.AiStates, aiState)
	table.insert(aiState.Children, rtNpcGrp.Id)
	context.GroupStatesName[rtNpcGrp.Id] = aiState.Id

	return rtNpcGrp, aiState
end

function Translator.translateAiGroup(entity, context)
	local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
	if  entity.Behavior.Actions then
		Translator.translateEventHandlers( context, entity, entity.Behavior.Actions, rtNpcGrp)
	end
end



function Translator.translateAiGroupEvent(eventName, entity, context, rtAction)
	assert(rtAction)
	--inspect(context)
	local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)
	local states = Translator.getRtStatesNames(context, entity.InstanceId)
--	local rtAct = context.RtAct

	local act = entity:getParentAct()
	local rtAct2 = context.ActIdToRtAct[act.InstanceId]
	local entityAct = context.Act

	local entityIndex = context.Scenario:getActIndex(act.InstanceId)
	local componentIndex =  context.Scenario:getActIndex(context.Act.InstanceId)

	-- entity on act2, component on act1 (they can not interact)
	if entityIndex ~= componentIndex and entityIndex ~= 0 and componentIndex ~= 0 then
		return
	end

	local rtAct = context.RtAct
	if rtAct2 ~= rtAct then
		local baseAct = context.Scenario:getBaseAct()
		local index = context.Scenario:getActIndex(context.Act.InstanceId)
		if index == -1 then
			printWarning("Invalid Scenario")
		end
		-- Permanent content is known by everyone
		if index ~= 0 then
			local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
		
			local action = Translator.createAction("test_act", rtNpcGrpBase.Id , index)
			table.insert(action.Children, rtAction)
			rtAction = action
		end
	end
	
	local rtEvent = Translator.createEvent(eventName, states,  rtNpcGrp.Id)
	table.insert(rtEvent.ActionsId, rtAction.Id)
	table.insert(rtAct2.Events, rtEvent)
	table.insert(rtAct2.Actions, rtAction)
end

function Translator.translateAiGroupInitialState(entity, context, rtAction)
	return Translator.translateAiGroupEvent("start_of_state", entity, context, rtAction)
end

function Translator.translateAiGroupPlayerTargetNpc(entity, context, rtAction)
	return Translator.translateAiGroupEvent("player_target_npc", entity, context, rtAction) 
end

--Group
Translator.getNpcGroupLogicGroupDeath= function(this, context, eventrtNpcGrp, rtNpcGrp)
	local eventHandler, firsCondition, lastCondition = nil, nil, nil
	eventHandler = Translator.createEvent("group_eliminated", "",  rtNpcGrp.Id)
	return eventHandler, firsCondition, lastCondition
end


function Translator.translateDialog(entity, context)
	local rtNpcGrp = Translator.getRtGroup(context, entity.InstanceId)

	local beforeWait = 0

	if (table.getn(entity.Components) > 0) then
		local i = 0
		while i < table.getn(entity.Components) and not entity.Components[i]:isKindOf("ChatStep") do
			i = i + 1 
		end
		if i < table.getn(entity.Components) and entity.Components[i]:isKindOf("ChatStep") then
			beforeWait = entity.Components[i].Time
		end
	end

	local rtEventStart = Translator.createEvent("timer_t1_triggered", "", rtNpcGrp.Id) -- Start Of Chat Step



	local rtDialogOk = Translator.createAction("switch_actions",  Logic.chatStepVar)
	local rtAction = nil
	local rtAction2 = nil

	rtAction = Translator.createAction("chat_step_first", rtNpcGrp.Id, beforeWait)
	table.insert(rtDialogOk.Children, rtAction)
	local chatStepIndex = 0
	local componentIndex, component = next(entity.Components)

	local endParam = { Grps={}, Whos={}, Emotes={}, Indexs={}, Says={}, WhoNoEntitys={}}

	while componentIndex do
		
		if component and component:isKindOf("ChatStep") then
			chatStepIndex = chatStepIndex + 1
			local param = {}


			local who = r2:getInstanceFromId(component.Actions[0].Who)
			local facing = r2:getInstanceFromId(component.Actions[0].Facing)
	


			local whoGrp = nil
			local whoName = nil
			local facingGrp = nil
			local facingName = nil

			if who then
				whoGrp = Translator.getRtGroup(context, who.InstanceId)
				whoGrp = whoGrp.Id
				whoName = who.Name
			end

			if facing then
				facingGrp = Translator.getRtGroup(context, facing.InstanceId)
				facingGrp = facingGrp.Id
				facingName = facing.Name
			end

			param.WhoGrp = whoGrp
			param.Who = whoName
			param.FacingGrp = facingGrp
			param.Facing = facingName
			if not param.Facing then param.Facing = "" end
			param.Says = r2.Features.TextManager.getRtId(context, component.Actions[0].Says)
			if not param.Says then param.Says = "" end
			param.Emote = component.Actions[0].Emote
			if not param.Emote then param.Emote = "" end
			param.Index = chatStepIndex

			param.WhoNoEntity = component.Actions[0].WhoNoEntity
			if not param.WhoNoEntity then param.WhoNoEntity = "" end
		
			param.Break = 0
			if component.BreakAtEnd then
				param.Break = component.BreakAtEnd
			end

			componentIndex, component = next(entity.Components, componentIndex)

			if component then
				param.Time = component.Time
			else
				param.Time = 3
			end

			rtAction = Translator.createAction("chat_step", rtNpcGrp.Id, param)
			table.insert(rtDialogOk.Children, rtAction)

			table.insert(endParam.Indexs, param.Index)
			table.insert(endParam.Grps, param.WhoGrp)
			table.insert(endParam.Whos, param.Who)
			table.insert(endParam.Emotes, param.Emote)
			table.insert(endParam.Says, param.Says)
			table.insert(endParam.WhoNoEntitys, param.WhoNoEntity)			
		

		else -- !if isKindOf("ChatStep")
			componentIndex, component = next(entity.Components, componentIndex)
		end
	end

	rtAction = Translator.createAction("chat_step_last", rtNpcGrp.Id, chatStepIndex+1)
	table.insert(rtDialogOk.Children, rtAction)



	local rtDialogStart = Translator.createAction("dynamic_if", "start == 1" , rtDialogOk )



	table.insert(rtEventStart.ActionsId, rtDialogStart.Id)
	table.insert(context.RtAct.Events, rtEventStart)
	table.insert(context.RtAct.Actions, rtDialogStart)


	local baseAct = context.Scenario:getBaseAct()
	local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)


	local rtActionEnd = Translator.createAction("chat_step_end", rtNpcGrp.Id, endParam, rtNpcGrpBase.Id)
	if (rtActionEnd) then
		local rtEvenEnd = Translator.createEvent("timer_t0_triggered", "", rtNpcGrp.Id) -- Endo Of Chat Step
		table.insert(rtEvenEnd.ActionsId, rtActionEnd.Id)
		table.insert(context.RtAct.Events, rtEvenEnd)
		table.insert(context.RtAct.Actions, rtActionEnd)
	end



	do
		local rtInitialState= Translator.createAction("dialog_init",  rtNpcGrp.Id , entity.Repeating, entity.AutoStart )
		Translator.translateAiGroupInitialState(entity, context, rtInitialState)
	end

	if (entity.AutoStart == 1) then
		local rtInitialState = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1", 
				Translator.createAction("dialog_starts",  rtNpcGrp.Id )
			)
		Translator.translateAiGroupInitialState(entity, context, rtInitialState)
	end


	Translator.translateAiGroup(entity, context)
end


Translator.getNpcGroupLogicGroupAMemberDeath = Translator.getNpcLogicEventDeath

-- user Event 0
-- start = 1


--
-- TODO: dmler les events (tmp: on utilise les events 7 et 8 pour respectivement activate et deactivate)
--
function Translator.getDialogLogicAction(entity, context, action)
	assert( action.Class == "ActionStep")

	local firstAction, lastAction = nil, nil

	assert( action.Class == "ActionStep")
	local component = r2:getInstanceFromId(action.Entity)
	assert(component)
	local rtNpcGrp = Translator.getRtGroup(context, component.InstanceId)
	assert(rtNpcGrp)

	if action.Action.Type == 'activate' then
		local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 1)
		local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 7)
		local action3 = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".AutoStart == 1", 
				Translator.createAction("dialog_starts", rtNpcGrp.Id)
			)
		local actionActivate = r2.Translator.createAction("multi_actions", {action1, action2, action3})

		local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 0", actionActivate)
		return retAction, retAction
	elseif action.Action.Type == 'deactivate' then
		--local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
		local action1 = r2.Translator.createAction("dialog_deactivate", rtNpcGrp.Id)
		local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 8)
		--local action3 = r2.Translator.createAction("dialog_stops", rtNpcGrp.Id)
		local retAction = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 1, 
			r2.Translator.createAction("multi_actions", {action1, action2}))
		return retAction, retAction
	elseif action.Action.Type == 'starts dialog' then
		local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1", 
				Translator.createAction("dialog_starts", rtNpcGrp.Id)
			)
		return retAction, retAction
	elseif action.Action.Type == 'continues dialog' then
		local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1", 
				Translator.createAction("dialog_continues", rtNpcGrp.Id)
			)
		return retAction, retAction
	elseif action.Action.Type == 'starts chat' then		
		local index = Translator.getChatPositionFromDialog(component, action.Action.Value)
		if index == -1 then return nil end
		local retAction = r2.Translator.createAction("dynamic_if", r2:getNamespace()..rtNpcGrp.Id..".Active == 1", 
				Translator.createAction("chat_starts", rtNpcGrp.Id, index)
			)
		return retAction, retAction
	elseif action.Action.Type == 'stops dialog' then
		--add condition if Active == 1 ?
		local retAction = Translator.createAction("dialog_stops", rtNpcGrp.Id)
		return retAction, retAction

	end

	printWarning('Action not implemented yet :'.. action.Action.Type)
	assert(nil)
	return nil, nil
end




function Translator.getChatPositionFromDialog(dialog, chatInstanceId)
	assert(dialog)
	assert(dialog.Class == 'ChatSequence' or dialog.Class == "ProximityDialog")
	assert(chatInstanceId ~= nil and chatInstanceId ~= "")
	local index = -1
	local componentIndex, component = next(dialog.Components)
	while componentIndex do
		if component.Class == 'ChatStep' then
			index = index + 1	
			if tostring(component.InstanceId) == tostring(chatInstanceId) then
				return index
			end
		end
		componentIndex, component = next(dialog.Components, componentIndex)
	end
	return -1

end

--
-- TODO: dmler les events (tmp: on utilise les events 7 et 8 pour respectivement activate et deactivate)
--
function Translator.getDialogLogicEvent(entity, context, event)
	assert(entity)
	assert( event.Class == "LogicEntityAction")


	local component =  entity -- r2:getInstanceFromId(event.Entity)
	assert(component)
	local rtNpcGrp = Translator.getRtGroup(context, component.InstanceId)
	assert(rtNpcGrp)

	local states = Translator.getRtStatesNames(context, entity.InstanceId)



	local eventType = tostring(event.Event.Type)
	
	if eventType == 'activation' then
		return r2.Translator.getComponentUserEvent(rtNpcGrp, 7)
	
	elseif eventType == 'deactivation' then
		return r2.Translator.getComponentUserEvent(rtNpcGrp, 8)
	
	elseif eventType == 'end of chat' then
		local action =  Translator.createEvent("timer_t2_triggered", states,  rtNpcGrp.Id)
		local index = Translator.getChatPositionFromDialog(component, event.Event.Value)
		if index ==  -1  then return nil end
		local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index + 2, firstCondition)
		return action, firstCondition, firstCondition

	elseif eventType == 'end of dialog' then
		return Translator.getComponentUserEvent(rtNpcGrp, 2)
	
	elseif eventType == 'start of chat' then
		local action =  Translator.createEvent("user_event_4", states,  rtNpcGrp.Id)
		local index = Translator.getChatPositionFromDialog(component, event.Event.Value)
		if index == -1  then return nil end
		local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index+2, firstCondition)
		return action, firstCondition, firstCondition
	
	elseif eventType == 'start of dialog' then
		return Translator.getComponentUserEvent(rtNpcGrp, 1)
	end
	
	printWarning('Event not implemented yet :'.. event.Event.Type)
	assert(nil)
end


Translator.getDialogLogicCondition = function(entity, context, condition )
	assert( condition.Class == "ConditionStep")
	local rtNpcGrp = Translator.getRtGroup(context, condition.Entity)
	assert(rtNpcGrp)
	local funs ={}

	if condition.Condition.Type == "is in dialog" then
		local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 1)
		return firstCondition, firstCondition
	end

	if condition.Condition.Type == "is not in dialog" then
		local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 0)
		return firstCondition, firstCondition
	end


	if condition.Condition.Type == "is in chat" then
		local index = Translator.getChatPositionFromDialog(entity, condition.Condition.Value)
		assert(index ~= -1)
		local lastCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "v1", index+2)
		local firstCondition = Translator.createAction("if_value_equal", rtNpcGrp.Id, "start", 1, lastCondition)
		return firstCondition, lastCondition
	end

	printWarning('Condition not implemented yet :'.. condition.Condition.Type)
	return nil, nil
end


function Translator.translateDefaultFeature(entity, context, translateActivity)
	local components = entity.Components
	--luaObject(context.Feature)
	local key,comp = next(components,nil)
	while(key ~= nil)
	do
		-- Npc case (npc alone not object)
		if (comp.isKindOf and comp:isKindOf("Npc")) then
			local hlNpc = comp
			context.Feature = hlNpc

			-- create and set rtNpc
			
			local rtNpc = r2.Translator.translateNpc(hlNpc, context)	
			table.insert(context.RtAct.Npcs, rtNpc)

			-- create or get rtGrp
			-- set rtGrp.GroupParameter  by reading hlNpc (Aggro, Player attackable..)
			local rtNpcGrp = r2.Translator.getRtGroup(context,hlNpc.InstanceId)
			r2.Translator.setGroupParameters (hlNpc, rtNpcGrp)
			table.insert(rtNpcGrp.Children, rtNpc.Id)
				
			-- set activity
			-- when translating a usercomponentholder (container which has aiActivities), we must translate the AiActivities
			if translateActivity and translateActivity == true
			then
				local aiActivity = r2.Translator.getAiActivity(hlNpc)
				r2.Translator.translateActivities(context, hlNpc,  hlNpc:getBehavior(), rtNpcGrp, aiActivity)
			end

			-- set eventHandlers
			r2.Translator.translateEventHandlers(context, hlNpc, hlNpc:getBehavior().Actions, rtNpcGrp)
		end
		key,comp = next(components,key)
	end
end

function Translator.pretranslateDefaultFeature(this, context)
	local components = this.Components

	local key, comp = next(components, nil)
	while (key ~= nil) do
		if (comp.isKindOf and comp:isKindOf("Npc")) then
			local rtNpcGrp = r2.Translator.getRtGroup(context,comp.InstanceId)		
		end
		key, comp = next(components, key)										
	end
end

function Translator.pretranslateDefaultFeature2(this, context)
	local components = this.Components

	local key, comp = next(components, nil)
	while (key ~= nil) do
		if (comp.isKindOf and comp:isKindOf("Npc")) then
			local rtNpcGrp = r2.Translator.getRtGroup(context,comp.InstanceId)
			-- set activity
			local hlNpc = comp
			context.Feature = hlNpc
			local aiActivity = r2.Translator.getAiActivity(hlNpc)
			r2.Translator.translateActivities(context, hlNpc,  hlNpc:getBehavior(), rtNpcGrp, aiActivity)

		end
		key, comp = next(components, key)										
	end
end




function Translator.getDefaultFeatureActivitiesIds(this)

	local activitiesIds = {}

	local function getActivitiesIdsFrom(entity)
		local components = entity.Components
		local key,comp = next(components,nil)
		while(key ~= nil)
		do
			-- Npc case (npc alone not object)
			if (comp.isKindOf and comp:isKindOf("Npc")) then
				local behavior = comp:getBehavior()
				local k, v = next(behavior.Activities, nil)
				while k do
					table.insert(activitiesIds, v.InstanceId)
					k, v = next(behavior.Activities, k)
				end
			else
				if comp.Components then
					getActivitiesIdsFrom(comp)
				end
			end
 			key,comp = next(components, key)
		end
	end

	getActivitiesIdsFrom(this)

	return activitiesIds

end


--function Translator.getTopParentTreeNode(instance)
--	local tmpInstance = instance
--	if tmpInstance.ParentInstance.Class ~= "LogicEntity" and tmpInstance.ParentInstance.Class ~= "DefaultFeature"
--		and tmpInstance.ParentInstance.Class ~= "Act" then
--		return tmpInstance:getFeatureParentTreeNode()--tmpInstance:getParentTreeNode()
--	else
--		return tmpInstance:getFeatureParentTreeNode()
--	end
--end

function Translator.getDebugBase(base)
	if dataDevMode then
		return "palette.entities.botobjects.milestone"
	else
		return base
	end
end

function Translator.getDebugCreature(creature)
	if dataDevMode then
		return "object_milestone.creature"
	else
		return creature
	end
end


-- feature generic activate & deactivate 
function Translator.getFeatureActivationLogicAction(rtNpcGrp, action)
	if (action.Action.Type == "activate") then
		local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 1)
		local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 4)
		local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
		assert(retAction)
		return retAction, retAction
	elseif (action.Action.Type == "deactivate") then
		local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Active", 0)
		local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 5)
		local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
		assert(retAction)
		return retAction, retAction
	end
	return nil, nil
end

function Translator.getFeatureActivationLogicEvent(rtNpcGrp, event)

	local eventType = event.Event.Type
	if eventType == "activation" then
		return r2.Translator.getComponentUserEvent(rtNpcGrp, 4)
	elseif eventType == "deactivation" then
		return r2.Translator.getComponentUserEvent(rtNpcGrp, 5)
	end
	return nil, nil, nil
end

function Translator.getFeatureActivationCondition(condition, rtNpcGrp)
	if condition.Condition.Type == "is active" then
		local action1 = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 1);
		return action1, action1
	elseif condition.Condition.Type == "is inactive" then
		local action1 = r2.Translator.createAction("if_value_equal", rtNpcGrp.Id, "Active", 0);
		return action1, action1
	end
	return nil, nil
end


function Translator.translateFeatureActivation(instance, context)
	local rtNpcGrp = r2.Translator.getRtGroup(context, instance.InstanceId)
	assert(rtNpcGrp)
	if instance.Active and instance.Active == 1 then
		local action1 = r2.Translator.createAction("set_value",  rtNpcGrp.Id, "Active", 1)
		local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 4)
		local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
		r2.Translator.translateAiGroupEvent("start_of_state" , instance, context, retAction)
	else
		local retAction = r2.Translator.createAction("set_value",  rtNpcGrp.Id, "Active", 0)
		r2.Translator.translateAiGroupEvent("start_of_state" , instance, context, retAction)	
	end
end


function Translator.addActivationToTranslations(logicTranslations)
	if logicTranslations.ApplicableActions == nil then logicTranslations.ApplicableActions = {} end
	--logicTranslations.ApplicableActions.activate = {menu=i18n.get("uiR2EdActivate"):toUtf8(), text="activates"}
	--logicTranslations.ApplicableActions.deactivate = {menu=i18n.get("uiR2EdDesactivate"):toUtf8(), text="deactivates"}
	--logicTranslations.ApplicableActions.trigger = {menu=i18n.get("uiR2EdTrigger"):toUtf8(), text="triggers"}

	if logicTranslations.Events == nil then logicTranslations.Events = {} end
	--logicTranslations.Events.activation	= {menu=i18n.get("uiR2EdActivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdActivation")}
	--logicTranslations.Events.deactivation = {menu=i18n.get("uiR2EdDesactivation"):toUtf8(), text=r2:lowerTranslate("uiR2EdDesactivation")}
	--logicTranslations.Events.trigger = {menu=i18n.get("uiR2EdTrigger"):toUtf8(), text=r2:lowerTranslate("uiR2EdTrigger")}

	if logicTranslations.Conditions == nil then logicTranslations.Conditions = {} end
	--logicTranslations.Conditions["is active"] = {menu=i18n.get("uiR2EdIsActive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsActive")}
	--logicTranslations.Conditions["is inactive"]	= {menu=i18n.get("uiR2EdIsInactive"):toUtf8(), text=r2:lowerTranslate("uiR2EdIsInactive")}
	return logicTranslations
end


function Translator.CreateUserComponent(featureName)
	if not featureName or featureName == "" then
		debugInfo("Translator: calling createUserComponent on nil or empty featureName")
		return
	end

	local function posOk(x, y, z)
		debugInfo(string.format("Validate creation of '"..featureName.."' at pos (%d, %d, %d)", x, y, z))
		local component = r2.Features[featureName].createUserComponent( x, y)
		component.Texts = nil
		r2.requestInsertNode(r2:getCurrentAct().InstanceId, "Features", -1, "", component)
	end

	local function posCancel()
		debugInfo("Cancel choice '"..featureName.."' position")
	end

	r2:choosePos("object_component_user_event.creature", posOk, posCancel, "")	
end

function Translator.CheckPickedEntity(component, prop)
	local k, v = next(prop, nil)
	while k do
		local property = v
	
		if property.Type and property.Type == "RefId" then			
			local this = r2:getInstanceFromId(component.InstanceId)			

			local targetId = this[property.Name]

			if targetId ~= r2.RefId("") then
				debugInfo("targetId:" ..targetId)
				local filterFunc = "return " ..property.PickFunction .."('"..targetId.."')"
				debugInfo("filterfunc: " ..filterFunc)			
				local ok = loadstring(filterFunc)()
				if ok == false then
					debugInfo("name: " ..property.Name)
					r2.requestSetNode(this.InstanceId, property.Name, r2.RefId(""))	
				end

			end
		end
		k, v = next(prop, k)
	end
	
end



function Translator.checkActForPicking(componentId, entityId)
	local component = r2:getInstanceFromId(componentId)
	assert(component)
	--debugInfo("CheckActForPicking: EntityId =" ..entityId)
	--inspect(component)
	local entity = r2:getInstanceFromId(entityId)
	assert(entity)

	return entity:getParentAct().InstanceId == r2.Scenario.Acts[0].InstanceId 
	or entity:getParentAct().InstanceId == component:getParentAct().InstanceId
end


function Translator.getEventFromType(instance, context, eventType)
	if not context or not instance or not instance.getLogicEvent then return nil end
	local fakeEvent = {}
	fakeEvent.Class = "LogicEntityAction"
	fakeEvent.Event = {}
	fakeEvent.Event.Type = eventType
	return instance:getLogicEvent(context, fakeEvent)
end

----------------------------------------
--- TASK MODULE ------------------------
----------------------------------------

Translator.Tasks = {}

--Start of state (init) = event 7
function Translator.Tasks.startOfStateLogic(component, context, rtGrp)
	do
		local action = r2.Translator.createAction("user_event_trigger", rtGrp.Id, 7)
		r2.Translator.translateAiGroupEvent("start_of_state" , component, context, action)
	end
	
	do
		local repeatable = component.Repeatable
		if not repeatable then repeatable = 0 end

		local rtAction1 = r2.Translator.createAction("set_value",  rtGrp.Id, "Active", component.Active)
		local rtAction2 = r2.Translator.createAction("set_value",  rtGrp.Id, "v1", repeatable)
		local rtAction3 = r2.Translator.createAction("set_value",  rtGrp.Id, "v2", 0) 
		local rtAction3 = r2.Translator.createAction("set_value",  rtGrp.Id, "v3", 0) -- Success
		local rtAction = r2.Translator.createAction("multi_actions", { rtAction1, rtAction2, rtAction3,  } )
		r2.Translator.translateAiGroupEvent("user_event_7", component, context, rtAction)
	end
end

--Activation = event 4
function Translator.Tasks.activationLogic(component, context, rtGrp)
	do	
		local repeatable = component.Repeatable
		if not repeatable then repeatable = 0 end

		local rtAction1 = r2.Translator.createAction("set_value",  rtGrp.Id, "Active", 1)
		local rtAction2 = r2.Translator.createAction("set_value",  rtGrp.Id, "v1", repeatable)
		local rtAction3 = r2.Translator.createAction("set_value",  rtGrp.Id, "v2", 0) -- Success
		local rtAction = r2.Translator.createAction("multi_actions", { rtAction1, rtAction2, rtAction3,  } )
		r2.Translator.translateAiGroupEvent("user_event_4", component, context, rtAction)
	end
end

--Deactivation = event 5
function Translator.Tasks.deactivationLogic(component, context, rtGrp)
	do
		local rtAction = r2.Translator.createAction("multi_actions", {
				r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ),
				r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
				})
		r2.Translator.translateAiGroupEvent("user_event_5", component, context, rtAction)
	end
end

--When using talkTo, giveItem or requestItem actions, event 3 is emitted when the player took the missin (contextual validation)
function Translator.Tasks.setStatusLogic(component, context, rtGrp)
	do
		local action = r2.Translator.createAction("set_value", rtGrp.Id, "v2", 1 )
		r2.Translator.translateAiGroupEvent("user_event_3", component, context, action)
	end
end

--Success = event 9
--No broadcast means the broadcast action is done elsewhere in the translate (not on success)
function Translator.Tasks.successNoBroadcastLogic(component, context, rtGrp)
	do	
		--if repeatable	
		local action1 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 1,  
			r2.Translator.createAction("multi_actions", {
				r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1 ),
				r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
				r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
				})
			); 
		--if not repeatable
		local action2 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 0, 
			r2.Translator.createAction("multi_actions", {
				r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ) ,
				r2.Translator.createAction("set_value", rtGrp.Id, "v2", 2 ),
				r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
				r2.Translator.createAction("user_event_trigger", rtGrp.Id, 5),
				})
			); 
	
		local actions = r2.Translator.createAction("multi_actions", {action1, action2})	

		local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2, 
			r2.Translator.createAction("condition_if", r2:getNamespace()..rtGrp.Id..".Active == 1", actions))
		r2.Translator.translateAiGroupEvent("user_event_9", component, context, action)
	end
end

--Success with broadcast : for components using event 8 as an intermediate step.
function Translator.Tasks.successBroadcastLogic(component, context, rtGrp)
	local validationNeeded = component.ValidationNeeded

	local action2 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 1,  --if Repeatable
		r2.Translator.createAction("multi_actions", {
			r2.Translator.createAction("set_value", rtGrp.Id, "Active", 1 ),
			r2.Translator.createAction("set_value", rtGrp.Id, "v2", 0 ),
			r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
			})
		); 
	local action3 = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v1", 0,  -- if not Repeatable
		r2.Translator.createAction("multi_actions", {
			r2.Translator.createAction("set_value", rtGrp.Id, "Active", 0 ) ,
			r2.Translator.createAction("set_value", rtGrp.Id, "v2", 2 ),
			r2.Translator.createAction("set_value", rtGrp.Id, "v3", 1 ),
			r2.Translator.createAction("user_event_trigger", rtGrp.Id, 5)
			})
		); 
	
	local actions = {}
	if validationNeeded == 1 then
		actions = {action2, action3}
	else
		local baseAct = r2.Scenario:getBaseAct()
		local baseActRtGrp = r2.Translator.getRtGroup(context, baseAct.InstanceId)
		local actionBroadcast = r2.Translator.createAction("broadcast_msg",baseActRtGrp.Id, component:textAdapter(component.BroadcastText) )
	
		actions = {action2, action3, actionBroadcast}
	end
	local multiActions = r2.Translator.createAction("multi_actions", actions)
			
	local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2, 
		r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1, multiActions))
	r2.Translator.translateAiGroupEvent("user_event_9", component, context, action)
end

--When validation is needed, emit success event when targeting mission giver
function Translator.Tasks.validationByMissionGiver(component, giver, context, rtGrp)
	local rtGiverGrp = r2.Translator.getRtGroup(context, giver.InstanceId)
	assert(rtGiverGrp)
	do	
		local actionEvent = r2.Translator.createAction("user_event_trigger", rtGrp.Id, 9)
		
		local action1 = r2.Translator.createAction("npc_say", component:textAdapter(component.MissionSucceedText),   rtGiverGrp.Id ..":"..giver.Name)

		local action = r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 2, 
			r2.Translator.createAction("condition_if", r2:getNamespace()..rtGrp.Id..".Active == 1", 
			r2.Translator.createAction("multi_actions", {actionEvent, action1})))
		
		r2.Translator.translateAiGroupEvent("player_target_npc", giver, context, action)
	end
end

-- when receiving event 8, just broadcast a msg indicating that the mission is successful but that the player has 
-- to go back to the giver to complete it.
function Translator.Tasks.broadcastOnEvent8(component, context)
	local baseAct = r2.Scenario:getBaseAct()
	local baseActRtGrp = r2.Translator.getRtGroup(context, baseAct.InstanceId)
	local actionBroadcast = r2.Translator.createAction("broadcast_msg",baseActRtGrp.Id, component:textAdapter(component.BroadcastText) )
	
	r2.Translator.translateAiGroupEvent("user_event_8", component, context, actionBroadcast)
end

function Translator.Tasks.giverLogic(component, giver, context, rtGrp)
	local rtGiverGrp = r2.Translator.getRtGroup(context, giver.InstanceId)
	assert(rtGiverGrp)

	local actionWaitValidation = r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1,  -- Active
			 r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 1,  -- giver has been spoken to
				r2.Translator.createAction("multi_actions", {
				r2.Translator.createAction("npc_say", component:textAdapter(component.WaitValidationText),   rtGiverGrp.Id ..":"..giver.Name),
				r2.Translator.createAction("user_event_trigger", rtGrp.Id, 2)
		})))
		
	--say mission text + contextual text (talk to)
	local multiActions = r2.Translator.createAction("multi_actions", {
			r2.Translator.createAction("npc_say", component:textAdapter(component.MissionText),   rtGiverGrp.Id ..":"..giver.Name), 
			r2.Translator.createAction("talk_to", rtGrp.Id,  component:textAdapter(component.ContextualText)),
			})
	
	local actionTalkTo = r2.Translator.createAction("if_value_equal", rtGrp.Id, "Active", 1,  -- Active
		 r2.Translator.createAction("if_value_equal", rtGrp.Id, "v2", 0, multiActions))

	local rtAction = r2.Translator.createAction("multi_actions", {actionWaitValidation, actionTalkTo})

	r2.Translator.translateAiGroupEvent("player_target_npc", giver, context, rtAction)
end






























