#[allow(warnings)]
#[cfg(feature = "images")]
pub mod images {
    use image::GenericImageView;
    use image::ImageFormat;
    use image::{DynamicImage, ImageBuffer, Rgba, RgbaImage};
    /// # image_add_padding
    /// padding_color [[r,g,b,a]]
    /// ```ignore
    /// use doe::images::image_add_padding;
    /// image_add_padding(
    ///     "demo.png",
    ///     [255,255,255,255], 10,
    ///     10,
    ///     "new_demo.png"
    /// );
    /// ````
    ///
    pub fn image_add_padding(
        path: &str,
        padding_color: [u8; 4],
        padding_vertical: u32,
        padding_horisontal: u32,
        new_path: &str,
    ) -> DynamicImage {
        let image = image::open(path).unwrap();
        let (width, height) = (image.width(), image.height());
        let padded_width = width + 2 * padding_horisontal;
        let padded_height = height + 2 * padding_vertical;
        let color = Rgba(padding_color); //color
        let mut padded_image: RgbaImage =
            ImageBuffer::from_pixel(padded_width, padded_height, color);
        for (x, y, pixel) in image.pixels() {
            padded_image.put_pixel(x + padding_horisontal, y + padding_vertical, pixel);
        }
        DynamicImage::ImageRgba8(padded_image)
    }

    pub fn image_resize(path: &str, size: (u32, u32)) -> DynamicImage {
        // 打开图像文件
        let img = image::open(path).expect("无法打开图像文件");
        // 调整图像大小
        let resized_img = img.resize_exact(size.0, size.1, image::imageops::FilterType::Lanczos3);
        resized_img
    }
    /// # image_convert
    /// ```ignore
    /// let new_format = [
    ///     "Png",
    ///     "Jpeg",
    ///     "Gif",
    ///     "WebP",
    ///     "Pnm",
    ///     "Tiff",
    ///     "Tga",
    ///     "Dds",
    ///     "Bmp",
    ///     "Ico",
    ///     "Hdr",
    ///     "OpenExr",
    ///     "Farbfeld",
    ///     "Avif",
    ///     "Qoi",
    /// ]
    /// ```
    /// ```ignore
    /// use doe::images::image_convert;
    /// image_convert("dvwa_23_14.png","Jpeg","demo.jpg");
    /// ```
    ///
    pub fn image_convert(path: &str, new_format: &str, new_path: &str) {
        // 打开图像文件
        let img = image::open(path).expect("无法打开图像文件");
        let format = match new_format.as_ref() {
            "Png" => (ImageFormat::Png, "png"),
            "Jpeg" => (ImageFormat::Jpeg, "jpg"),
            "Gif" => (ImageFormat::Gif, "gif"),
            "WebP" => (ImageFormat::WebP, "webp"),
            "Pnm" => (ImageFormat::Pnm, "pnm"),
            "Tiff" => (ImageFormat::Tiff, "tiff"),
            "Tga" => (ImageFormat::Tga, "tga"),
            "Dds" => (ImageFormat::Dds, "dds"),
            "Bmp" => (ImageFormat::Bmp, "bmp"),
            "Ico" => (ImageFormat::Ico, "ico"),
            "Hdr" => (ImageFormat::Hdr, "hdr"),
            "OpenExr" => (ImageFormat::OpenExr, "exr"),
            "Farbfeld" => (ImageFormat::Farbfeld, "ff"),
            "Avif" => (ImageFormat::Avif, "avif"),
            "Qoi" => (ImageFormat::Qoi, "qoi"),
            _ => (ImageFormat::Png, "png"),
        };
        img.save_with_format(new_path, format.0).unwrap();
    }

    pub fn convert_to_icns(
        png_path: &str,
        icns_path: &str,
    ) -> Result<(), Box<dyn std::error::Error>> {
        use icns::{IconFamily, IconType, Image};
        let file = std::io::BufReader::new(std::fs::File::open(png_path).unwrap());
        let image = Image::read_png(file).unwrap();
        let w = image.width();
        let h = image.height();
        let new_file = std::io::BufWriter::new(std::fs::File::create(icns_path).unwrap());
        let mut icon_family = IconFamily::new();
        icon_family.add_icon(&image).unwrap();
        icon_family.write(new_file).unwrap();
        Ok(())
    }
    /// # rotate_image
    /// ```ignore
    /// let p_name = "demo.png";
    /// let rotated_img = doe::images::rotate_image(&p_name, 15.0);
    /// rotated_img.save(p_name).expect("Failed to save rotated image");
    /// ```
    /// 
    /// 
    pub fn rotate_image(path: &str, degrees: f32) -> RgbaImage {
        let img = image::open(path).expect("Failed to open image");
        // Calculate the radians equivalent of the given degrees
        let radians = degrees.to_radians();

        // Compute the dimensions of the rotated image
        let (width, height) = img.dimensions();
        let rotated_width =
            ((radians.cos() * width as f32).abs() + (radians.sin() * height as f32).abs()) as u32;
        let rotated_height =
            ((radians.sin() * width as f32).abs() + (radians.cos() * height as f32).abs()) as u32;

        // Create a new blank image with the rotated dimensions
        let mut rotated_img = RgbaImage::new(rotated_width, rotated_height);

        // Compute the center coordinates of the rotated image
        let center_x = rotated_width as f32 / 2.0;
        let center_y = rotated_height as f32 / 2.0;

        // Iterate over each pixel in the rotated image and copy the corresponding pixel from the original image
        for (x, y, pixel) in rotated_img.enumerate_pixels_mut() {
            // Compute the corresponding coordinates in the original image
            let orig_x = radians.cos() * ((x as f32 - center_x) / center_x)
                + radians.sin() * ((y as f32 - center_y) / center_y);
            let orig_y = -radians.sin() * ((x as f32 - center_x) / center_x)
                + radians.cos() * ((y as f32 - center_y) / center_y);

            // Convert the floating-point coordinates to integer coordinates
            let orig_x = orig_x * center_x + center_x;
            let orig_y = orig_y * center_y + center_y;

            // Check if the computed coordinates are within the bounds of the original image
            if orig_x >= 0.0 && orig_x < width as f32 && orig_y >= 0.0 && orig_y < height as f32 {
                // Get the pixel value from the original image
                let orig_pixel = img.get_pixel(orig_x as u32, orig_y as u32);

                // Set the corresponding pixel in the rotated image
                *pixel = Rgba([orig_pixel[0], orig_pixel[1], orig_pixel[2], orig_pixel[3]]);
            }
        }

        rotated_img
    }


    pub fn cut_area(img: ImageBuffer<Rgba<u8>, Vec<u8>>, x: u32, y: u32, width: u32, height: u32) -> Option<RgbaImage> {
        let sub_image = img.view(x, y, width, height);
        let mut cut_image = RgbaImage::new(width, height);
        for (x, y, pixel) in sub_image.pixels() {
            cut_image.put_pixel(x, y, pixel);
        }
        Some(cut_image)
    }
    
    pub fn convert_to_ico(
        png_path: &str,
        ico_path: &str,
    ) -> Result<(), Box<dyn std::error::Error>> {
        use std::fs::write;
        use std::fs::File;
        use std::io::Write;
        // Create a new, empty icon collection:
        let mut icon_dir = ico::IconDir::new(ico::ResourceType::Icon);
        // Read a PNG file from disk and add it to the collection:
        let file = std::fs::File::open(png_path).unwrap();
        let image = ico::IconImage::read_png(file).unwrap();
        icon_dir.add_entry(ico::IconDirEntry::encode(&image).unwrap());
        let file = std::fs::File::create(ico_path).unwrap();
        icon_dir.write(file).unwrap();
        Ok(())
    }
}
#[cfg(feature = "images")]
pub use images::*;
