package wow.doge.mygame.game

import akka.actor.typed.scaladsl.Behaviors
import wow.doge.mygame.state.MovementActor
import wow.doge.mygame.state.PlayerMovementState2
import wow.doge.mygame.state.MovementActorTimer
import com.jme3.scene.shape.Box
import com.jme3.scene.Geometry
import wow.doge.mygame.implicits._
import wow.doge.mygame.events.EventBus
import wow.doge.mygame.events.Events
import wow.doge.mygame.state.ImMovementActor

object GameAppActor {

  sealed trait Command
  def apply(app: GameApp) =
    Behaviors.setup[Command] { ctx =>
      lazy val b = new Box(1, 1, 1)
      lazy val geom = new Geometry("Box", b)
      val movementActor =
        ctx.spawn(
          MovementActor(MovementActor.Props(app, geom)),
          "movementActor"
          // DispatcherSelector.fromConfig("jme-dispatcher")
        )

      val movementActorTimer = ctx.spawn(
        MovementActorTimer(movementActor),
        "movementActorTimer"
      )
      val imMovementActor = ctx.spawn(
        ImMovementActor(ImMovementActor.Props(app, geom)),
        "imMovementActor"
      )

      val subscribingActor = ctx.spawn(SubscribingActor(), "subscriber-1")

      val eventBus =
        ctx.spawn(Behaviors.logMessages(EventBus[Events.Tick]()), "eventBus1")

      eventBus ! EventBus.Subscribe(subscribingActor)

      eventBus ! EventBus.Publish(Events.PhysicsTick, ctx.self)

      app
        .getStateManager()
        .attach(
          new PlayerMovementState2(
            movementActor,
            movementActorTimer,
            imMovementActor,
            geom
          )
        )
      app.start()
      Behaviors.stopped
    }
}

object SubscribingActor {
  def apply() =
    Behaviors.receive[Events.PhysicsTick.type] { (ctx, msg) =>
      ctx.log.debug(s"received event $msg")
      Behaviors.same
    }
}
