using UnityEngine;
using Zenject;
using FlappyBird.Core;
using FlappyBird.Gameplay;
using FlappyBird.Gameplay.Bird;
using FlappyBird.Gameplay.Pipes;
namespace FlappyBird.Installers
{
///
/// Zenject MonoInstaller for core gameplay bindings.
/// Attach this to the SceneContext GameObject in each gameplay scene.
///
public sealed class GameInstaller : MonoInstaller
{
[Header("Game Management")]
[Tooltip("GameManagerView MonoBehaviour in the scene.")]
[SerializeField] private GameManagerView _gameManagerView;
[Tooltip("BirdCollisionView MonoBehaviour on the bird GameObject.")]
[SerializeField] private BirdCollisionView _birdCollisionView;
[Header("Bird")]
[Tooltip("Drag the Bird GameObject here (must have Rigidbody2D).")]
[SerializeField] private BirdView _birdView;
[Tooltip("BirdSettings ScriptableObject asset.")]
[SerializeField] private BirdSettings _birdSettings;
[Header("Pipes")]
[Tooltip("PipeSettings ScriptableObject asset.")]
[SerializeField] private PipeSettings _pipeSettings;
[Tooltip("Pipe-pair prefab with a PipeView component.")]
[SerializeField] private PipeView _pipePrefab;
[Tooltip("PipeSpawnerTicker MonoBehaviour in the scene.")]
[SerializeField] private PipeSpawnerTicker _pipeSpawnerTicker;
public override void InstallBindings()
{
BindGameState();
BindScore();
BindBird();
BindPipes();
BindDeath();
}
// ── Game State ─────────────────────────────────────────────────────
private void BindGameState()
{
Container.Bind()
.To()
.AsSingle();
// Bind the concrete MonoBehaviour so BirdCollisionView can resolve it by type.
Container.Bind()
.FromInstance(_gameManagerView)
.AsSingle();
Container.QueueForInject(_gameManagerView);
Container.QueueForInject(_birdCollisionView);
}
// ── Score ──────────────────────────────────────────────────────────
private void BindScore()
{
Container.Bind()
.To()
.AsSingle();
}
// ── Bird ───────────────────────────────────────────────────────────
private void BindBird()
{
Container.Bind()
.FromComponentOn(_birdView.gameObject)
.AsSingle();
Container.BindInstance(_birdSettings).AsSingle();
Container.Bind()
.To()
.AsSingle();
Container.QueueForInject(_birdView);
}
// ── Pipes ──────────────────────────────────────────────────────────
private void BindPipes()
{
Container.BindInstance(_pipeSettings).AsSingle();
Container.BindFactory()
.FromComponentInNewPrefab(_pipePrefab)
.AsSingle();
Container.BindInterfacesTo()
.AsSingle();
Container.Bind()
.To()
.AsSingle();
Container.QueueForInject(_pipeSpawnerTicker);
}
// ── Death ──────────────────────────────────────────────────────────
private void BindDeath()
{
// BindInterfacesTo registers the same instance for both
// IDeathHandler and IInitializable (so Zenject calls Initialize()).
Container.BindInterfacesTo()
.AsSingle();
}
}
}