-----------------------------------------------------------------------
-- the table where all the functions/methods go to
-----------------------------------------------------------------------
Global = {
   quest,
   name,
   locations,
   iactors,
   inventory,
   triggers,
   conversations,
   cutscenes,
   checklist
}
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- init function
-----------------------------------------------------------------------
function Global:init()
   local questName = "Global"
   -- the quest object stores the C++ object pointer (Quest object)
   self.quest = QuestMgr:createQuest(questName)
   self.name  = questName
   
   -- the locations associated with this quest
   self.locations = {
      "bazar",
      "giza",
      "palace_garden",
      "sphinx_inside",
      "sphinx_outside",
      "palace_gate",
      "oasis",

      "desert_plain",
      "desert_rock",
      "desert_crossing"
   }
   -- the interactor objects associated with this quest
   self.iactors = {
      "char_jackal",
      "char_bigcop",
      "char_bulbul",
      "char_burgerman",
      "char_blackeye",
      "char_dinar",
--      "char_egyptian",
      "char_father",
      "char_girlie",
      "char_granny",
      "char_nubian",
      "char_prisoner",
      "char_raseltin",
      "char_far_el_matu",
      "char_mut_el_tebtyns",
      "char_slavedriver",
      "char_slave",
      "char_seeker",
      "char_smallcop",
      "char_pharao",
      "char_tailor",
      "char_tarok",
      "char_thara",
      "char_assil",
      "char_bakshish",
      "char_volcano",
      "char_wineman",
      "char_gordon",
      "char_osiris",
      "char_badawi",
      "char_scarabking",
      "char_schmuel",
      "char_ephraim",
      "char_shalom",
      "char_caravanleader",
      "char_genie",
      
      "char_egyptian_1",
      "char_egyptian_2",

      "item_silver_coin",

      "animobj_iactor_key",
      "item_flute",

      "item_treasure_map",
      "item_cloak_dirty",
      "iactor_home_hanging_basket",
      "item_cloak_noble",
      "item_brush_broken",
      "item_treasure_dirty",
      "item_camel_hair",
      "item_skull",
      "item_croc_purse",
      "item_croc_teeth",
      "item_skull",
      "item_stone_arm",
      "char_crocodile",
      "item_shirt_hawai",
      "item_pirate_flag",
      "item_hanger",
      "iactor_palace_prison_cell_to_palace_prison_tunnel",
      "iactor_palace_gate_entrance_to_palace_courtyard",
      "animobj_bazar_water_plane",
      "iactor_giza_camel_o_wash",

      "iactor_palace_gate_street_to_palace_gate_entrance",

      "animobj_palace_garden_water_plane",
      "animobj_palace_garden_crank"
   }

   -- the conversations associated with this quest
   self.conversations = {
      "Standard_dinar_noble_shop",
      "SunOfCairo_bakshish_quest",
      "Standard_slave",
      "Standard_slavedriver",
      "Final_pharaoh",
      "Final_bakshish"
   }
   
   -- the cutscenes associated with this quest
   self.cutscenes = {
   }

   -- the checklist of little tasks associated with this quest
   self.checklist = {
      "SpokenToDinarOnce",
      "SeekerProblemDiscussed",
      "SlaveToldStory",

      "GlobalRaseltinLoopRunning",
      "GlobalRaseltinLoopBlocked",
      "GardenGordonLoopRunning",
      "GardenGordonLoopBlocked",

      -- TL
      "Egyptian1WalkActive",
      "Egyptian1WalkToGirliePending",
      "Egyptian1WalkOffPending",
      "Egyptian2WalkActive",
      "Egyptian2WalkToTailorPending",
      "Egyptian2WalkOffPending",
      "GrannyWalkActive",
      "PalaceGateIntroduced",

      -- and ultimately
      "QuestSolved"
   }

   ------------------------- Global Assil/Thara close trigger -------------------

   local trig_args = ProximityTriggerArgs("myArgs")
   trig_args.entity1  = "char_assil"
   trig_args.entity2  = "char_thara"
   trig_args.distance = 75
   trig_args.lua_func = "Global:onAssilCloseToThara"
   trig_args.single_shot = false
   EventTriggerMgr:createProximityEventTrigger("trig_assil_thara", trig_args)
   --EventTriggerMgr:subscribeEventTriggerEvent("trig_assil_thara", "EventProximityAreaEntered",
	--				      "Global:onAssi

   -- create a proximity trigger for the slavedriver/slave conversation
   local trig_args = ProximityTriggerArgs("myArgs")
   trig_args.entity1 = "char_assil"
   trig_args.entity2 = "char_slave"
   trig_args.distance = 1000
   trig_args.lua_func = "Global:startSlaveConversationLoop"
   trig_args.single_shot = false
   EventTriggerMgr:createProximityEventTrigger("trig_bazar_slave_loop", trig_args)
   EventTriggerMgr:subscribeEventTriggerEvent("trig_bazar_slave_loop", "EventProximityAreaLeft", 
					      "Global:stopSlaveConversationLoop", false)
   self.quest:addTrigger("trig_bazar_slave_loop", "bazar")

   -- create a proximity trigger for gordon
   local trig_args = ProximityTriggerArgs("myArgs")
   trig_args.entity1 = "char_assil"
   trig_args.entity2 = "char_gordon"
   trig_args.distance = 1000
   trig_args.lua_func = "Global:startGordonConversationLoop"
   trig_args.single_shot = false
   EventTriggerMgr:createProximityEventTrigger("trig_palace_garden_gordon_loop", trig_args)
   EventTriggerMgr:subscribeEventTriggerEvent("trig_palace_garden_gordon_loop", "EventProximityAreaLeft", 
					      "Global:stopGordonConversationLoop", false)
   self.quest:addTrigger("trig_palace_garden_gordon_loop", "palace_garden")
   EventTriggerMgr:setEventTriggerMuted("trig_palace_garden_gordon_loop",true)

   ----------------------- Egyptian Walk -----------------------
   
   local trig_args = ProximityTriggerArgs("char_assil")
   trig_args.entity1 = "char_assil"
   trig_args.entity2 = "char_egyptian_1"
   trig_args.distance = 550
   trig_args.lua_func = "Global:onAssilGetsCloseToEgyptian1"
   trig_args.single_shot = false
   EventTriggerMgr:createProximityEventTrigger("trig_bazar_peasant_a_prox", trig_args)
   --EventTriggerMgr:subscribeEventTriggerEvent("trig_bazar_peasant_a_prox", "EventProximityAreaLeft", 
	--				      "Global:startEgyptian1WalkLoop", false)
   self.quest:addTrigger("trig_bazar_peasant_a_prox", "bazar")

   local trig_args = ProximityTriggerArgs("char_assil")
   trig_args.entity1 = "char_assil"
   trig_args.entity2 = "char_egyptian_2"
   trig_args.distance = 600
   trig_args.lua_func = "Global:onAssilGetsCloseToEgyptian2"
   trig_args.single_shot = false
   EventTriggerMgr:createProximityEventTrigger("trig_bazar_peasant_b_prox", trig_args)
   EventTriggerMgr:subscribeEventTriggerEvent("trig_bazar_peasant_b_prox", "EventProximityAreaLeft", 
					      "Global:startEgyptian2WalkLoop", false)
   self.quest:addTrigger("trig_bazar_peasant_b_prox", "bazar")

   ----------------------- /Egyptian Walk -----------------------

   -- associate the locations with the quest
   for key, value in ipairs(self.locations) do
      self.quest:addLocation(value)
   end
   -- associate the interactors with the quest
   for key, value in ipairs(self.iactors) do
      self.quest:addInteractor(value)
   end
   -- associate the conversations with the quest
   for key, value in ipairs(self.conversations) do
      self.quest:addConversation(value)
   end
   -- associate the cutscenes with the quest
   for key, value in ipairs(self.cutscenes) do
      self.quest:addCutscene(value)
   end
   -- associate the list items with the quest
   for key, value in ipairs(self.checklist) do
      self.quest:addTaskToCheckList(value)
   end

   -- subscribe the lua functions to call
   self.quest:subscribeLocationEntered(self.name .. ":onLocationEntered")
   self.quest:subscribeLocationLeft(self.name .. ":onLocationLeft")
   self.quest:subscribeInteractorEvent(self.name .. ":onInteractorEvent")
   self.quest:subscribeInteractorEntered(self.name .. ":onMouseEnteredInteractor")
   self.quest:subscribeInteractorLeft(self.name .. ":onMouseLeftInteractor")
   self.quest:subscribeLocationFadingInFinished(self.name .. ":onLocationFadingInFinished")
   self.quest:subscribeConversationEvent(self.name .. ":onConversationEvent")
   self.quest:subscribeConversationFinished(self.name .. ":onConversationFinished")
   self.quest:subscribeCutsceneFinished(self.name .. ":onCutsceneFinished")
   self.quest:subscribeTriggerEvent(self.name .. ":onTriggerEvent")   
   self.quest:subscribeTriggerFaceEvent(self.name .. ":onTriggerFaceEvent")   
   self.quest:subscribeCheckListChanged(self.name .. ":updateFromCheckList")   

   -- set the initial quest state
   self.quest:setState("Initialized")

   -- TL
   --CameraMgr:subscribeEvent("EventCameraActivated","Global:onCameraChanged",false)
end
-----------------------------------------------------------------------

--------------------------------------------------------------------------
-- sets the quest active and updates the iactor configurations
--------------------------------------------------------------------------
function Global:activate()
   _LogInfo(self.name .. ":activate", self.name)

   self:initConfigurations()
   self.quest:setActive(true)

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

-----------------------------------------------------------------------
-- sets the quest inactive and resets the iactor configurations
-----------------------------------------------------------------------
function Global:deactivate()
   _LogInfo("Global:deactivate", "called")
   self.quest:setActive(false)

   -- reset the configurations for the interactor objects to default
   for key, value in ipairs(self.iactors) do
      local iactor = GameEntityMgr:getInteractor(value)
      iactor:initFromDefaultConfiguration()
   end
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when an action was performed on an interactor
-- associated with this quest
-----------------------------------------------------------------------
function Global:onInteractorEvent(p_Interactor, p_ActionID, p_InteractedInteractor)
   _LogInfo("Global:onInteractorEvent", p_Interactor)

   local questState = self.quest:getState()
   local iactor     = GameEntityMgr:getInteractor(p_Interactor)
   local location

   if p_Interactor == "animobj_palace_garden_crank" and p_ActionID == Interactor.LookAt then
      if GameEntityMgr:getMainCharacter() == "char_thara" then
	 player("CFG_ANIMOBJ_PALACE_GARDEN_CRANK_LOOKAT_THARA")
      else
	 player("CFG_ANIMOBJ_PALACE_GARDEN_CRANK_LOOKAT")
      end
   end

   if p_Interactor == "animobj_palace_garden_water_plane" and p_ActionID == Interactor.LookAt then
      --player:say("CFG_ANIMOBJ_PALACE_GARDEN_WATER_PLANE_LOOKAT")
      if GameEntityMgr:getMainCharacter() == "char_thara" then
	 player:say("CFG_ANIMOBJ_PALACE_GARDEN_WATER_PLANE_LOOKAT_THARA")
      else
	 player:say("CFG_ANIMOBJ_PALACE_GARDEN_WATER_PLANE_LOOKAT")
      end
   end

   if p_Interactor == "item_flute" and p_ActionID == Interactor.LookAt then
      if GameEntityMgr:getMainCharacter() == "char_thara" then
	 player:say("CFG_ITEM_FLUTE_LOOKAT_THARA")
      else
	 player:say("CFG_ITEM_FLUTE_LOOKAT")
      end
   end

   if p_Interactor == "iactor_palace_gate_street_to_palace_gate_entrance" and 
      p_ActionID == Interactor.Leave then
      if not self.quest:isDone("PalaceGateIntroduced") then
	 api:cutscene("palace_gate_intro")
	 self.quest:setDone("PalaceGateIntroduced")
      end
   end

   if (p_Interactor == "char_assil" or p_Interactor == "char_thara") and 
      p_ActionID == Interactor.Use then
      if Ankh:isCharSwitchVisible() then
	 Ankh:toggleMainChar()
      end
   end

   if p_Interactor == "char_assil" then
      if string.len(p_InteractedInteractor) > 0 then
	 -- check if char switch is visible
	 if Ankh:isCharSwitchVisible() then
	    -- give item to other char
	    g_InteractionHandled = true
	    char_thara:removeItemSafely(p_InteractedInteractor)
	    char_assil:addItemSafely(p_InteractedInteractor)
	    char_assil:say("ID_SWAP_ITEM_ASSIL")
	 end
      end
   end

   if p_Interactor == "char_thara" then
      if string.len(p_InteractedInteractor) > 0 then
	 if Ankh:isCharSwitchVisible() then
	    -- give item to other char
	    g_InteractionHandled = true
	    char_assil:removeItemSafely(p_InteractedInteractor)
	    char_thara:addItemSafely(p_InteractedInteractor)
	    char_thara:say("ID_SWAP_ITEM_THARA")
	 end
      end
   end

   if p_Interactor == "item_treasure_map" and p_ActionID == Interactor.LookAt then
      QuestHelper:showTreasureMap()
   end

   if p_Interactor == "char_volcano" and p_ActionID == Interactor.TalkTo then
      if Sphinx.quest:isActive() then
         api:conversation("Sphinx_volcano_hint")
      elseif SunOfCairo.quest:isActive() then
         api:conversation("SunOfCairo_volcano_hint")
      elseif Embassy.quest:isActive() or Bulbul.quest:isActive() then
         api:conversation("Embassy_volcano_hint")
      elseif EnterPalace.quest:isActive() then
         api:conversation("EnterPalace_volcano_welcome")
      end
   end

   if p_Interactor == "char_dinar" and p_ActionID == Interactor.TalkTo then
      if not Embassy.quest:isActive() and not SunOfCairo.quest:isActive() then
         if TriggerControl.quest:isDone("DinarInShadyShop") then
            if not self.quest:isDone("SpokenToDinarOnce") then
               self.quest:setDone("SpokenToDinarOnce")
               api:conversation("Standard_dinar_shady_shop")
            else
               api:conversation("Standard_dinar_shady_shop_followup")
            end
         else
            api:conversation("Standard_dinar_noble_shop")
         end
      end
   end

   if p_Interactor == "char_seeker" and p_ActionID == Interactor.TalkTo then
      if Sphinx.quest:isActive() then
         api:conversation("SunOfCairo_seeker_send_out_hint")
      elseif not SunOfCairo.quest:isActive() then
         if not self.quest:isDone("SeekerProblemDiscussed") then
            self.quest:setDone("SeekerProblemDiscussed")
            api:conversation("Standard_seeker")
         else
            api:conversation("Standard_seeker_hint")
         end
      end
   end

   if ((p_Interactor == "char_bigcop" or p_Interactor == "char_smallcop") and
       p_ActionID == Interactor.TalkTo) or
      (p_Interactor == "iactor_palace_gate_entrance_to_palace_courtyard" and
       p_ActionID == Interactor.Leave) then
      if EnterPalace.quest:isDone("QuestSolved") and not SunOfCairo.quest:isActive() and
         not Sphinx.quest:isActive() then
         api:conversation("SunOfCairo_guards_deny")
      elseif (SunOfCairo.quest:isActive() and SunOfCairo.quest:isDone("KeyReceived")) or
              Sphinx.quest:isActive() then
         api:conversation("Sphinx_guards_deny")
      end
   end

   if p_Interactor == "char_wineman" and p_ActionID == Interactor.TalkTo then
      if not SunOfCairo.quest:isActive() then
         api:conversation("SunOfCairo_wineman_quest")
      end      
   end

   if p_Interactor == "char_bakshish" and p_ActionID == Interactor.TalkTo then
      if not SunOfCairo.quest:isActive() and not Sphinx.quest:isActive() then
         api:conversation("SunOfCairo_bakshish_quest")
      end      
   end

   if p_Interactor == "char_slave" and p_ActionID == Interactor.TalkTo then
      if Sphinx.quest:isActive() then
         api:conversation("SunOfCairo_slave_oasis_done")
      elseif not SunOfCairo.quest:isActive() then
         api:conversation("Standard_slave")
      end      
   end

   if p_Interactor == "char_slavedriver" and p_ActionID == Interactor.TalkTo then
      if not SunOfCairo.quest:isActive() then
         api:conversation("Standard_slavedriver")
      end      
   end

   if p_Interactor == "char_girlie" and p_ActionID == Interactor.TalkTo then
      if not QuestMgr:isQuestActive("Oasis") then
         api:conversation("Oasis_girlie_standard")
      end
   end

   if (p_Interactor == "char_raseltin" or
       p_Interactor == "char_far_el_matu" or
       p_Interactor == "char_mut_el_tebtyns") and p_ActionID == Interactor.TalkTo then
      if not QuestMgr:isQuestActive("Oasis") then
         api:conversation("Oasis_raseltin_done")
      end
   end

   if p_Interactor == "char_schmuel" or
      p_Interactor == "char_ephraim" or
      p_Interactor == "char_shalom" then
      if not QuestMgr:isQuestActive("Oasis") and not QuestMgr:isQuestActive("SunOfCairo") then
         api:conversation("Oasis_schmuel_done")
      end
   end

   if p_Interactor == "animobj_iactor_key" and p_ActionID == Interactor.Pickup then
      if not SunOfCairo.quest:isActive() then
       	char_assil:say("ID_SUNOFCAIRO_CANNOT_TAKE_BUNCH_OF_KEYS")
      end
   end

   if p_InteractedInteractor == "item_silver_coin" then
      if string.find(p_Interactor, "char_") then 
	 if p_Interactor == "char_thara" then
	    -- nothing to do
         elseif not (p_Interactor == "char_nubian" or p_Interactor == "char_bulbul" or
            (p_Interactor == "char_girlie" and Oasis.quest:isDone("TreasureMapHint") and not Oasis.quest:isDone("TreasureMapTaken")) or
            (p_Interactor == "char_wineman" and SunOfCairo.quest:isActive())) then
            g_InteractionHandled = true
            api:conversation("Standard_assil_keep_coin")
         end
      end
   end

   if (p_Interactor == "char_wineman" and p_InteractedInteractor == "item_bottle_empty") then
      if not SunOfCairo.quest:isDone("BananaGiven") then
         g_InteractionHandled = true
         Inventory:removeItemSafely("item_bottle_empty")
         Inventory:addItemSafely("item_silver_coin")
         api:conversation("SunOfCairo_wineman_give_refund")
      end
   end

   -- hints for not allowed combinations of items
   if (p_Interactor == "iactor_home_hanging_basket" and p_InteractedInteractor == "item_cloak_dirty") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_CLOTH_TOO_SHORT")
      g_InteractionHandled = true

   elseif (p_Interactor == "iactor_home_hanging_basket" and p_InteractedInteractor == "item_cloak_noble") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_CLOTH_TOO_SHORT")
      g_InteractionHandled = true
      
   elseif (p_Interactor == "item_brush_broken" and p_InteractedInteractor == "item_treasure_dirty") or
          (p_Interactor == "item_treasure_dirty" and p_InteractedInteractor == "item_brush_broken") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_BRUSH_NEEDS_HAIR")
      g_InteractionHandled = true
      
   elseif (p_Interactor == "item_camel_hair" and p_InteractedInteractor == "item_treasure_dirty") or
          (p_Interactor == "item_treasure_dirty" and p_InteractedInteractor == "item_camel_hair") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_HAIR_NEEDS_BRUSH")
      g_InteractionHandled = true

   elseif (p_Interactor == "item_croc_purse" and p_InteractedInteractor == "item_skull") or
          (p_Interactor == "item_skull" and p_InteractedInteractor == "item_croc_purse") then
      CharacterControllerMgr:say("char_assil", "ID_COMBINE_MASK")
      g_InteractionHandled = true

   elseif (p_Interactor == "item_croc_purse" and p_InteractedInteractor == "item_croc_teeth") or
          (p_Interactor == "item_croc_teeth" and p_InteractedInteractor == "item_croc_purse") then
      CharacterControllerMgr:say("char_assil", "ID_COMBINE_MASK")
      g_InteractionHandled = true

   elseif (p_Interactor == "item_skull" and p_InteractedInteractor == "item_croc_teeth") or
          (p_Interactor == "item_croc_teeth" and p_InteractedInteractor == "item_skull") then
      CharacterControllerMgr:say("char_assil", "ID_COMBINE_MASK")
      g_InteractionHandled = true
   --elseif (p_Interactor == "item_stone_arm" and p_InteractedInteractor == "char_crocodile") or
   --       (p_Interactor == "char_crocodile" and p_InteractedInteractor == "item_stone_arm") then
   --   CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_ARM_HAS_NO_DISGUISE")

   elseif (p_Interactor == "item_shirt_hawai" and p_InteractedInteractor == "char_crocodile") or
          (p_Interactor == "char_crocodile" and p_InteractedInteractor == "item_shirt_hawai") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_SHIRT_ALONE_NOT_EATEN")
      g_InteractionHandled = true

   elseif (p_Interactor == "item_stone_arm" and p_InteractedInteractor == "item_pirate_flag") or
          (p_Interactor == "item_pirate_flag" and p_InteractedInteractor == "item_stone_arm") then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_ARM_NEEDS_BETTER_DISGUISE")
      g_InteractionHandled = true

   elseif p_Interactor == "iactor_palace_prison_cell_to_palace_prison_tunnel" and p_InteractedInteractor == "item_hanger" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_HANGER_MUST_BE_MODIFIED")
      g_InteractionHandled = true

   elseif p_Interactor == "animobj_bazar_water_plane" and p_InteractedInteractor == "item_treasure_dirty" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_WATER_DOES_NOT_HELP")
      g_InteractionHandled = true

   elseif p_Interactor == "iactor_giza_camel_o_wash" and p_InteractedInteractor == "item_treasure_dirty" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_THIS_IS_NO_CAMEL")
      g_InteractionHandled = true

   elseif (p_Interactor == "char_smallcop" or p_Interactor == "char_bigcop") and
           p_InteractedInteractor == "item_croc_teeth" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_NOT_SHOCKING_ENOUGH")
      g_InteractionHandled = true

   elseif (p_Interactor == "char_smallcop" or p_Interactor == "char_bigcop") and
           p_InteractedInteractor == "item_skull" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_NOT_SHOCKING_ENOUGH")
      g_InteractionHandled = true

   elseif (p_Interactor == "char_smallcop" or p_Interactor == "char_bigcop") and
           p_InteractedInteractor == "item_croc_purse" then
      CharacterControllerMgr:say("char_assil", "ID_FEEDBACK_NOT_SHOCKING_ENOUGH")
      g_InteractionHandled = true
   end

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

-----------------------------------------------------------------------
-- lua slot called when the mouse entered an iactor associated 
-- with this quest
-----------------------------------------------------------------------
function Global:onMouseEnteredInteractor(p_Interactor)
   _LogInfo("Global:onMouseEnteredInteractor", p_Interactor)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when the mouse left an iactor associated 
-- with this quest
-----------------------------------------------------------------------
function Global:onMouseLeftInteractor(p_Interactor)
   _LogInfo("Global:onMouseLeftInteractor", p_Interactor)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when the player entered a location that is associated
-- with this quest
-----------------------------------------------------------------------
function Global:onLocationEntered(p_Location)
   _LogInfo("Global:onLocationEntered", p_Location)

   local SkinCtrl

   if p_Location == "bazar" then
      SkinCtrl = ControllerMgr:getSkinController("animobj_bazar_cat_beige/SkinController")
      SkinCtrl:blendTo("cat_idle", 0.1, 0, false, true)

      SkinCtrl = ControllerMgr:getSkinController("animobj_bazar_cat_black/SkinController")
      SkinCtrl:setSpeed("cat_idle_greedy", 0.8, 0.0)
      SkinCtrl:blendTo("cat_idle_greedy", 0.1, 0, false, true)

      SkinCtrl = ControllerMgr:getSkinController("animobj_bazar_cat_orange/SkinController")
      SkinCtrl:setSpeed("cat_idle_greedy", 1.2, 0.0)
      SkinCtrl:blendTo("cat_idle_greedy", 0.1, 0, false, true)

      if not CrocMask.quest:isDone("CrocPurseTaken") then
         api:attachToBoneSafely("char_granny","item_croc_purse","RigProp")
      end

      if not SunOfCairo.quest:isDone("BunchOfKeysTaken") then
         api:attachToBoneSafely("char_slavedriver","animobj_iactor_key","RigPelvis")
      end

      Global:startBazarWalkLoops()
      char_egyptian_2:setMaterial("egyptian2")
   end

   if p_Location == "giza" then
      if not SunOfCairo.quest:isDone("CaravanLeaderWokenUp") then
         SkinCtrl = ControllerMgr:getSkinController("animobj_giza_camel_a1/SkinController")
         SkinCtrl:setSpeed("camel_idle", 0.7, 0.0)
         SkinCtrl:blendTo("camel_idle", 0.1, 0, false, true)

         SkinCtrl = ControllerMgr:getSkinController("animobj_giza_camel_a2/SkinController")
         SkinCtrl:setSpeed("camel_idle", 0.8, 0.0)
         SkinCtrl:blendTo("camel_idle", 0.1, 0, false, true)

         local controller=ControllerMgr:getController("animobj_giza_sign/sign_idle")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_giza_sign")
         if not obj:isControllerAttached("animobj_giza_sign/sign_idle") then
            obj:attachController("animobj_giza_sign/sign_idle")
            ControllerMgr:resumeController("animobj_giza_sign/sign_idle")
         end
      end
   end

   if p_Location == "palace_garden" then
      if not Garden.quest:isDone("BannerAcquired") and not Garden.quest:isDone("WaterLevelLowered") then
         local controller=ControllerMgr:getController("animobj_palace_garden_water_screw/turn_slow")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_palace_garden_water_screw")
         if not obj:isControllerAttached("animobj_palace_garden_water_screw/turn_slow") then
            obj:attachController("animobj_palace_garden_water_screw/turn_slow")
            ControllerMgr:resumeController("animobj_palace_garden_water_screw/turn_slow")
         end
      end
   end

   if p_Location == "sphinx_inside" then
      local controller=ControllerMgr:getController("animobj_sphinx_inside_warp_effect_a/teleporter_idle")
      controller:setCycleType(AnimationController.Loop)
      local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_warp_effect_a")
      if not obj:isControllerAttached("animobj_sphinx_inside_warp_effect_a/teleporter_idle") then
         obj:attachController("animobj_sphinx_inside_warp_effect_a/teleporter_idle")
         ControllerMgr:resumeController("animobj_sphinx_inside_warp_effect_a/teleporter_idle")
      end
   end

   if p_Location == "sphinx_inside" then
	      local SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel/SkinController")
         SkinCtrl:setSpeed("eel1_swim", 0.9, 0.0)
         SkinCtrl:blendTo("eel1_swim", 0.1, 0, false, true)

      if not Sphinx.quest:isDone("WaterFlushed") then
         SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel1/SkinController")
         SkinCtrl:setSpeed("eel1_swim", 0.9, 0.0)
         SkinCtrl:blendTo("eel1_swim", 0.1, 0, false, true)
         local controller=ControllerMgr:getController("eel1_swim")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_electric_eel1")
         if not obj:isControllerAttached("eel1_swim") then
            obj:attachController("eel1_swim")
            ControllerMgr:resumeController("eel1_swim")
         end

         SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel2/SkinController")
         SkinCtrl:setSpeed("eel2_swim", 1.1, 0.0)
         SkinCtrl:blendTo("eel2_swim", 0.1, 0, false, true)
         local controller=ControllerMgr:getController("eel2_swim")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_electric_eel2")
         if not obj:isControllerAttached("eel2_swim") then
            obj:attachController("eel2_swim")
            ControllerMgr:resumeController("eel2_swim")
         end

         SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel3/SkinController")
         SkinCtrl:setSpeed("eel3_swim", 0.8, 0.0)
         SkinCtrl:blendTo("eel3_swim", 0.1, 0, false, true)
         local controller=ControllerMgr:getController("eel3_swim")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_electric_eel3")
         if not obj:isControllerAttached("eel3_swim") then
            obj:attachController("eel3_swim")
            ControllerMgr:resumeController("eel3_swim")
         end

         SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel4/SkinController")
         SkinCtrl:setSpeed("eel4_swim", 1.0, 0.0)
         SkinCtrl:blendTo("eel4_swim", 0.1, 0, false, true)
         local controller=ControllerMgr:getController("eel4_swim")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_electric_eel4")
         if not obj:isControllerAttached("eel4_swim") then
            obj:attachController("eel4_swim")
            ControllerMgr:resumeController("eel4_swim")
         end

         SkinCtrl = ControllerMgr:getSkinController("animobj_sphinx_inside_electric_eel5/SkinController")
         SkinCtrl:setSpeed("eel5_swim", 1.05, 0.0)
         SkinCtrl:blendTo("eel5_swim", 0.1, 0, false, true)
         local controller=ControllerMgr:getController("eel5_swim")
         controller:setCycleType(AnimationController.Loop)
         local obj=GameEntityMgr:getGameEntity("animobj_sphinx_inside_electric_eel5")
         if not obj:isControllerAttached("eel5_swim") then
            obj:attachController("eel5_swim")
            ControllerMgr:resumeController("eel5_swim")
         end
      end
   end

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

-----------------------------------------------------------------------
-- lua slot called when the player left a location that is associated
-- with this quest
-----------------------------------------------------------------------
function Global:onLocationLeft(p_Location)
   _LogInfo("Global:onLocationLeft", p_Location)

   if p_Location == "desert_rock" or p_Location == "desert_plain" or 
      p_Location == "desert_crossing" then
      Ankh:hideFerrySwitch()
   end

   if p_Location == "bazar" then
      if not CrocMask.quest:isDone("CrocPurseTaken") then
         api:detachFromBoneSafely("char_granny","item_croc_purse")
      end

      if not SunOfCairo.quest:isDone("BunchOfKeysTaken") then
         api:detachFromBoneSafely("char_slavedriver","animobj_iactor_key")
      end

      Global:stopBazarWalkLoops()
   end

   if p_Location == "giza" then
      Global:stopRaseltinConversationLoop()
      Global:stopBakshishGizaConversationLoop()
   end

   if p_Location == "oasis" then
      Global:stopGenieConversationLoop()
   end

   if p_Location == "sphinx_outside" then
      Global:stopBakshishConversationLoop()
   end

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

-----------------------------------------------------------------------
-- lua slot called whenever a location associated with this quest
-- has finished fading in
-----------------------------------------------------------------------
function Global:onLocationFadingInFinished(p_Location)
   _LogInfo("Global:onLocationFadingInFinished", p_Location)

   if p_Location == "desert_rock" or p_Location == "desert_plain" or 
      p_Location == "desert_crossing" then
      Ankh:showFerrySwitch()
   end

   if p_Location == "bazar" then
      if not self.quest:isDone("SpokenToDinarOnce") and CameraMgr:getActiveCameraName() == "cam_bazar_burger" then
         self.quest:setDone("SpokenToDinarOnce")
         api:cutscene_("Standard_dinar_intercepts",0)
      end
   end
   
   if p_Location == "giza" then
      if not SunOfCairo.quest:isDone("CaravanLeaderWokenUp") then
         Global:startRaseltinConversationLoop()
      elseif not Sphinx.quest:isActive() then
         Global:startBakshishGizaConversationLoop()
      end
   end

   if p_Location == "sphinx_outside" and not SunOfCairo.quest:isDone("CaravanLeaderWokenUp") then
      if CameraMgr:getActiveCameraName() == "cam_sphinx_outside_sphinx" then
         Global:startBakshishConversationLoop()
      else
         Global:stopBakshishConversationLoop()
      end
   end

   if p_Location == "oasis" then
      if not SunOfCairo.quest:isDone("SlaveDive") and SunOfCairo.quest:isActive() then
         if LocationMgr:getLocationActivePathNodes("oasis") == "oasis_stairs_a_pathnodes" then
            Global:startGenieConversationLoop()
         else
            Global:stopGenieConversationLoop()
         end
      end
   end

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

-----------------------------------------------------------------------
-- lua slot called when a cutscene associated with this quest was
-- finished
-----------------------------------------------------------------------
function Global:onCutsceneFinished(p_Cutscene)
   _LogInfo("Global:onCutsceneFinished", p_Cutscene)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when a conversation associated with this quest
-- was finished
-----------------------------------------------------------------------
function Global:onConversationFinished(p_Conversation)
   _LogInfo("Global:onConversationFinished", p_Conversation)
end
----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when a conversation associated with this quest
-- has fired a special event
-----------------------------------------------------------------------
function Global:onConversationEvent(p_Conversation, p_Event)
   _LogInfo("Global:onConversationEvent", p_Conversation .. ":" .. p_Event)

   if p_Conversation == "Final_bakshish" and p_Event == "activate_final_animated_camera" then
     CameraMgr:activateCamera("cam_underworld_bakshish_thara_shoe")
   end

   if p_Conversation == "Final_pharaoh" then
      if p_Event == "comedian_try_dance" then
	 -- let him try to dance and fail miserably
	 local skinCtrl = ControllerMgr:getSkinController("char_comedian_3/SkinController")
	 skinCtrl:setCycleType("comedian_3_fall",AnimationController.Clamp)
	 skinCtrl:blendTo("comedian_3_fall",0,0.35,false,true)
	 api:callDelayed("sound(\"punch\")",4.0)
      elseif p_Event == "gordon_pull_lever" then
	 -- let him pull the lever to fulfil the comedian's destiny
	 local skinCtrl = ControllerMgr:getSkinController("char_gordon/SkinController")
	 skinCtrl:setCycleType("all_pull_lever",AnimationController.Clamp)
	 skinCtrl:blendTo("all_pull_lever",0,0.35,false,true)
	 animobj_lever_guard_pull:playAnimation("lever_pull")
	 api:callDelayed("Global:letComedianFall()",1.5)
	 sound("huge_lever_pull")
      end
   end
end
-----------------------------------------------------------------------

function Global:letComedianFall()
   animobj_palace_throneroom_trapdoor_a:playAnimation("open")
   animobj_palace_throneroom_trapdoor_b:playAnimation("open")
   sound("trapdoor_open")
   api:callDelayed("char_comedian_3:playAnimation(\"comedian_3_fall_into_hole\")",0.25)
end

-----------------------------------------------------------------------
-- lua slot called when a trigger associated with this quest
-- has fired its event
-----------------------------------------------------------------------
function Global:onTriggerEvent(p_Trigger)
   _LogInfo("Global:onTriggerEvent", p_Trigger)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- lua slot called when a trigger associated with this quest
-- has fired its event enhanced with the face the trigger was entered
-----------------------------------------------------------------------
function Global:onTriggerFaceEvent(p_Trigger,p_FrontFace)
   _LogInfo("Global:onTriggerFaceEvent", p_Trigger)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- sets the interactor configurations for the iactors associated with
-- this quest according to the quest's current state
-----------------------------------------------------------------------
function Global:initConfigurations()
   local questState = self.quest:getState()
   -- default case, quest just initialized
   if questState == "Initialized" then
      for key, value in ipairs(self.iactors) do
         local configName = self.name .. "_" .. value
         _LogInfo("setting config: '" .. value .. "' to '" .. configName .. "'","")
         if InteractorConfigurationMgr:isConfigurationPresent(configName) then
            local iactor = GameEntityMgr:getInteractor(value)
            iactor:setConfiguration(configName)
         else
	         _LogWarning("lua", "No such config: " .. configName)
	      end
      end
   end
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- check function
-----------------------------------------------------------------------
function Global:updateFromCheckList(p_Task, p_Done)
   --_LogInfo("Global:updateFromCheckList", "")

   if p_Task == "PalaceGateIntroduced" then
      if p_Done then
	 iactor_palace_gate_street_to_palace_gate_entrance:setConfiguration("cfg_iactor_palace_gate_street_to_palace_gate_entrance")
      else
	 iactor_palace_gate_street_to_palace_gate_entrance:setConfiguration("PalaceGateIntro_iactor_palace_gate_street_to_palace_gate_entrance")
      end
   end

   if p_Task == "GlobalRaseltinLoopBlocked" then
      if p_Done then
         Global:stopRaseltinConversationLoop()
      else
         Global:startRaseltinConversationLoop()
      end
   end

   if p_Task == "GardenGordonLoopBlocked" then
      if p_Done then
         Global:stopGordonConversationLoop()
      else
         Global:startGordonConversationLoop()
      end
   end

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startSlaveConversationLoop()
   _LogInfo("Global:startSlaveConversationLoop", "")

   if not QuestMgr:isQuestActive("SunOfCairo") then
      ConversationMgr:setConversationInteractive("Standard_slave_slavedriver_loop", false)
      -- text position 0 is 'overhead'
      ConversationMgr:setTextPosition("Standard_slave_slavedriver_loop", 0)
      api:conversation("Standard_slave_slavedriver_loop")
   elseif not SunOfCairo.quest:isDone("SlavedriverPassedOut") then
      ConversationMgr:setConversationInteractive("SunOfCairo_slave_slavedriver_loop", false)
      -- text position 0 is 'overhead'
      ConversationMgr:setTextPosition("SunOfCairo_slave_slavedriver_loop", 0)
      api:conversation("SunOfCairo_slave_slavedriver_loop")
   end

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopSlaveConversationLoop()
   _LogInfo("Global:stopSlaveConversationLoop", "")

   if not QuestMgr:isQuestActive("SunOfCairo") then
      ConversationMgr:cancelConversation("Standard_slave_slavedriver_loop")
   else
      ConversationMgr:cancelConversation("SunOfCairo_slave_slavedriver_loop")
   end

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startBakshishConversationLoop()
   _LogInfo("Global:startBakshishConversationLoop", "")

   -- TL added Osiris check
   if not Osiris.quest:isActive() then
      ConversationMgr:setConversationInteractive("SunOfCairo_bakshish_loop", false)
      -- text position 0 is 'overhead'
      ConversationMgr:setTextPosition("SunOfCairo_bakshish_loop", 0)
      api:conversation("SunOfCairo_bakshish_loop")
   end

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopBakshishConversationLoop()
   _LogInfo("Global:stopBakshishConversationLoop", "")

   ConversationMgr:cancelConversation("SunOfCairo_bakshish_loop")

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startRaseltinConversationLoop()
   _LogInfo("Global:startRaseltinConversationLoop", "")

   if not self.quest:isDone("GlobalRaseltinLoopRunning") and
      not self.quest:isDone("GlobalRaseltinLoopBlocked") then
      ConversationMgr:setConversationInteractive("Oasis_raseltin_loop", false)
      -- text position 0 is 'overhead'
      ConversationMgr:setTextPosition("Oasis_raseltin_loop", 0)
      api:conversation("Oasis_raseltin_loop")
      self.quest:setDone("GlobalRaseltinLoopRunning")
   end

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopRaseltinConversationLoop()
   _LogInfo("Global:stopRaseltinConversationLoop", "")

   if self.quest:isDone("GlobalRaseltinLoopRunning") then
      ConversationMgr:cancelConversation("Oasis_raseltin_loop")
      self.quest:setUndone("GlobalRaseltinLoopRunning")
   end

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startBakshishGizaConversationLoop()
   _LogInfo("Global:startBakshishGizaConversationLoop", "")

   ConversationMgr:setConversationInteractive("SunOfCairo_bakshish_giza_loop", false)
   -- text position 0 is 'overhead'
   ConversationMgr:setTextPosition("SunOfCairo_bakshish_giza_loop", 0)
   api:conversation("SunOfCairo_bakshish_giza_loop")

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopBakshishGizaConversationLoop()
   _LogInfo("Global:stopBakshishGizaConversationLoop", "")

   ConversationMgr:cancelConversation("SunOfCairo_bakshish_giza_loop")

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startGordonConversationLoop()
   _LogInfo("Global:startGordonConversationLoop", "")

   if not self.quest:isDone("GardenGordonLoopRunning") and
      not self.quest:isDone("GardenGordonLoopBlocked") then
      ConversationMgr:setConversationInteractive("Garden_gordon_loop", false)
      -- text position 0 is 'overhead'
      ConversationMgr:setTextPosition("Garden_gordon_loop", 0)
      api:conversation("Garden_gordon_loop")
      self.quest:setDone("GardenGordonLoopRunning")
   end

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopGordonConversationLoop()
   _LogInfo("Global:stopGordonConversationLoop", "")

   if self.quest:isDone("GardenGordonLoopRunning") then
      ConversationMgr:cancelConversation("Garden_gordon_loop")
      self.quest:setUndone("GardenGordonLoopRunning")
   end

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

-----------------------------------------------------------------------
-- start the conversation loop
-----------------------------------------------------------------------
function Global:startGenieConversationLoop()
   _LogInfo("Global:startGenieConversationLoop", "")

   ConversationMgr:setConversationInteractive("SunOfCairo_genie_loop", false)
   -- text position 0 is 'overhead'
   ConversationMgr:setTextPosition("SunOfCairo_genie_loop", 0)
   api:conversation("SunOfCairo_genie_loop")

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

-----------------------------------------------------------------------
-- stop the conversation loop
-----------------------------------------------------------------------
function Global:stopGenieConversationLoop()
   _LogInfo("Global:stopGenieConversationLoop", "")

   ConversationMgr:cancelConversation("SunOfCairo_genie_loop")

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

-----------------------------------------------------------------------
-- The default interaction handler, should handle interactions
-- that have not been handled by any active quest
-- For this to work, all quests have to flag the global variable
-- 'g_InteractionHandled' to true whenever a combination of objects
-- worked out.
-----------------------------------------------------------------------
DefaultInteractionHandler = {}
-----------------------------------------------------------------------
function DefaultInteractionHandler:onInteractorsCombined(p_Interactor,
							 p_InteractedInteractor)
   if not g_InteractionHandled then
      -- no quest handled the interaction, the action did not make sense
      -- it's possible to handle the interaction depending on the two objects
      -- combined allowing for more elaborate behaviour than just
      -- "That doesn't make sense"...

      local i = math.random(2)

      if i == 0 then
	      player:say("ID_THATS_SILLY")
      elseif i == 1 then
	      player:say("ID_WONT_WORK_OUT")
      elseif i == 2 then
	      player:say("ID_DOESNT_WORK")
      else -- won't be included TL
	      player:say("ID_THATS_SILLY")
      end

      --[[if iaction(p_Interactor,p_InteractedInteractor,
      "char_tarok","item_brush_broken") then
      player:say("Hitting him on the head, that might actually be fun...")
      else
      player:say("I don't think that'll work out")
      end]]

   end

   -- flag the next interaction to come as "not yet handled"
   g_InteractionHandled = false
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-- functions handling walking of bazar characters
-----------------------------------------------------------------------
function Global:startBazarWalkLoops()
   if not self.quest:isDone("GrannyWalkActive") then
      char_granny:setPosition(-27.5, 0, -534)
      self:startGrannyWalkLoop()
   end
   --self.quest:setDone("Egyptian1WalkActive")
   --self.quest:setDone("Egyptian2WalkActive")

   if not self.quest:isDone("Egyptian1WalkActive") then
      char_egyptian_1:setPosition(473,119,-811)
      _LogInfo("Global:startBazarWalkLoops", "")
      char_egyptian_1:setPathnodeGraph("peasant_a")
      self:startEgyptian1WalkLoop()
   end
   --self:walkToGirlieEgyptian1()

   if not self.quest:isDone("Egyptian2WalkActive") then
      char_egyptian_2:setPosition(680, 286, -2024)
      char_egyptian_2:setPathnodeGraph("peasant_b")
      --self:walkToTailorEgyptian2()
      api:callDelayed("Global:startEgyptian2WalkLoop()", 1)
   end

end
-----------------------------------------------------------------------
function Global:startEgyptian1WalkLoop()
   if not self.quest:isDone("Egyptian1WalkActive") then
      self.quest:setDone("Egyptian1WalkActive")
      if not self.quest:isDone("Egyptian1WalkToGirliePending") then
         self:walkToGirlieEgyptian1()
      end
   end
end
-----------------------------------------------------------------------
function Global:stopEgyptian1WalkLoop()
   CharacterControllerMgr:stop("char_egyptian_1")
   self.quest:setUndone("Egyptian1WalkActive")
end
-----------------------------------------------------------------------
function Global:startEgyptian2WalkLoop()
   if not self.quest:isDone("Egyptian2WalkActive") then
      self.quest:setDone("Egyptian2WalkActive")
      if not self.quest:isDone("Egyptian2WalkOffPending") then
         Global:walkToTailorEgyptian2()
      end
   end
end
-----------------------------------------------------------------------
function Global:stopEgyptian2WalkLoop()
   CharacterControllerMgr:stop("char_egyptian_2")
   self.quest:setUndone("Egyptian2WalkActive")
end
-----------------------------------------------------------------------
function Global:stopEgyptian1WalkLoop()
   CharacterControllerMgr:stop("char_egyptian_1")
   self.quest:setUndone("Egyptian1WalkActive")
end
-----------------------------------------------------------------------
function Global:startGrannyWalkLoop()
   self.quest:setDone("GrannyWalkActive")
   CharacterControllerMgr:setWalkSpeed("char_granny",30)
   self:walkToUpperPointGranny()
end
-----------------------------------------------------------------------
function Global:continueGrannyWalkLoop()
   self.quest:setDone("GrannyWalkActive")
   self:walkToLowerPointGrannyStartingFromAttachPoint()
   --CharacterControllerMgr:setWalkSpeed("char_granny",30)
end
-----------------------------------------------------------------------
function Global:stopGrannyWalkLoop()
   CharacterControllerMgr:stop("char_granny")
   self.quest:setUndone("GrannyWalkActive")
end
-----------------------------------------------------------------------
function Global:stopBazarWalkLoops()
   CharacterControllerMgr:stop("char_egyptian_1")
   CharacterControllerMgr:stop("char_egyptian_2")
   CharacterControllerMgr:stop("char_granny")

   self.quest:setUndone("Egyptian1WalkActive")
   self.quest:setUndone("Egyptian2WalkActive")
   self.quest:setUndone("GrannyWalkActive")

   self.quest:setUndone("GrannyWalkActive")

   --[[if char_granny:isControllerAttached("char_granny/RotationController_Begin") then
      char_granny:detachController("char_granny/RotationController_Begin")
   end

   if char_egyptian_1:isControllerAttached("char_egyptian_1/RotationController_Begin") then
      char_egyptian_1:detachController("char_egyptian_1/RotationController_Begin")
   end

   if char_egyptian_2:isControllerAttached("char_egyptian_2/RotationController_Begin") then
      char_egyptian_2:detachController("char_egyptian_2/RotationController_Begin")
   end

   if char_granny:isControllerAttached("char_granny/RotationController_End") then
      char_granny:detachController("char_granny/RotationController_End")
   end

   if char_egyptian_1:isControllerAttached("char_egyptian_1/RotationController_End") then
      char_egyptian_1:detachController("char_egyptian_1/RotationController_End")
   end

   if char_egyptian_2:isControllerAttached("char_egyptian_2/RotationController_End") then
      char_egyptian_2:detachController("char_egyptian_2/RotationController_End")
   end]]
end
-----------------------------------------------------------------------
function Global:walkToLowerPointGrannyStartingFromAttachPoint()
   if self.quest:isDone("GrannyWalkActive") then
      if LocationMgr:getCurrentLocation() == "bazar" then
         CharacterControllerMgr:walk("char_granny",
			   	  PinaVector3(-27.5,0,-534),
				     Degree(0))
         api:callDelayed("Global:walkToUpperPointGranny()",25)
      else
         self.quest:setUndone("GrannyWalkActive")
      end   
   end
end
-----------------------------------------------------------------------
function Global:walkToLowerPointGranny()
   if self.quest:isDone("GrannyWalkActive") then
      if LocationMgr:getCurrentLocation() == "bazar" then
         CharacterControllerMgr:walk("char_granny",
			   	  PinaVector3(-27.5,0,-534),
				     Degree(0))
         api:callDelayed("Global:walkToUpperPointGranny()",45)
      else
         self.quest:setUndone("GrannyWalkActive")
      end   
   end
end
-----------------------------------------------------------------------
function Global:walkToUpperPointGranny()
   if self.quest:isDone("GrannyWalkActive") then
      if LocationMgr:getCurrentLocation() == "bazar" then
         CharacterControllerMgr:walk("char_granny",
			   	  --PinaVector3(66,0,-1891),
                 PinaVector3(73, 266, -1697),
				   Degree(270))
         api:callDelayed("Global:walkToLowerPointGranny()",45)
      else
         self.quest:setUndone("GrannyWalkActive")
      end
   end
end
-----------------------------------------------------------------------
function Global:walkOffEgyptian1()
   _LogInfo("walkOffEgyptian1","called")

   if LocationMgr:getCurrentLocation() == "bazar" then
      CharacterControllerMgr:walk("char_egyptian_1",
				  --PinaVector3(12,-32,675),
              PinaVector3(473, 119, -811),
				  Degree(270))

      if self.quest:isDone("Egyptian1WalkActive") then
	      local delay = 10 + math.random(5)  
         if not self.quest:setDone("Egyptian1WalkToGirliePending") then
	         api:callDelayed("Global:walkToGirlieEgyptian1",delay)
            self.quest:setDone("Egyptian1WalkToGirliePending")
         end
      end
   else
      self.quest:setUndone("Egyptian1WalkActive")
   end
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
function Global:walkOffEgyptian2()
   if LocationMgr:getCurrentLocation() == "bazar" then
      CharacterControllerMgr:walk("char_egyptian_2",
				  PinaVector3(680, 286, -2024),
				  Degree(270))
      if self.quest:isDone("Egyptian2WalkActive") then      
         if not self.quest:setDone("Egyptian2WalkToTailorPending") then
	      local delay = 10 + math.random(5)
	      api:callDelayed("Global:walkToTailorEgyptian2",delay)
         self.quest:setDone("Egyptian2WalkToTailorPending")
         end
      end
   else
      self.quest:setUndone("Egyptian2WalkActive")
   end
end
-----------------------------------------------------------------------
function Global:walkToGirlieEgyptian1()
   _LogInfo("walkToGirlieEgyptian1","called")

   if self.quest:isDone("Egyptian1WalkActive") then      
      if LocationMgr:getCurrentLocation() == "bazar" then
         if (api:getDistanceSqr(char_assil:getPosition(),char_egyptian_1:getPosition())>360000) then
            self.quest:setUndone("Egyptian1WalkToGirliePending")
            CharacterControllerMgr:walk("char_egyptian_1",
				   --PinaVector3(-49.346577,8.073211,-266.370728),
               PinaVector3(0, 5, -282),
				   Degree(270))
            local delay = 10 + math.random(5)
            api:callDelayed("Global:walkOffEgyptian1()",delay)
         else
            if not self.quest:isDone("Egyptian1WalkToGirliePending") then
               api:callDelayed("Global:walkToGirlieEgyptian1()", 5)
               self.quest:setDone("Egyptian1WalkToGirliePending")
            end
         end   
      else
         self.quest:setUndone("Egyptian1WalkActive")
      end   
   end
end
-----------------------------------------------------------------------
function Global:walkToTailorEgyptian2()
   if self.quest:isDone("Egyptian2WalkActive") then      
      if LocationMgr:getCurrentLocation() == "bazar" then
         if (api:getDistanceSqr(char_assil:getPosition(),char_egyptian_2:getPosition())>360000) then
            self.quest:setUndone("Egyptian2WalkToTailorPending")
            CharacterControllerMgr:walk("char_egyptian_2",
				   PinaVector3(112, 273, -1770),
				   Degree(280))
            local delay = 10 + math.random(5)
            api:callDelayed("Global:walkOffEgyptian2()",delay)
         else
            if not self.quest:isDone("Egyptian2WalkToTailorPending") then
               api:callDelayed("Global:walkToTailorEgyptian2()", 5)
               self.quest:setDone("Egyptian2WalkToTailorPending")
            end
         end   
      else
         self.quest:setUndone("Egyptian2WalkActive")
      end   
   end
end
-----------------------------------------------------------------------
function Global:onAssilGetsCloseToEgyptian1()
   _LogInfo("onAssilGetsCloseToEgyptian1","setting Egyptian1WalkActive undone")
   --self.quest:setUndone("Egyptian1WalkActive")
   self:egyptian1FleeAssil()
end
-----------------------------------------------------------------------
function Global:egyptian1FleeAssil()
   --self.quest:setUndone("Egyptian1WalkActive")
   self:walkOffEgyptian1()
   --self.quest:setDone("Egyptian1WalkActive")
end
-----------------------------------------------------------------------
function Global:onAssilGetsCloseToEgyptian2()
   _LogInfo("onAssilGetsCloseToEgyptian1","setting Egyptian2WalkActive undone")
   --self.quest:setUndone("Egyptian2WalkActive")
   --self:walkOffEgyptian2()
   self:egyptian2FleeAssil()
end
-----------------------------------------------------------------------
function Global:egyptian2FleeAssil()
   self.quest:setUndone("Egyptian2WalkActive")
   self:walkOffEgyptian2()
   --self.quest:setDone("Egyptian2WalkActive")
end
-----------------------------------------------------------------------
function Global:onCameraChanged()

   local cam = CameraMgr:getActiveCameraName()
   if cam == "cam_bazar_entrance" then
      char_egyptian_1:setVisible(false)
      char_egyptian_2:setVisible(true)

   elseif cam == "cam_bazar_cloth" then
      char_egyptian_1:setVisible(true)
      char_egyptian_2:setVisible(false)

   elseif cam == "cam_bazar_plaza" then
      char_egyptian_1:setVisible(false)
      char_egyptian_2:setVisible(true)

   elseif cam == "cam_bazar_a" then
      char_egyptian_1:setVisible(true)
      char_egyptian_2:setVisible(true)

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

-----------------------------------------------------------------------
-----------------------------------------------------------------------
function Global:fadeInChapter2()
   local overlay = GUIWindowMgr:getOverlay2D("ankh_chapter_overlay")
   overlay:setTextureName("ankh_chapter_overlay/ImagePanel","chapter_2_german.tga")
   overlay:setVisible(true)
   overlay:setAlpha(0.0)
   overlay:animateAlpha(0.0,1.0,1.0)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-----------------------------------------------------------------------
function Global:fadeOutChapter2()
   local overlay = GUIWindowMgr:getOverlay2D("ankh_chapter_overlay")
   overlay:setVisible(true)
   overlay:setAlpha(1.0)
   overlay:animateAlpha(1.0,0.0,1.0)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-----------------------------------------------------------------------
function Global:showTreasureMap()   
   local overlay = GUIWindowMgr:getOverlay2D("ankh_treasure_map")
   overlay:setVisible(true)
   --overlay:setAlpha(0.0)
   --overlay:animateAlpha(1.0,0.0,1.0)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-----------------------------------------------------------------------
function Global:hideTreasureMap()
   local overlay = GUIWindowMgr:getOverlay2D("ankh_treasure_map")
   overlay:setVisible(false)
   --overlay:setVisible(true)
   --overlay:setAlpha(1.0)
   --overlay:animateAlpha(0.0,1.0,1.0)
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
-----------------------------------------------------------------------
function Global:toggleTreasureMap()
   local overlay = GUIWindowMgr:getOverlay2D("ankh_treasure_map")
   if overlay:isVisible() then
      Global:hideTreasureMap()
   else
      Global:showTreasureMap()
   end
end
-----------------------------------------------------------------------

-----------------------------------------------------------------------
--
-----------------------------------------------------------------------
function Global:onAssilCloseToThara()

   if not Ankh:isCharSwitchVisible() then
      return 
   end

   MouseIface:blockInput(1.0)

   if GameEntityMgr:getMainCharacter() == "char_assil" then
      -- get rotation, rotate by 180 degree, give go
      local yawBefore = char_assil:getRotate():getYaw()
      _LogInfo("","s" .. yawBefore:getDegrees())
      local yawAfter  = Degree(180 + yawBefore:getDegrees())
      if yawAfter:getDegrees() > 360 then
	 yawAfter = yawAfter - Degree(360)
      end
      char_assil:setYaw(yawAfter)
      char_assil:move(0,0,50)
      targetPos = char_assil:getPosition()
      char_assil:move(0,0,-50)
      char_assil:setYaw(yawBefore)
      CharacterControllerMgr:walk("char_assil",targetPos,yawAfter)
   end

   if GameEntityMgr:getMainCharacter() == "char_thara" then
      -- get rotation, rotate by 180 degree, give go
      local yawBefore = char_thara:getRotate():getYaw()
      _LogInfo("","s" .. yawBefore:getDegrees())
      local yawAfter  = Degree(180 + yawBefore:getDegrees())
      if yawAfter:getDegrees() > 360 then
	 yawAfter = yawAfter - Degree(360)
      end
      char_thara:setYaw(yawAfter)
      char_thara:move(0,0,50)
      targetPos = char_thara:getPosition()
      char_thara:move(0,0,-50)
      char_thara:setYaw(yawBefore)
      CharacterControllerMgr:walk("char_thara",targetPos,yawAfter)
   end

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