use image::{
    DynamicImage,
    GenericImageView,
    RgbaImage,
    SubImage
};

/// a frame in a spritesheet
/// x, y are the coordinates of the frame in the spritesheet, 1 per frame
#[derive(Clone, Copy)]
pub struct Frame(pub u32, pub u32);

pub struct Animation {
    pub frames: &'static [Frame],
    pub ticks_per_frame: u32
}

pub struct Spritesheet {
    image: RgbaImage,
    sprite_size: (u32, u32)
}

// this reminded me of the plist spritesheet format from RobTop's Geometry Dash
// oh RobTop how i miss you
impl Spritesheet {
    pub fn new(image: DynamicImage, sprite_size: (u32, u32)) -> Self {
        Spritesheet {
            image: image.into(),
            sprite_size: sprite_size
        }
    }

    pub fn get_frame(
        &self,
        frame: Frame
    ) -> SubImage<&RgbaImage> {
        let Frame(x, y) = frame;
        let (width, height) = self.sprite_size;
        let (x, y) = (x * width, y * height);

        return self.image.view(x, y, width, height)
    }

    pub fn get_animation(
        &self,
        animation: Animation,
        animation_tick: u32
    ) -> SubImage<&RgbaImage> {
        self.get_frame(animation.frames[animation_tick as usize % animation.frames.len()])
    }

    pub fn get_size(&self) -> (u32, u32) {
        self.sprite_size
    }
}
