// 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 const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0

pub struct decoder? implements base.image_decoder(
	width  : base.u32,
	height : base.u32,

	call_sequence : base.u8,

	frame_config_io_position : base.u64,

	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 c   : base.u8
	var i   : base.u32
	var x32 : base.u32
	var x64 : base.u64

	if this.call_sequence <> 0 {
		return base."#bad call sequence"
	}

	// TypeField, FixHeaderField.
	i = 0
	while i < 2 {
		c = args.src.read_u8?()
		if c <> 0 {
			return "#bad header"
		}
		i += 1
	} endwhile

	// Width, height.
	i = 0
	while i < 2 {
		x32 = 0

		while true,
			inv i < 2,
		{
			c = args.src.read_u8?()
			x32 |= (c & 0x7F) as base.u32
			if (c >> 7) == 0 {
				break
			}
			x64 = (x32 as base.u64) << 7
			if x64 > 0xFFFF_FFFF {
				return "#bad header"
			}
			x32 = x64 as base.u32
		} endwhile

		if i == 0 {
			this.width = x32
		} else {
			this.height = x32
		}
		i += 1
	} endwhile

	this.frame_config_io_position = args.src.position()

	if args.dst <> nullptr {
		args.dst.set!(
			pixfmt: base.PIXEL_FORMAT__INDEXED__BGRA_BINARY,
			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
	var dst_pixfmt          : base.pixel_format
	var dst_bits_per_pixel  : base.u32[..= 256]
	var dst_bytes_per_pixel : base.u64[..= 32]
	var dst_x_in_bytes      : base.u64
	var dst_x               : base.u32
	var dst_y               : base.u32
	var tab                 : table base.u8
	var dst                 : slice base.u8
	var src                 : array[1] base.u8
	var c                   : base.u8

	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"
	}

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

	// 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

	// TODO: be more efficient than reading one byte at a time.
	if this.width > 0 {
		tab = args.dst.plane(p: 0)
		while dst_y < this.height {
			assert dst_y < 0xFFFF_FFFF via "a < b: a < c; c <= b"(c: this.height)
			dst = tab.row(y: dst_y)
			dst_x = 0

			while dst_x < this.width,
				inv dst_y < 0xFFFF_FFFF,
			{
				assert dst_x < 0xFFFF_FFFF via "a < b: a < c; c <= b"(c: this.width)

				if (dst_x & 7) == 0 {
					while args.src.length() <= 0,
						inv dst_x < 0xFFFF_FFFF,
						inv dst_y < 0xFFFF_FFFF,
						post args.src.length() > 0,
					{
						yield? base."$short read"
						tab = args.dst.plane(p: 0)
						dst = tab.row(y: dst_y)
						dst_x_in_bytes = (dst_x as base.u64) * dst_bytes_per_pixel
						if dst_x_in_bytes <= dst.length() {
							dst = dst[dst_x_in_bytes ..]
						}
					} endwhile
					c = args.src.peek_u8()
					args.src.skip_u32_fast!(actual: 1, worst_case: 1)
				}
				if (c & 0x80) == 0 {
					src[0] = 0x00
				} else {
					src[0] = 0xFF
				}
				// TODO: this should just be "c ~mod<<= 1", but that generates:
				//
				// error: conversion to ‘uint8_t {aka unsigned char}’ from
				// ‘int’ may alter its value [-Werror=conversion]
				//     v_c <<= 1;
				c = (((c as base.u32) << 1) & 0xFF) as base.u8

				this.swizzler.swizzle_interleaved_from_slice!(
					dst: dst, dst_palette: this.util.empty_slice_u8(), src: src[..])

				if dst_bytes_per_pixel <= dst.length() {
					dst = dst[dst_bytes_per_pixel ..]
				}

				dst_x += 1
			} endwhile
			dst_y += 1
		} endwhile
	}

	this.call_sequence = 3
}

pri func decoder.skip_frame?(src: base.io_reader) {
	var bytes_per_row : base.u64[..= 0x2000_0000]
	var total_bytes   : base.u64

	bytes_per_row = ((this.width as base.u64) + 7) / 8
	total_bytes = bytes_per_row * (this.height as base.u64)

	args.src.skip?(n: total_bytes)

	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. WBMP doesn't support metadata.
}

pub func decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
	return base."#no more information"
}

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