content: {-# LANGUAGE OverloadedStrings #-}
  
  -- |
  -- SPDX-License-Identifier: BSD-3-Clause
  --
  -- Here is the WorldPanel player configurable key event handler.
  module Swarm.TUI.Controller.EventHandlers.World (
    worldEventHandlers,
  ) where
  
  import Brick hiding (Location)
  import Brick.Keybindings
  import Control.Lens
  import Control.Monad (when)
  import Data.Int (Int32)
  import Linear
  import Swarm.Game.Location
  import Swarm.Game.State
  import Swarm.Game.State.Landscape
  import Swarm.Language.Syntax.Direction (Direction (..), directionSyntax)
  import Swarm.TUI.Controller.Util
  import Swarm.TUI.Model
  import Swarm.TUI.Model.Event
  
  -- | Handle a user input event in the world view panel.
  worldEventHandlers :: [KeyEventHandler SwarmEvent (EventM Name AppState)]
  worldEventHandlers = allHandlers World $ \case
    MoveViewEvent d -> ("Scroll world view in the " <> directionSyntax (DAbsolute d) <> " direction", scrollViewInDir $ toHeading d)
  
  scrollViewInDir :: V2 Int32 -> EventM Name AppState ()
  scrollViewInDir d = do
    c <- use $ playState . scenarioState . gameState . creativeMode
    s <- use $ playState . scenarioState . gameState . landscape . worldScrollable
    when (c || s) $ scrollView (.+^ (worldScrollDist *^ d))
  
  worldScrollDist :: Int32
  worldScrollDist = 8
  
  -- | Manually scroll the world view.
  scrollView :: (Location -> Location) -> EventM Name AppState ()
  scrollView update =
    playState . scenarioState . gameState . robotInfo %= modifyViewCenter (fmap update)
  