use bevy::prelude::*;
use bevy_dolly::prelude::*;

impl GameCameraRig {
    pub fn new_with_arm(arm: Vec3) -> Self {
        Self(
            CameraRig::builder()
                .with(Position::new(Vec3::ZERO))
                .with(Rotation::new(Quat::IDENTITY))
                .with(Smooth::new_position(1.25).predictive(true))
                .with(Smooth::new_rotation(10.))
                .with(Arm::new(arm))
                .with(
                    LookAt::new(Vec3::ZERO + Vec3::Y)
                        .tracking_smoothness(1.25)
                        .tracking_predictive(true),
                )
                .build(),
        )
    }

    pub fn set_position_target(&mut self, target_position: Vec3, target_rotation: Quat) {
        self.driver_mut::<Position>().position = target_position;
        self.driver_mut::<Rotation>().rotation = target_rotation;
        self.driver_mut::<LookAt>().target = target_position + Vec3::Y;
    }
}

/// A custom camera rig which combines smoothed movement with a look-at driver.
#[derive(Component, Debug, Deref, DerefMut)]
pub struct GameCameraRig(CameraRig);

// Turn the nested rig into a driver, so it can be used in another rig.
impl RigDriver for GameCameraRig {
    fn update(&mut self, params: RigUpdateParams) -> Transform {
        self.0.update(params.delta_time_seconds)
    }
}
