module Engine.Events.MouseButton
  ( ClickHandler
  , callback
  , handler
  ) where

import RIO

import Data.Type.Equality (type (~))
import Geomancy (Vec2)
import UnliftIO.Resource (ReleaseKey)

import Engine.Events.Sink (MonadSink, Sink)
import Engine.Window.MouseButton (ModifierKeys, MouseButton, MouseButtonState)
import Engine.Window.MouseButton qualified as MouseButton
import Engine.Worker qualified as Worker

type ClickHandler e st m =
  Sink e st ->
  Vec2 ->
  (ModifierKeys, MouseButtonState, MouseButton) ->
  m ()

callback
  :: ( MonadSink rs m
     , Worker.HasOutput cursor
     , Worker.GetOutput cursor ~ Vec2
     )
  => cursor
  -> ClickHandler e st m
  -------------------------
  -> Sink e st
  -> m ReleaseKey
callback :: forall rs (m :: * -> *) cursor e st.
(MonadSink rs m, HasOutput cursor, GetOutput cursor ~ Vec2) =>
cursor -> ClickHandler e st m -> Sink e st -> m ReleaseKey
callback cursor
cursorP ClickHandler e st m
eventHandler = Callback m -> m ReleaseKey
forall rs (m :: * -> *).
MonadSink rs m =>
Callback m -> m ReleaseKey
MouseButton.callback (Callback m -> m ReleaseKey)
-> (Sink e st -> Callback m) -> Sink e st -> m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. cursor -> ClickHandler e st m -> Sink e st -> Callback m
forall rs (m :: * -> *) cursor e st.
(MonadSink rs m, HasOutput cursor, GetOutput cursor ~ Vec2) =>
cursor
-> ClickHandler e st m
-> Sink e st
-> (ModifierKeys, MouseButtonState, MouseButton)
-> m ()
handler cursor
cursorP ClickHandler e st m
eventHandler

handler
  :: ( MonadSink rs m
     , Worker.HasOutput cursor
     , Worker.GetOutput cursor ~ Vec2
     )
  => cursor
  -> ClickHandler e st m
  -> Sink e st
  -> (ModifierKeys, MouseButtonState, MouseButton)
  -> m ()
handler :: forall rs (m :: * -> *) cursor e st.
(MonadSink rs m, HasOutput cursor, GetOutput cursor ~ Vec2) =>
cursor
-> ClickHandler e st m
-> Sink e st
-> (ModifierKeys, MouseButtonState, MouseButton)
-> m ()
handler cursor
cursorP ClickHandler e st m
eventHandler Sink e st
sink (ModifierKeys, MouseButtonState, MouseButton)
buttonEvent = do
  Vec2
cursorPos <- cursor -> m (GetOutput cursor)
forall worker (m :: * -> *).
(HasOutput worker, MonadIO m) =>
worker -> m (GetOutput worker)
Worker.getOutputData cursor
cursorP
  Utf8Builder -> m ()
forall (m :: * -> *) env.
(MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) =>
Utf8Builder -> m ()
logDebug (Utf8Builder -> m ()) -> Utf8Builder -> m ()
forall a b. (a -> b) -> a -> b
$ Utf8Builder
"MouseButton event: " Utf8Builder -> Utf8Builder -> Utf8Builder
forall a. Semigroup a => a -> a -> a
<> (Vec2, (ModifierKeys, MouseButtonState, MouseButton))
-> Utf8Builder
forall a. Show a => a -> Utf8Builder
displayShow (Vec2
cursorPos, (ModifierKeys, MouseButtonState, MouseButton)
buttonEvent)
  ClickHandler e st m
eventHandler Sink e st
sink Vec2
cursorPos (ModifierKeys, MouseButtonState, MouseButton)
buttonEvent