use std::io::Write;

use crate::{encode_tile, image::Image, protocol::{self, ProtocolWriterResult}};

pub fn encode_image<W: Write>(
    image: Image,
    writer: &mut protocol::ProtocolWriter<W>
) -> ProtocolWriterResult<()> {
    assert!(image.layers.len() <= 4); // TODO: Enforce in Image

    writer.write_u16(image.width as u16)?;
    writer.write_u16(image.height as u16)?;

    for i in 0..4 {
        writer.write_u8(image.layers.get(i).map(|l| l.0).unwrap_or(0))?;
    }

    for y0 in (0..image.height).step_by(16) {
        for x0 in (0..image.width).step_by(16) {
            for (quality, layer) in image.layers.iter() {
                let mut data = [0; 256];

                for y in 0..16 {
                    for x in 0..16 {
                        let src_x = x0 + x;
                        let src_y = y0 + y;
                        data[y * 16 + x] = 
                            if src_x < image.width && src_y < image.height { 
                                layer[src_y * image.width + src_x] 
                            } else {
                                0
                            };
                    }
                }

                encode_tile::encode_tile(data, *quality, writer)?
            }
        }
    }

    Ok(())
}