use super::input_wrapper::*;
use super::tunnel_wrapper::*;
use babalcore::*;
use gdnative::prelude::*;

#[derive(NativeClass)]
#[inherit(Spatial)]
pub struct Ball {
    player: Player,
    virtual_pos: Vector3,
}

#[methods]
impl Ball {
    fn new(_owner: &Spatial) -> Self {
        Ball {
            player: Player::new(),
            virtual_pos: Vector3::new(0.0, 0.0, 0.0),
        }
    }

    #[export]
    fn _ready(&self, _owner: &Spatial) {
        godot_print!("Ball is ready, virtual_pos=\"{:?}\".", self.virtual_pos);
    }

    #[export]
    fn tick(&mut self, _owner: &Spatial, delta: f64, tunnel: Variant, input: Variant) {
        match TunnelWrapper::from_variant(&tunnel) {
            Ok(tunnel_wrapper) => match InputWrapper::from_variant(&input) {
                Ok(mut input_wrapper) => {
                    self.player.tick(delta, &tunnel_wrapper, &mut input_wrapper);
                }
                Err(e) => godot_print!("error building InputWrapper: {:?}", e),
            },
            Err(e) => godot_print!("error building TunnelWrapper: {:?}", e),
        }
    }

    #[export]
    fn position(&self, _owner: &Spatial) -> Vector3 {
        self.player.position()
    }

    #[export]
    fn update_player_position(&mut self, owner: &Spatial, pos: Vector3) {
        let mut translation = owner.translation();
        translation.y = pos.y;
        owner.set_translation(translation);
    }

    #[export]
    fn level_col(&mut self, _owner: &Spatial, width: usize) -> isize {
        self.player.level_col(width)
    }

    #[export]
    fn level_row(&mut self, _owner: &Spatial) -> isize {
        self.player.level_row()
    }
}
