// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub status "#bad header"
pub status "#unsupported BMP file"

pri status "@internal note: short read"

pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0

pub struct decoder? implements base.image_decoder(
	width  : base.u32[..= 0x7FFF_FFFF],
	height : base.u32[..= 0x7FFF_FFFF],

	call_sequence : base.u8,

	top_down      : base.bool,
	pad_per_row   : base.u32[..= 3],
	bytes_per_row : base.u64[..= 0x0000_0001_FFFF_FFFC],  // 4 * 0x7FFF_FFFF
	pixfmt        : base.pixel_format,

	io_redirect_fourcc : base.u32,
	io_redirect_pos    : base.u64,

	frame_config_io_position : base.u64,

	padding : base.u32,

	mask_r : base.u32,
	mask_g : base.u32,
	mask_b : base.u32,
	mask_a : base.u32,

	dst_x     : base.u32,
	dst_y     : base.u32,
	dst_y_end : base.u32,
	dst_y_inc : base.u32,

	pending_pad : base.u32[..= 3],

	swizzler : base.pixel_swizzler,
	util     : base.utility,
)

pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
}

pub func decoder.decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
	var magic           : base.u32
	var bitmap_info_len : base.u32
	var width           : base.u32
	var height          : base.u32
	var planes          : base.u32
	var bits_per_pixel  : base.u32
	var compression     : base.u32

	if (this.call_sequence <> 0) or (this.io_redirect_fourcc == 1) {
		return base."#bad call sequence"
	} else if this.io_redirect_fourcc <> 0 {
		return base."@I/O redirect"
	}

	// Read the BITMAPFILEHEADER (14 bytes).

	magic = args.src.read_u16le_as_u32?()
	if magic <> 'BM'le {
		return "#bad header"
	}

	args.src.skip_u32?(n: 8)

	this.padding = args.src.read_u32le?()
	if this.padding < 14 {
		return "#bad header"
	}
	this.padding -= 14
	this.io_redirect_pos = (this.padding as base.u64) ~sat+ args.src.position()

	// Read the BITMAPINFOHEADER (version 3 / 4 / 5 is 40 / 108 / 124 bytes).

	bitmap_info_len = args.src.read_u32le?()
	if (bitmap_info_len <> 40) and (bitmap_info_len <> 108) and (bitmap_info_len <> 124) {
		return "#unsupported BMP file"
	}
	if this.padding < bitmap_info_len {
		return "#bad header"
	}
	this.padding -= bitmap_info_len

	width = args.src.read_u32le?()
	if width >= 0x8000_0000 {
		return "#bad header"
	}
	this.width = width

	height = args.src.read_u32le?()
	if height == 0x8000_0000 {
		return "#bad header"
	} else if height >= 0x8000_0000 {
		// The &0x7FFF_FFFF is redundant, but proves to the compiler that the
		// result is within this.height's refined bounds.
		this.height = (0 ~mod- height) & 0x7FFF_FFFF
		this.top_down = true
	} else {
		this.height = height
	}

	planes = args.src.read_u16le_as_u32?()
	if planes <> 1 {
		return "#unsupported BMP file"
	}

	bits_per_pixel = args.src.read_u16le_as_u32?()
	compression = args.src.read_u32le?()
	if bits_per_pixel == 0 {
		if compression == 4 {
			this.io_redirect_fourcc = 'JPEG'be
			return base."@I/O redirect"
		} else if compression == 5 {
			this.io_redirect_fourcc = 'PNG 'be
			return base."@I/O redirect"
		}
		return "#unsupported BMP file"
	} else if bits_per_pixel == 24 {
		// 3 bytes per pixel, but row lengths are rounded up to multiples of 4.
		// The "((x + 3) >> 2) << 2" dance rounds x up.
		this.bytes_per_row = ((((this.width as base.u64) * 3) + 3) >> 2) << 2
		this.pad_per_row = this.width & 3
		this.pixfmt = this.util.make_pixel_format(repr: base.PIXEL_FORMAT__BGR)
	} else if bits_per_pixel == 32 {
		this.bytes_per_row = (this.width as base.u64) * 4
		this.pad_per_row = 0
		this.pixfmt = this.util.make_pixel_format(repr: base.PIXEL_FORMAT__BGRA_NONPREMUL)
	} else {
		// TODO: support other bits_per_pixel's.
		return "#unsupported BMP file"
	}

	// We've already read 20 bytes from the BITMAPINFOHEADER: size (4), width
	// (4), height (4), planes (2), bpp (2), compression (4). Skip the rest of
	// the version 3 BITMAPINFOHEADER (whose total size is 40).
	args.src.skip_u32?(n: 40 - 20)

	if bitmap_info_len >= 108 {
		this.mask_r = args.src.read_u32le?()
		this.mask_g = args.src.read_u32le?()
		this.mask_b = args.src.read_u32le?()
		this.mask_a = args.src.read_u32le?()

		// If compression is 3 (BITFIELDS) but the explicit masks are what the
		// implicit masks are for no compression, treat it as no compression.
		if (compression == 3) and
			(this.mask_r == 0x00FF_0000) and
			(this.mask_g == 0x0000_FF00) and
			(this.mask_b == 0x0000_00FF) and
			(this.mask_a == 0xFF00_0000) {
			compression = 0
		}

		// Skip the rest of the BITMAPINFOHEADER. We've already read (40 + (4 *
		// 4)) bytes.
		args.src.skip_u32?(n: bitmap_info_len - 56)
	}

	if compression <> 0 {
		// TODO: support compression.
		return "#unsupported BMP file"
	}

	this.frame_config_io_position = args.src.position()

	if args.dst <> nullptr {
		args.dst.set!(
			pixfmt: base.PIXEL_FORMAT__BGRA_NONPREMUL,  // TODO: this.pixfmt instead?
			pixsub: 0,
			width: this.width,
			height: this.height,
			first_frame_io_position: this.frame_config_io_position,
			first_frame_is_opaque: true)
	}

	this.call_sequence = 1
}

pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
	if this.call_sequence < 1 {
		this.decode_image_config?(dst: nullptr, src: args.src)
	} else if this.call_sequence == 1 {
		if this.frame_config_io_position <> args.src.position() {
			return base."#bad restart"
		}
	} else if this.call_sequence == 2 {
		this.skip_frame?(src: args.src)
		return base."@end of data"
	} else {
		return base."@end of data"
	}

	if args.dst <> nullptr {
		args.dst.set!(bounds: this.util.make_rect_ie_u32(
			min_incl_x: 0,
			min_incl_y: 0,
			max_excl_x: this.width,
			max_excl_y: this.height),
			duration: 0,
			index: 0,
			io_position: this.frame_config_io_position,
			disposal: 0,
			opaque_within_bounds: true,
			overwrite_instead_of_blend: false,
			background_color: 0xFF00_0000)
	}

	this.call_sequence = 2
}

pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
	var status : base.status

	if this.call_sequence < 2 {
		this.decode_frame_config?(dst: nullptr, src: args.src)
	} else if this.call_sequence == 2 {
		// No-op.
	} else {
		return base."@end of data"
	}

	args.src.skip_u32?(n: this.padding)

	if (this.width > 0) and (this.height > 0) {
		this.dst_x = 0
		if this.top_down {
			this.dst_y = 0
			this.dst_y_end = this.height
			this.dst_y_inc = 1
		} else {
			this.dst_y = this.height ~mod- 1
			this.dst_y_end = 0xFFFF_FFFF  // -1 as a base.u32.
			this.dst_y_inc = 0xFFFF_FFFF  // -1 as a base.u32.
		}

		status = this.swizzler.prepare!(
			dst_pixfmt: args.dst.pixel_format(),
			dst_palette: args.dst.palette(),
			src_pixfmt: this.pixfmt,
			src_palette: this.util.empty_slice_u8(),
			blend: args.blend)
		if not status.is_ok() {
			return status
		}

		while true {
			status = this.swizzle!(dst: args.dst, src: args.src)
			if status.is_ok() {
				break
			} else if status <> "@internal note: short read" {
				return status
			}
			yield? base."$short read"
		} endwhile
	}

	this.call_sequence = 3
}

pri func decoder.swizzle!(dst: ptr base.pixel_buffer, src: base.io_reader) base.status {
	var dst_pixfmt          : base.pixel_format
	var dst_bits_per_pixel  : base.u32[..= 256]
	var dst_bytes_per_pixel : base.u64[..= 32]
	var dst_bytes_per_row   : base.u64
	var tab                 : table base.u8
	var dst                 : slice base.u8
	var i                   : base.u64
	var n                   : base.u64

	// TODO: the dst_pixfmt variable shouldn't be necessary. We should be able
	// to chain the two calls: "args.dst.pixel_format().bits_per_pixel()".
	dst_pixfmt = args.dst.pixel_format()
	dst_bits_per_pixel = dst_pixfmt.bits_per_pixel()
	if (dst_bits_per_pixel & 7) <> 0 {
		return base."#unsupported option"
	}
	dst_bytes_per_pixel = (dst_bits_per_pixel / 8) as base.u64
	dst_bytes_per_row = (this.width as base.u64) * dst_bytes_per_pixel
	tab = args.dst.plane(p: 0)

	while.outer true {
		while this.pending_pad > 0 {
			if args.src.length() <= 0 {
				return "@internal note: short read"
			}
			this.pending_pad -= 1
			args.src.skip_u32_fast!(actual: 1, worst_case: 1)
		} endwhile

		while.inner true {
			if this.dst_x == this.width {
				this.dst_x = 0
				this.dst_y ~mod+= this.dst_y_inc
				if this.dst_y == this.dst_y_end {
					break.outer
				} else if this.pad_per_row <> 0 {
					this.pending_pad = this.pad_per_row
					continue.outer
				}
			}

			dst = tab.row(y: this.dst_y)
			if dst_bytes_per_row < dst.length() {
				dst = dst[.. dst_bytes_per_row]
			}
			i = (this.dst_x as base.u64) * dst_bytes_per_pixel
			if i >= dst.length() {
				// TODO: advance args.src if the dst pixel_buffer bounds is
				// smaller than this BMP's image bounds?
				continue.inner
			}
			n = this.swizzler.swizzle_interleaved_from_reader!(
				dst: dst[i ..],
				dst_palette: this.util.empty_slice_u8(),
				src: args.src)
			if n == 0 {
				return "@internal note: short read"
			}
			this.dst_x ~sat+= (n & 0xFFFF_FFFF) as base.u32
		} endwhile.inner
	} endwhile.outer

	return ok
}

pri func decoder.skip_frame?(src: base.io_reader) {
	args.src.skip_u32?(n: this.padding)
	args.src.skip?(n: this.bytes_per_row * (this.height as base.u64))

	this.call_sequence = 3
}

pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
	return this.util.make_rect_ie_u32(
		min_incl_x: 0,
		min_incl_y: 0,
		max_excl_x: this.width,
		max_excl_y: this.height)
}

pub func decoder.num_animation_loops() base.u32 {
	return 0
}

pub func decoder.num_decoded_frame_configs() base.u64 {
	if this.call_sequence > 1 {
		return 1
	}
	return 0
}

pub func decoder.num_decoded_frames() base.u64 {
	if this.call_sequence > 2 {
		return 1
	}
	return 0
}

pub func decoder.restart_frame!(index: base.u64, io_position: base.u64) base.status {
	if this.call_sequence == 0 {
		return base."#bad call sequence"
	}
	if args.index <> 0 {
		return base."#bad argument"
	}
	this.call_sequence = 1
	this.frame_config_io_position = args.io_position
	return ok
}

pub func decoder.set_report_metadata!(fourcc: base.u32, report: base.bool) {
	// No-op. BMP doesn't support metadata.
}

pub func decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
	if this.io_redirect_fourcc <= 1 {
		return base."#no more information"
	}
	if args.minfo <> nullptr {
		args.minfo.set!(
			flavor: 1,  // WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT
			w: this.io_redirect_fourcc,
			x: 0,
			y: this.io_redirect_pos,
			z: 0xFFFF_FFFF_FFFF_FFFF)
	}
	// Setting io_redirect_fourcc to a dummy value of 1 will cause future calls
	// to return an error.
	this.io_redirect_fourcc = 1
}

pub func decoder.workbuf_len() base.range_ii_u64 {
	return this.util.make_range_ii_u64(min_incl: 0, max_incl: 0)
}
