use crate::drawable::Drawable;
use crate::pixel_buf::PixelBuf;
use crate::png_data::PngData;
use crate::{DISPLAY_HEIGHT, DISPLAY_WIDTH};
use crate::pixel::Pixel;
/// Represents a bouncing image on the screen.
pub struct BouncingImage {
    img: PngData,
    x: f32,
    y: f32,
    x1: f32,
    y1: f32,
    x2: f32,
    y2: f32,
    /// Horizontal velocity in pixels per second.
    move_x: f32,
    /// Vertical velocity in pixels per second.
    move_y: f32,
}

impl BouncingImage {
    /// Initializes a new BouncingImage.
    ///
    /// - `move_x`, `move_y`: velocity in pixels per second.
    /// - `start_x`, `start_y`: initial position (-1 to center on that axis).
    pub fn new(img_file: &str, move_x: f32, move_y: f32, start_x: i32, start_y: i32) -> Self {
        let img = PngData::open(img_file).expect("Could not load image");
        let x2 = DISPLAY_WIDTH as f32 - img.width as f32;
        let y2 = DISPLAY_HEIGHT as f32 - img.height as f32;
        let x1: f32 = 0.0;
        let y1: f32 = 0.0;

        let x = if start_x == -1 {
            (x1 + x2) / 2.0
        } else {
            start_x as f32
        };
        let y = if start_y == -1 {
            (y1 + y2) / 2.0
        } else {
            start_y as f32
        };

        BouncingImage {
            img,
            x,
            y,
            x1,
            y1,
            x2,
            y2,
            move_x,
            move_y,
        }
    }
}
fn offset_pixels(pixels: &Vec<Pixel>, dx: u16, dy: u16) -> Vec<Pixel> {
    let mut out = pixels.clone(); // memcpy, since Pixel is Copy
    for p in out.iter_mut() {
        p.x = p.x.saturating_add(dx);
        p.y = p.y.saturating_add(dy);
    }
    out
}
impl Drawable for BouncingImage {
    fn draw(&self, buf: &mut PixelBuf, _elapsed: f32) {

        let pixels = offset_pixels(&self.img.packed_pixels,self.x as u16,self.y as u16);
        buf.set_pixels(pixels);
    }

    fn update(&mut self, dt: f32, _elapsed: f32) {
        self.x += self.move_x * dt;
        self.y += self.move_y * dt;

        if self.x < self.x1 || self.x > self.x2 {
            self.move_x *= -1.0;
            self.x = self.x.clamp(self.x1, self.x2);
        }
        if self.y < self.y1 || self.y > self.y2 {
            self.move_y *= -1.0;
            self.y = self.y.clamp(self.y1, self.y2);
        }
    }
}
