r2.registerHighLevel = function()
	local classMapDescriptionVersion = 0
	
	local classMapDescription =
	{
		BaseClass="BaseClass",
		Name = "MapDescription",
		DisplayerUI = "",
		ersion = classMapDescriptionVersion,
		Prop =
		{			
			{Name="Title", Type="String", Category="uiR2EDRollout_Scenario"},
			{Name="LevelId", Type="String"},
			{Name="ShortDescription", Type="String", Category="uiREDRollout_"},
			{Name="OptimalNumberOfPlayer", Type="Number", Category="uiREDRollout_", Min="1", Max="10", Default="1"},
			{Name="Creator", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText"},
			{Name="CreatorMD5", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText"},

			{Name="CreationDate", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText"},
			{Name="OtherCharAccess", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText", DefaultValue="Full", DefaultInBase = 1 },
			{Name="NevraxScenario", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText", DefaultValue="0", DefaultInBase = 1 },
			{Name="TrialAllowed", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText", DefaultValue="0", DefaultInBase = 1 },
			{Name="ScenarioTag", Type="String", Category="uiREDRollout_", WidgetStyle = "StaticText", DefaultValue="", DefaultInBase = 1 },
		},
		
	
	}	


	local classScenarioVersionName = getClientCfgVar("BuildName")
	local classScenarioVersion = 4

	local classScenario =
	{
		--BaseClass="BaseClass",
		BaseClass="LogicEntity",
		Name = "Scenario",
		InEventUI = true,
		Version = classScenarioVersion,
		VersionName =classScenarioVersionName,
		BuildPropertySheet = false,
		Prop = 
		{	
			{Name="AccessRules", Type="String", WidgetStyle = "StaticText"},
			{Name="Description", Type="MapDescription"},
			{Name="Acts", Type="Table"},
			{Name="Locations", Type="Table"},
			{Name="Texts", Type="TextManager"},
			{Name="VersionName", Type="String", DefaultValue=classScenarioVersionName, Visible=false }, -- just a string			
			{Name="Versions", Type="Table"}, 
			{Name="UserComponents", Type="Table"}, 
			{Name="PlotItems", Type="Table"},
			{Name="Language", Type="String", DefaultValue="en", Visible=false},
			{Name="Type", Type="String", DefaultValue="so_story_telling", Visible=false},
			--{Name="TestRefId", Type="RefId", Category="uiR2EDRollout_Test"},
			{Name="ScenarioScore", Type="Number", DefaultValue="0", Min="0", Visible=false},
			{Name="Score", Type="Number"},
		},
		Parameters = {},
		ApplicableActions = { 
			--"Start Scenario Timing", "Stop Scenario Timing", "add scenario points", "succeed scenario", "fail scenario"
		},
		Events = {
		--	"on scenario succeeded", "on scenario failed"
		},
		Conditions = {
		--	"is active", "is finished"
		},
		TextContexts =		{},
		TextParameters =	{},
		LiveParameters =	{},
		----------------------------------------------------------------------------------------------------
		isDisplayModeOptionAvailable = function(this) return false end,
		----------------------------------------------------------------------------------------------------
		updateVersion = function(this, scenarioValue, currentValue)
			local patchValue = scenarioValue
			if patchValue < 1 then
				-- Patch only for old save (not the 0.0.3)
				if VersionName ~= "0.0.3" then
					-- TODO use identifier instead
					local oldValue = this.Description.LocationId
					local newValue = oldValue

					if 0 == oldValue  then 
						newValue = 1
					elseif 1 <= oldValue and oldValue <= 5 then
						newValue = oldValue + 2
					elseif 6 == oldValue then
						newValue =  9
					elseif 7 == oldValue then
						newValue =  11
					elseif 8 <= oldValue and oldValue <= 27 then
						newValue = oldValue + 5
					end
						
					r2.requestSetNode(this.Description.InstanceId, "LocationId", newValue)
				end	
				patchValue = 1
			end

			-- plot item feature
			if patchValue < 2 then
				r2.requestSetNode(this.InstanceId, "PlotItems", {})
				r2.requestSetNode(this.InstanceId, "UserComponents", {})				
				patchValue = 2
			end

			-- update of enum for scenario type
			if patchValue < 3 then
				if this.Type == nil or this.Type == "" then
					r2.requestSetNode(this.InstanceId, "Type", "so_story_telling")
				elseif this.Type == "Roleplay" then					
					r2.requestSetNode(this.InstanceId, "Type", "so_story_telling")
				elseif this.Type == "Combat" then
					r2.requestSetNode(this.InstanceId, "Type", "so_hack_slash")
				end
				patchValue = 3
			end

			-- patch for level
			if patchValue < 4 then
				if this.Description.LevelId == nil or this.Description.LevelId < 0 or this.Description.LevelId > 5 then					
					r2.requestSetNode(this.Description.InstanceId, "LevelId", 0)
				end					
				patchValue = 4
			end



			if patchValue == currentValue then return true end
			return false
		end,

		---------------------------------------------------------------------------------------------------------
		-- get name of tree icon 
		getContextualTreeIcon = function(this)
			return this:getTreeIcon()
		end,	
		
		-----------------------------------------------------------------------------
		getBaseAct = function(this)
			return this.Acts[0]
		end,

		getCurrentAct = function(this)
			return r2:getCurrentAct()
		end,
		-----------------------------------------------------------------------------
		-- from baseClass
		getDisplayName = function(this)
			return i18n.get("uiR2EDScenario")
		end,
		-----------------------------------------------------------------------------
		-- from baseClass
		isDeletable = function(this)
			return false
		end,
		-----------------------------------------------------------------------------
		--
		getBaseActLeftBudget = function(this)
			local maxValue = this:getMaxSecondaryActCost()
			return this.Description.MaxEntities - this:getBaseAct():getLocalCost() - maxValue
		end,
		-----------------------------------------------------------------------------
		-- Called by the C++ just before testing to see if the cost of this scenario is valid
		-- Should return true in this case
		-- If the scenario has a too high cost, then this function has the responsability to warn the player
		validateForTesting = function(this)
			if this:getMaxSecondaryActCost() < 0 then
				messageBox(i18n.get("uiR2EDScenarioBudgetExceeded"))
				return false
			else
				return true
			end
		end,
		-----------------------------------------------------------------------------
		--
		getMaxSecondaryActCost = function(this)
			local scenarioObj = r2.getScenarioObj()
			local max = 0
			local maxStatic = 0
			local first = true
			k,v = next(this.Acts,nil)
			while k~=nil do
				if first == true then
					first = false
				else
					if max < v:getLocalCost() then
							max = v:getLocalCost()
					end
					if maxStatic < v:getLocalStaticCost() then
						debugInfo("setting maxStatic")
						maxStatic = v:getLocalStaticCost()
					end
				end
				k,v=next(this.Acts,k)
			end

			return max, maxStatic
		end,
		-----------------------------------------------------------------------------
		-- returns a table with all objects of kind "kind" in the permanent act & current act
		getAllInstancesByType = function(this, kind)
			assert(type(kind) == "string")
			local result = {}			
			--this:delegate():appendInstancesByType(result, kind)
			r2.Classes.BaseClass.appendInstancesByType(this, result, kind)
			this.Acts[0]:appendInstancesByType(result, kind)
			local currAct = r2:getCurrentAct()
			if currAct ~= nil and currAct ~= this.Acts[0] then
				currAct:appendInstancesByType(result, kind)
			end
			return result				
		end,
		-----------------------------------------------------------------------------
		-- from baseClass
		completeSelectBarMenu = function(this, rootMenu)
			-- if all acts are not used, propose to create a new one
			--rootMenu:addSeparator()
			--r2:addMenuLine(rootMenu, this:getDisplayName(), "lua", "r2:setSelectedInstanceId('" .. this.InstanceId .."')", tostring(k), this:getSelectBarIcon(), 14)
			--rootMenu:addSeparator()
			--r2:addMenuLine(rootMenu, i18n.get("uiR2EDNewAct"), "lua", "r2.ScenarioWindow:newAct()", "new_act", "r2_icon_create.tga", 14)			
		end,
		-----------------------------------------------------------------------------
		-- from baseClass
		displayInSelectBar = function(this)
			return false -- don't display in the selection bar (only acts can be ...)
		end,
		--
		---------------------------------------------------------------------------------------------------------
		-- from base class		
		getFirstSelectBarSon = function(this)
			return r2:getCurrentAct():getFirstSelectBarSon()
		end,
		---------------------------------------------------------------------------------------------------------
		-- from base class		
		canHaveSelectBarSons = function(this)
			return false;
		end,
		---------------------------------------------------------------------------------------------------------
		-- from base class, update the item ui on first display
		onPostCreate = function(this)
			r2.PlotItemsPanel:reinit()
			r2.PlotItemDisplayerCommon:touch()
			if r2.Mode == "Edit" then
				-- if some element in the scenario are hidden, then display
				-- a message for the user to remember it
				-- local sons = {}
				-- this:getSons(sons)
				-- local showWarning = false
				-- for k, v in pairs(sons) do
				--	if type(v) == "userdata" and  v.isKindOf and v:isKindOf("WorldObject") and v.DisplayMode ~= 0 then
				--		showWarning = true
				--		break
				--	end
				-- end
				-- if showWarning then
				-- 	messageBox(i18n.get("uiR2EDDisplayModeMenuReminder"))
				-- end
				-- reset display modes
				r2.PrimDisplayFrozen = false
				r2.PrimDisplayVisible = true
				r2.PrimDisplayContextualVisibility = false
				r2.BotObjectsFrozen = false
				r2:setupFreezeBotObjectButton()
			end			
		end,

		onAttrModified = function(this, name)
			if this == r2.Scenario then
				if name ~= "Acts" then
					r2.ScenarioWindow:updateScenarioProperties()
				end

				if name=="Acts" and r2.Scenario:getCurrentAct()==r2.Scenario:getBaseAct() and r2.Scenario.Acts.Size>1 then
					r2.ScenarioWindow:setAct( r2.Scenario.Acts[1] )
				end
			end
		end,

		-----------------------------------------------------------------------------
		onErase = function(this)
			r2.acts.deleteOldScenario = false
		end,
		getName = function(this)
			if this.Ghost_Name then return this.Ghost_Name end
			return this.Name
		end,
	}

	----------------------------------------------------------------------------
	-- add a line to the event menu
	function classScenario.initLogicEntitiesMenu(this, logicEntityMenu)
		local name = i18n.get("uiR2EDScenario")
		logicEntityMenu:addLine(name, "lua", "", "Scenario")
	end

	----------------------------------------------------------------------------
	-- add a line to the event sub menu
	function classScenario.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction)
		local name = r2.Scenario:getName()
		subMenu:addLine(name, "lua", calledFunction.."('".. r2.Scenario.InstanceId .."')", r2.Scenario.InstanceId)
	end

	----------------------------------------------------------------------------
	-- add a line to the event menu
	function classScenario:getLogicTranslations()
		local logicTranslations = {
			["ApplicableActions"] = {
					--["Start Scenario Timing"]	= { menu=i18n.get( "uiR2AA0ScenarioStartTiming" ), 
					--						text=i18n.get( "uiR2AA1ScenarioStartTiming" )},
					--["Stop Scenario Timing"]	= { menu=i18n.get( "uiR2AA0ScenarioStopTiming" ), 
					--						text=i18n.get( "uiR2AA1ScenarioStopTiming" )},
					--["add scenario points"]	= { menu=i18n.get( "uiR2AA0ScenarioAddPoints" ), 
					--						text=i18n.get( "uiR2AA1ScenarioAddPoints" )},
					--["succeed scenario"]	= { menu=i18n.get( "uiR2AA0ScenarioSucceed" ), 
					--						text=i18n.get( "uiR2AA1ScenarioSucceed" )},
					--["fail scenario"]	= { menu=i18n.get( "uiR2AA0ScenarioFail" ), 
					--						text=i18n.get( "uiR2AA1ScenarioFail" )},
			},
			["Events"] = {	
				--["On Scenario Started"]	= { menu=i18n.get( "uiR2Event0ScenarioStart" ), 
				--							text=i18n.get( "uiR2Event1ScenarioStart" )},
				--["on scenario succeeded"]	= { menu=i18n.get( "uiR2Event0ScenarioSucceed" ), 
				--							text=i18n.get( "uiR2Event1ScenarioSucceed" )},
				--["on scenario failed"]	= { menu=i18n.get( "uiR2Event0ScenarioFailed" ), 
				--							text=i18n.get( "uiR2Event1ScenarioFailed" )},
			},
			["Conditions"] = {	
			}
		}
		return logicTranslations
	end
	
	function classScenario.initEventValuesMenu(this, menu, categoryEvent)	
		for ev=0,menu:getNumLine()-1 do

			local eventType = tostring(menu:getLineId(ev))

			if r2.events.eventTypeWithValue[eventType] == "Number" then
				menu:addSubMenu(ev)
				local subMenu = menu:getSubMenu(ev)
				local func = ""

				local lineNb = 0
				for i=1, 100, 20 do
					local lineStr = tostring(i).."/"..tostring(i+19)
					subMenu:addLine(lineStr, "", "", tostring(i))

					subMenu:addSubMenu(lineNb)
					local subMenu2= subMenu:getSubMenu(lineNb)
					for s=0, 19 do
						lineStr = tostring(i+s) 
						local func = "r2.events:setEventValue('','" .. categoryEvent .."','".. lineStr.."')"
						subMenu2:addLine(lineStr, "lua", func, lineStr)
					end
					lineNb = lineNb+1
				end
			end
		end
	end

	function classScenario.pretranslate(this, context)
		-- Nothing to do: Done by act[0]:pretranslate
	end

	function classScenario.translate(this, context)
		r2.Translator.translateAiGroup(this, context)
	end


	function classScenario.getLogicEvent(this, context, event)
		assert( event.Class == "LogicEntityAction") 

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

		local eventType = tostring(event.Event.Type)
		
		local eventHandler, firstCondition, lastCondition = nil, nil, nil
		
		local rtNpcGrp = r2.Translator.getRtGroup(context, r2.Scenario.Acts[0].InstanceId)
		assert(rtNpcGrp)

		if eventType == "On Scenario Started" then 
			return r2.Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)
		elseif eventType == "on scenario succeeded" then
			return r2.Translator.getComponentUserEvent(rtNpcGrp, 7)
		elseif eventType == "on scenario failed" then
			return r2.Translator.getComponentUserEvent(rtNpcGrp, 8)
		end
		
		return eventHandler, firstCondition, lastCondition
	end
	
	function classScenario.getLogicAction(entity, context, action)
		assert( action.Class == "ActionStep") 
		local component = r2:getInstanceFromId(action.Entity)
		assert(component)
		local rtNpcGrp = r2.Utils.getRtGroup(context, component.InstanceId)
		assert(rtNpcGrp)
		
		if (action.Action.Type == "Start Scenario Timing") then	
			local action = r2.Translator.createAction("start_scenario_timing")
			return action, action
		elseif (action.Action.Type == "Stop Scenario Timing") then	
			local action = r2.Translator.createAction("stop_scenario_timing")
			return action, action
		elseif (action.Action.Type == "add scenario points") then
			if not action.Action.ValueString then return end
			local points = tonumber(action.Action.ValueString)
			local baseAct = r2.Scenario:getBaseAct()
			local rtBaseActGrp = r2.Translator.getRtGroup(context, baseAct.InstanceId)

			local action = r2.Translator.createAction("add_scenario_points", rtBaseActGrp.Id, points)
			return action, action
		elseif action.Action.Type == "succeed scenario" then
			local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Success", 1)
			local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 7)
			local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
			assert(retAction)
			return retAction, retAction
		elseif action.Action.Type == "fail scenario" then
			local action1 = r2.Translator.createAction("set_value", rtNpcGrp.Id, "Success", 0)
			local action2 = r2.Translator.createAction("user_event_trigger", rtNpcGrp.Id, 8)
			local retAction = r2.Translator.createAction("multi_actions", {action1, action2})
			assert(retAction)
			return retAction, retAction
		end

		return r2.Translator.getFeatureActivationLogicAction(rtNpcGrp, action)
	end

	function classScenario.getLogicCondition(this, context, condition)
		assert( condition.Class == "ConditionStep") 
		local component = r2:getInstanceFromId(condition.Entity)
		assert(component)
		local rtNpcGrp = r2.Utils.getRtGroup(context, component.InstanceId)
		assert(rtNpcGrp)

		return r2.Translator.getFeatureActivationCondition(condition, rtNpcGrp)
	end



	function classScenario.getActIndex(this, actInstanceId)
		local index = 0
		local k, v = next(this.Acts)
		while k do
			if tostring(v.InstanceId) == actInstanceId then
				return index
			end
			index = index + 1
			k, v = next(this.Acts, k)
		end
		return -1
	end


	-- maps each season found in the list box season to an enum to pass to setEditorSeason
	r2.ListBoxSeasonToEditorSeason = 
	{
		[0] = "Automatic",
		[1] = "Spring",
		[2] = "Summer",
		[3] = "Autumn",
		[4] = "Winter"
	}	


	local classActVersion = 6

	local classAct =
	{
		BaseClass="LogicEntity",
		Name = "Act",
		InEventUI = true,	
		Menu="ui:interface:r2ed_base_menu",
		DisplayerUI = "R2::CDisplayerLua",
		DisplayerUIParams = "createActUIDisplayer",
		TreeIcon="r2ed_icon_act.tga",
		Version=classActVersion,
		Parameters = {},
		ApplicableActions = {
			"Start Act",
		},
		Events = {
			"On Act Started", 
			--"On Scenario Started", 
		},
		Conditions = {
		--	"is active", "is finished"
		},
		TextContexts =		{},
		TextParameters =	{},
		LiveParameters =	{},
		Prop = 
		{			
			{Name="Version", Type="Number", Visible=false, DefaultValue=tostring(classActVersion)},
			{Name="Features", Type="Table"},						
			{Name="Events",Type="Table"},

			-- following field are tmp for property sheet building testing
			-- {Name="PVP", Type="Number", WidgetStyle="Boolean", Category="uiR2EDRollout_Test" },
			-- {Name="Slider1", Type="Number", WidgetStyle="Slider", Category="uiR2EDRollout_Test"},
			-- {Name="Slider2", Type="Number", WidgetStyle="Slider", Category="uiR2EDRollout_Test"},
			-- {Name="ComboBox1", Type="Number", WidgetStyle="EnumDropDown",
			--	Enum= { "Toto", "Tata", "Titi" }
			--},
			-- {Name="ComboBox2", Type="Number", WidgetStyle="EnumDropDown",
			-- Enum= { "A", "B", "C" }
			-- },
			{Name="Title", Type="String", WidgetStyle = "StaticText"},
			{Name="Name", Type="String", MaxNumChar="25"},
			

			{Name="ActivitiesIds",Type="Table"},
			{Name="Counters",Type="Table"},
			{Name="ManualWeather", Type="Number", WidgetStyle="Boolean", DefaultValue="0",
			 Visible = function(act) return not act:isBaseAct() end,
			},
			{Name="WeatherValue", Type="Number", WidgetStyle="Slider", Min=0, Max=1022, -- The final value in the Rt datas is 0 for autiweather and 1-1023 for weather value ([1, 1023] range <=> [0, 1022])
			 Visible = function(act) return act.ManualWeather == 1 and not act:isBaseAct() end,
			},
			{Name="Season", Type="Number", WidgetStyle="EnumDropDown", DefaultValue="0", Visible=false,
			  Enum= { "uiR2EDSeasonAuto", "uiR2EDSpring", "uiR2EDSummer", "uiR2EDAutumn", "uiR2EDWinter" },			  
			},
			{Name="LocationId", Type="String", Visible=false},
			{Name="ShortDescription", Type="String", Visible=false},
			{Name="PreActDescription", Type="String", DefaultValue="", Visible=false, DefaultInBase=1},
		},

		updateVersion = function(this, scenarioValue, currentValue )
			local patchValue = scenarioValue
			if patchValue < 1 then
				r2.requestSetNode(this.InstanceId, "ManualWeather", 0)				
				r2.requestSetNode(this.InstanceId, "WeatherValue", 0)				
				patchValue = 1
			end

			if patchValue < 2 then
				if not this.Behavior then
					local behavior = r2.newComponent("LogicEntityBehavior")				
					r2.requestInsertNode(this.InstanceId, "", -1, "Behavior", behavior)	
					r2.requestSetNode(this.InstanceId, "InheritPos", 1)
					-- TODO Add position (0,0,0)
				end
				patchValue = 2

			end
			if patchValue < 3 then
				if not this.Name then
					r2.requestSetNode(this.InstanceId, "Name", this.Title)				
				end
				patchValue = 3
			end
			if patchValue < 4 then
				if not this.ExportList then
				--	r2.requestInsertNode(this.InstanceId, "", -1, "ExportList", {})
				end
				patchValue = 4
			end
			-- version 5 : Remove the "Cost" field -> hold locally now
			if patchValue < 5 then
				if this.Cost then
					r2.requestEraseNode(this.InstanceId, "Cost", -1)
				end
				if this.StaticCost then
					r2.requestEraseNode(this.InstanceId, "StaticCost", -1)
				end
				patchValue =  5
			end
			
			if patchValue < 6 then
				if this.ExportList then
					r2.requestEraseNode(this.InstanceId, "ExportList", -1)
				end
				patchValue = 6
			end

			if patchValue == currentValue then return true end
			return false
		end,
		-----------------------------------------------------------------------------	
		canChangeDisplayMode = function(this)
			return false
		end,	
		-----------------------------------------------------------------------------
		onActChanged = function(this)
			assert(this)
			if this == r2:getCurrentAct() then					
				r2.acts:updatePaletteFromEcosystem()
				r2.ScenarioWindow:updateActProperties()	
			end
		end,
		-----------------------------------------------------------------------------
		onAttrModified = function(this, name)			
			if name == "Features" or Name == "Events" then
				-- ignore messages triggeered by sons for the update of the property window
				return
			end
			r2.ScenarioWindow:updateActProperties()
		end,
		-----------------------------------------------------------------------------
		onErase = function(this)

			this.User.Deleted = true

			if this.User.DeleteInProgress == true then return end

			this.User.DeleteInProgress = true
			this:setDeleteActionName()
			-- assume than on delete can only be called if this act is selected
			--assert(this:isSameObjectThan(r2:getCurrentAct()))

			-- update name of acts in act combo box 
			local afterDeletedAct = false
			for i=0, r2.Scenario.Acts.Size-1 do
				local act = r2.Scenario.Acts[i]
				if afterDeletedAct then
					r2.ActUIDisplayer:updateActName(act)
				elseif act==this then
					afterDeletedAct = true
				end
			end

			-- if Act[1] exists go to act1
			if not r2.acts.deleteOldScenario then
				if (table.getn(r2.Scenario.Acts) > 1) and (this~=r2.Scenario.Acts[1])  then
					r2.ScenarioWindow:setAct( r2.Scenario.Acts[1] )
				else
					r2:setCurrentActFromId(r2.Scenario:getBaseAct().InstanceId)

					if r2.logicComponents.undoRedoInstances[this.InstanceId] and (table.getn(r2.Scenario.Acts) <= 2) then
						r2.acts:openScenarioActEditor(false, true, true)
					end
				end
			end

			if r2.logicComponents.undoRedoInstances[this.InstanceId] then
				r2.logicComponents.undoRedoInstances[this.InstanceId] = nil
			end	
		end,

		-----------------------------------------------------------------------------
		updateWeather = function(this)					
			if this==r2:getCurrentAct() and this.WeatherValue and this.ManualWeather then
				setWeatherValue(this.ManualWeather == 0, this.WeatherValue / 1022)
			end
		end,
		-----------------------------------------------------------------------------
		accept = function(this, targetInstance)
			if targetInstance:isKindOf("BanditCampFeature") then
				return "Features"
			else
				return nil
			end			
		end,
		getSelectBarIcon = function(this)
			return "r2ed_icon_act.tga"
		end,
		-----------------------------------------------------------------------------
		isBaseAct = function(this)
			local parentScenario = this:getParentScenario()
			if not parentScenario then return false end
			return this:isSameObjectThan(parentScenario:getBaseAct())
			--return this == this:getParentScenario():getBaseAct()
		end,
		
		-----------------------------------------------------------------------------
		-- get the tree control where object other than botobject are inserted in this act
		getContentTree = function(this)			
			return this.User.ContentTree
		end,

		-----------------------------------------------------------------------------
		-- get the tree control where macro components are inserted in this act
		getMacroContentTree = function(this)	
			return this.User.MacroContentTree
		end,

		-----------------------------------------------------------------------------
		-- get the tree control where object other than botobject are inserted in this act
		getContentTreeNodes = function(this, nodeName)	
		
			local nodes = {}
			if this:isBaseAct() then
				local acts = this.Parent
				if acts.Size>1 then
					for i=1, acts.Size-1 do
						if acts[i]:getContentTree() then
							local node 
							if nodeName then
								node = acts[i]:getContentTree():getRootNode():getNodeFromId(nodeName)
							else
								node = acts[i]:getMacroContentTree():getRootNode()
							end
							nodes[acts[i].InstanceId] = node
						else
							return nil
						end
					end
				end
			else
				local node 
				if nodeName then
					node = this:getContentTree():getRootNode():getNodeFromId(nodeName)
				else
					node = this:getMacroContentTree():getRootNode()
				end
				nodes[this.InstanceId] = node
			end	
			return nodes
		end,

		-----------------------------------------------------------------------------
		-- get the default feature for this act
		getDefaultFeature = function(this)
			assert(this.Features[0]:isKindOf("DefaultFeature"))
			return this.Features[0]
		end,
		-----------------------------------------------------------------------------		
		hasScenarioCost = function(this)
			return true
		end,

		getName = function(this)
			assert(this)

			local name = this.Name
			local actNb = r2.logicComponents:searchElementIndex(this)-1

			local firstPart = i18n.get("uiR2EDDefaultActTitle").. actNb 
			local firstPartSpace = i18n.get("uiR2EDDefaultActTitle").. " " .. actNb 
			if name=="" then
				name = firstPartSpace
			elseif string.lower(name)==string.lower(firstPart) or string.lower(name)==string.lower(firstPartSpace) then
			else
				name = firstPartSpace .. ":" .. name
			end

			return name
		end,
		setName = function(this, value)
			assert(this)
			this.Name = value
		end,
		-----------------------------------------------------------------------------		
		-- from baseClass
		getDisplayName = function(this)
			if this:isBaseAct() then
				return i18n.get("uiR2EDBaseAct")
			end
			return this:getName()
		end,
		-----------------------------------------------------------------------------
		-- from baseClass
		isDeletable = function(this)
			return not this:isBaseAct()
		end,
		---------------------------------------------------------------------------------------------------------
		-- called when the instance is selected (default is no op)
		onSelect = function(this, selected)
			if selected and this ~= r2:getCurrentAct() then
				-- act was changed from the select bar, update editor state	
				r2.ScenarioWindow:setAct(this)
			end
		end,
		---------------------------------------------------------------------------------------------------------
		-- from baseClass : 
		-- special : the scenario is not displayed in the select bar, but serves as a 'root' for enumeration so
		-- we return it when acts menu is popped in the selectbar, so that acts can be enumerated
		getFirstSelectBarParent = function(this)
			return this.ParentInstance
		end,
		---------------------------------------------------------------------------------------------------------
		-- from baseClass :
		getSelectBarSons = function(this)
			return this.Features
		end,
		
		---------------------------------------------------------------------------------------------------------
		-- from BaseClass
		getParentAct = function(this)
			return this
		end	
	}

	function classAct.getActivitiesIds(this)
		local actActivitiesIds = {}
		local k, v = next(this.Features, nil)
		while k do
			local activitiesIds = {}
			if v.getActivitiesIds then
				activitiesIds = v:getActivitiesIds()
				table.merge(actActivitiesIds, activitiesIds)
			end
			k, v = next(this.Features, k)
		end
		return actActivitiesIds
	end

	function classAct.getWorldPos(this)
		return { x = 0, y = 0, z = 0 }
	end

	----------------------------------------------------------------------------
	-- add a line to the event sub menu
	function classAct.initLogicEntitiesInstancesMenu(this, subMenu, calledFunction)

		local empty = true
		local actsTable = r2.Scenario.Acts 

		for i=0, r2.Scenario.Acts.Size-1 do
			local act = r2.Scenario.Acts[i]
			if not act:isBaseAct() then
				subMenu:addLine(act.Name, "lua", calledFunction.."('".. act.InstanceId .."')", act.InstanceId)
				empty = false
			end
		end

		if empty==true then
			subMenu:addLine(i18n.get("uiR2EdNoSelelection"), "", "", "")
		end
	end

	----------------------------------------------------------------------------
	-- add a line to the event menu
	function classAct:getLogicTranslations()
		local logicTranslations = {
			["ApplicableActions"] = {
				["Start Act"]			= { menu=i18n.get( "uiR2AA0ActStart"	), 
											text=i18n.get( "uiR2AA1ActStart"	)},
			},
			["Events"] = {	
				["On Act Started"]		= { menu=i18n.get( "uiR2Event0ActStart"	), 
											text=i18n.get( "uiR2Event1ActStart"	)},
			},
			["Conditions"] = {	
			}
		}
		return logicTranslations
	end

	-----------------------------------------------------------------------------
	-- eval the used quota for this act alone
	function classAct.getUsedQuota(this)
		return this:getLocalCost()
	end	

	-----------------------------------------------------------------------------
	function classAct.appendInstancesByType(this, destTable, kind)				
		assert(type(kind) == "string")
		--this:delegate():appendInstancesByType(destTable, kind)
		r2.Classes.BaseClass.appendInstancesByType(this, destTable, kind)
		for key, feature in specPairs(this.Features) do	
			feature:appendInstancesByType(destTable, kind)
		end
	end
	-----------------------------------------------------------------------------
	function classAct.onDelete(this)
		if this.User.DeleteInProgress == true then return end

		-- assume than on delete can only be called if this act is selected
		assert(this:isSameObjectThan(r2:getCurrentAct()))

		r2.ScenarioWindow:deleteAct()	
	end

	-----------------------------------------------------------------------------
	-- return the left quota to add content into this act
	function classAct.getLeftQuota(this)
		if this:isBaseAct()
		then
			local maxValue, maxValue2 = this:getParentScenario():getMaxSecondaryActCost()
			local leftQuota = r2.getMaxNpcs() - this:getLocalCost() - maxValue
			local leftStaticQuota = r2.getMaxStaticObjects() - this:getLocalStaticCost() - maxValue2

			return leftQuota, leftStaticQuota
		else
			--return this:getParentScenario().Description.MaxEntities - this:getParentScenario():getBaseAct().Cost - this.Cost
			local cost =  r2.getMaxNpcs() - this:getParentScenario():getBaseAct():getLocalCost() - this:getLocalCost()
			local staticCost = r2.getMaxStaticObjects() - this:getParentScenario():getBaseAct():getLocalStaticCost() - this:getLocalStaticCost()

			return cost, staticCost 
		end
	end

	function classAct.getActId(this)
		assert(this)
		local parent = this:getParentScenario()
		local id = -1;
		local k,v = next(parent.Acts, nil)
		while k do
			id = id + 1
			if this:isSameObjectThan(v) then
				return id
			end
			k,v = next(parent.Acts, k)
		end
		return id -- -1
		
	end

	function classAct.getLogicAction(entity, context, action)
		
		assert( action.Class == "ActionStep") 
		local component = r2:getInstanceFromId(action.Entity)
		assert(component)
		local rtNpcGrp = r2.Translator.getRtGroup(context, component.InstanceId)
		assert(rtNpcGrp)
		local  firstAction, lastAction = nil, nil
		if action.Action.Type == "Start Act" then
			firstAction, lastAction = r2.Translator.createAction("dssStartAct", entity:getActId()) 
			assert(firstAction)
			assert(lastAction)
		end
		
		return firstAction, lastAction
	end


	function classAct.getLogicEvent(this, context, event)
		assert( event.Class == "LogicEntityAction") 

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

		local eventType = tostring(event.Event.Type)
		
		local eventHandler, lastCondition = nil, nil

		if eventType == "On Act Started" then 
			return r2.Translator.createEvent("timer_t0_triggered", "",  rtNpcGrp.Id)
		end
		
		
		return eventHandler, firstCondition, lastCondition
	end

	function classAct.getLogicCondition(this, context, condition)
		return nil
	end


	----------------------------------------------------------------------------
	-- Create a controler for the current Act
	--
	function classAct.pretranslate(this, context)
		r2.Translator.createAiGroup(this, context)
	end

	function classAct.translate(this, context)
		entity = this
		
		if this:isBaseAct() then
			local baseAct = this:getParentScenario():getBaseAct()
			local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
			local rtAction = r2.Translator.createAction("set_scenario_points", rtNpcGrpBase.Id )
			
			r2.Translator.translateAiGroupEvent("timer_t1_triggered", this, context, rtAction)
		end


		if not this:isBaseAct() then
			r2.Translator.translateAiGroup(entity, context)
			local rtNpcGrp = r2.Translator.getRtGroup(context, entity.InstanceId)
			local baseAct = this:getParentScenario():getBaseAct()
			local rtNpcGrpBase = r2.Translator.getRtGroup(context, baseAct.InstanceId)
			local index = context.Scenario:getActIndex(this.InstanceId)

			local rtAction = r2.Translator.createAction("act_starts", rtNpcGrp.Id, rtNpcGrpBase.Id, index)
			r2.Translator.translateAiGroupInitialState(entity, context, rtAction)
		end
	end
	
	local classLocationVersion = 1
	local classLocation =
	{
		Version = classLocationVersion,
		BaseClass="BaseClass",
		Name = "Location",
		Prop = 
		{			
			{Name="IslandName", Type="String"},
			{Name="ShortDescription", Type="String"},
			{Name="Time", Type="Number"},
			{Name="EntryPoint", Type="String"},
			{Name="Season", Type="String", DefaultValue=""},
			{Name="ManualSeason", Type="Number", WidgetStyle="Boolean", DefaultValue="0" }, 
		},

		onCreate = function(this)
			this:updateSeason()	
		end,

		onAttrModified = function(this, name)	
			if not r2:getCurrentAct() then return end
			if this.InstanceId == r2:getCurrentAct().LocationId then
				if name == "Season" then
					this:updateSeason()
				end
			end

		end,

		updateSeason = function(this)		
		
			-- change season in the editor
			-- effect may be seen only at the next teleport message if we're joining a session
			local season = this.Season
			if this.ManualSeason == 0 then season="Automatic" end
			--inspect(season)
			r2:setEditorSeason(season)				
		end,

		updateVersion = function(this, scenarioValue, currentValue )
			local patchValue = scenarioValue
			if patchValue < 1 then
				local updateMap = { ["summer"] = "Summer", ["winter"] = "Winter", ["fall"] = "Autumn", ["spring"] = "Spring",
				 ["Summer"] = "Summer", ["Winter"] = "Winter", ["Autumn"] = "Autumn", ["Spring"] = "Spring"}
				if (this.ManualSeason == 1 ) then
					if updateMap[ this.Season ]  then
						r2.requestSetNode(this.InstanceId, "Season", updateMap[this.Season])
					else
						debugInfo("Wrong conversion function")
						assert(nil);
					end
				end
				patchValue = 1
			end			
			if patchValue == currentValue then return true end
			return false
		end,	

	}

	local classState =
	{
		Name="State",
		Prop=
		{
			{Name="InstanceId", Type="String"},
			{Name="Name", Type="String" },
			{Name="Behavior",Type="Behavior"}
		}	
	}
	
	r2.registerComponent(classMapDescription)
	r2.registerComponent(classScenario)
	r2.registerComponent(classAct)
	r2.registerComponent(classState)
	r2.registerComponent(classLocation)
end




--r2.Features.Act = {}
--
--local feature = r2.Features.Act
--
--function mergeTraduction(localLogicEntityAttributes)
--	local k, v = next(localLogicEntityAttributes, nil)
--	while k do
--		local k2, v2 = next(v, nil)
--		while k2 do
--			if not r2.logicEntityAttributes[k][k2] then
--				r2.logicEntityAttributes[k][k2] = v2
--			end
--			k2, v2 = next(v, k2)
--		end
--		k, v = next(localLogicEntityAttributes, k)
--	end
--end
--
--
--function feature:init()
--	-- register trad
--	local localLogicEntityAttributes = {
--		["ApplicableActions"] = {	
--			["Start Act"]	= i18n.get("uiR2EdStartAct"), 
--		},
--		["Events"] = {	
--			["On Act Started"]		= i18n.get("uiR2EdOnActStarted"),
--		},
--		["Conditions"] = {	
--		}
--	}
--	mergeTraduction(localLogicEntityAttributes)
--end
--
--feature.init()
--
--r2.Features["Act"] = feature
--

-----------------------------------------------
-- Not Save to disc so not version number needed

r2.registerBasicBricks=function()
	local classRtScenario =
	{
		Name = "RtScenario",
		Prop =
		{
			{Name="Acts", Type="Table"},
			{Name="Texts", Type="RtTextManager"},
			{Name="PlotItems", Type="Table"},
			{Name="Locations", Type="Table"}
		}
	}

	r2.registerComponent(classRtScenario)

	local classRtAct =
	{	
		Name="RtAct",
		Prop=
		{
			{Name="Id", Type="String"},
			{Name="NpcGrps", Type="Table"},
			{Name="FaunaGrps", Type="Table"},
			{Name="AiStates", Type="Table"},
			{Name="Npcs", Type="Table"},
			{Name="Events",Type="Table"},
			{Name="Actions", Type="Table"},
			{Name="WeatherValue", Type="Number"},
			{Name="Name", Type="String"},
			{Name="IslandName", Type="String"},
			{Name="Season", Type="Number"},
			{Name="LocationId", Type="Number"},
			{Name="UserTriggers", Type="Table"}
		}
	}
	r2.registerComponent(classRtAct)

	local classRtLocation =
	{	
		Name="RtLocation",
		Prop=
		{
			{Name="Id", Type="String"},
			{Name="Island", Type="String"},
			{Name="EntryPoint", Type="String"},
			{Name="Season", Type="Number"},
		}
	}
	r2.registerComponent(classRtLocation)

	do
		local classRt =
		{	
			Name="RtUserTrigger",
			Prop=
			{
				{Name="Id", Type="String"},
				{Name="Name", Type="String"},
				{Name="Grp", Type="String"},
				{Name="TriggerId", Type="Number"},
			}
		}
		r2.registerComponent(classRt)

	end
	
	local classRtNpcGrp =
	{
		Name = "RtNpcGrp",
		Prop = 
		{
			{Name="Id", Type="String"},
			{Name="Name", Type="String"},
			{Name="Children", Type="Table"},
			{Name="AutoSpawn", Type="Number", DefaultValue="1"},
			{Name="BotChat_parameters", Type="String"},
			{Name="BotEquipment", Type="String"},
			{Name="BotSheetClient", Type="String"},
			{Name="BotVerticalPos", Type="String", DefaultValue="auto"},
			{Name="Count", Type="Number"},
			{Name="GrpKeywords", Type="String"},
			{Name="AiProfilParams", Type="String"},
			{Name="GrpParameters", Type="String"},

		}
			
	}

	r2.registerComponent(classRtNpcGrp)

	local classRtNpc =
	{
		Name = "RtNpc",
		Prop =
		{
			{Name="Id", Type="String", DefaultValue="" },
			{Name="Name", Type="String" },
			{Name="Children", Type="Table" },
			{Name="ChatParameters", Type="String" },
			{Name="Equipment", Type="Table" },
			{Name="IsStuck", Type="Number" },
			{Name="Keywords", Type="String" },
			{Name="Sheet", Type="String" },
			{Name="SheetClient", Type="String" },
			{Name="BotVerticalPos", Type="String", DefaultValue="auto" },
			{Name="Angle", Type="Number" },
			{Name="DmProperty", Type="Number"},
			{Name="Pt", Type="RtPosition" },
		}
	}

	r2.registerComponent(classRtNpc)
	
	local classRtPosition =
	{
		Name = "RtPosition",
		Prop =
		{
			{Name="x", Type="Number" },
			{Name="y", Type="Number" },
			{Name="z", Type="Number" },
		}
	}

	r2.registerComponent(classRtPosition)
	



	local classRtAiState  =
	{
		Name = "RtAiState",
		Prop = 
		{
			{Name="Id", Type="String", DefaultValue="" },
			{Name="Name", Type="String" },
			{Name="Children", Type="Table" },
			{Name="AiActivity", Type="String", DefaultValue="no_change" },
			{Name="AiMovement", Type="String", DefaultValue="" },
			{Name="AiProfileParams", Type="Number" },
			{Name="Keywords", Type="String" },
			{Name="VerticalPos", Type="String", DefaultValue="auto" },
			{Name="Pts", Type="Table" },
			{Name="Reactions",Type="Table"}
		}
	}



	r2.registerComponent(classRtAiState)

	local classRtNpcEventHandler =
	{
		Name = "RtNpcEventHandler",
		Prop =
		{
			{Name="Id", Type="String", DefaultValue="" },
			{Name="Name",Type="String"},
			{Name="Event", Type="String"},
			{Name="StatesByName",Type="String"},
			{Name="GroupsByName",Type="String"},
			{Name="ActionsId", Type="Table"}
		}
	}

	r2.registerComponent(classRtNpcEventHandler)

	local classRtNpcEventHandlerAction =
	{
		Name = "RtNpcEventHandlerAction",
		Prop =
		{
			{Name="Id", Type="String", DefaultValue="" },
			{Name="Action", Type="String"},
			{Name="Name", Type="String"},
			{Name="Parameters", Type="String"},
			{Name="Children",Type="Table"},
			{Name="Weight",Type="Number",DefaultValue="1"}
		} 
	}

	r2.registerComponent(classRtNpcEventHandlerAction)

local classRtFauna =
	{
		Name= "RtFauna",
		Prop=
		{
			{Name="Id", Type="String", DefaultValue=""},
			{Name="Name",Type="String"},
			{Name="Pts", Type="Table" },
			{Name="Children", Type="Table"}
		}
	}
	r2.registerComponent(classRtFauna)

	local classRtGroupFaunaEx =
	{
		Name="RtGroupFaunaEx",
		Prop=
		{
			{Name="Id",Type="String",DefaultValue=""},
			{Name="Name",Type="String"},
			{Name="FaunaType",Type="String",DefaultValue="HERBIVORE"},
			{Name="Children", Type="Table"}
		}
	}
	r2.registerComponent(classRtGroupFaunaEx)


	local classRtFaunaGenericPlace =
	{
		Name="RtFaunaGenericPlace",
		Prop=
		{
			{Name="Id",Type="String",DefaultValue=""},
			{Name="Name",Type="String"},
			{Name="FlagFood",Type="String",DefaultValue="true"},
			{Name="FlagRest",Type="String",DefaultValue="true"},
			{Name="FlagSpawn",Type="String",DefaultValue="true"},
			{Name="Index",Type="Number"},
			{Name="IndexNext",Type="Table"},
			{Name="Place",Type="Place"}
		}
	}
	r2.registerComponent(classRtFaunaGenericPlace)

	local classRtPopulation =
	{
		Name = "RtPopulation",
		Prop=
		{
			{Name="Id",Type="String",DefaultValue=""},
			{Name="Name",Type="String"},
			{Name="Children",Type="Table"}
		}
	}
	r2.registerComponent(classRtPopulation)

	local classRtPeople =
	{
		Name="RtPeople",
		Prop=
		{
			{Name="Name",Type="String"},
			{Name="Count",Type="Number"},
			{Name="CreatureCode",Type="String"}
		}
	}
	r2.registerComponent(classRtPeople)

	local classRtTextManager =
	{	
		Name="RtTextManager",
		Prop=
		{
			{Name="Id", Type="String"},
			{Name="Texts", Type="Table"},
		}
	}

	r2.registerComponent(classRtTextManager)

	local classRtEntryText =
	{
		Name="RtEntryText",
		Prop=
		{
			{Name="Id", Type="String"},
			{Name="Text", Type="String"}
		}
	}

	r2.registerComponent(classRtEntryText)


	-- Copy struct TMissionItem
	local classRtPlotItem =
	{
		Name = "RtPlotItem",
		Prop =
		{
			{Name="Id", Type="String"},
			{ Name="SheetId", Type="Number" },
			{ Name="Name", Type="String" },
			{ Name="Description", Type="String" },
			{ Name="Comment", Type="String" }
		}
	}
	r2.registerComponent(classRtPlotItem)

end
	
		
