// Copyright 2026 Gabriel Bjørnager Jensen.
//
// This file is part of LOOKLOOK.
//
// LOOKLOOK is free software: you can redistribute
// it and/or modify it under the terms of the GNU
// Affero General Public License as published by
// the Free Software Foundation, either version 3
// of the License, or (at your option) any later
// version.
//
// LOOKLOOK is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Af-
// fero General Public License along with LOOKLOOK.
// If not, see <https://www.gnu.org/licenses/>.

//! The [`ModeVideo`] structure.

use crate::mode::{
	ColourDepth,
	FrameRate,
	FrameResolution,
	PixelLayout,
	VideoFormat,
};

/// The `video` synth mode.
#[derive(Debug)]
#[derive_const(Clone)]
pub struct ModeVideo {
	/// The video width.
	pub width: FrameResolution,

	/// The video height.
	pub height: FrameResolution,

	/// The pixel layout.
	pub pixel_layout: PixelLayout,

	/// The pixel layout.
	pub colour_depth: ColourDepth,

	/// The frame rate.
	pub frame_rate: FrameRate,

	/// The amount of frames to render.
	pub frame_count: u64,

	/// The output format.
	pub format: VideoFormat,
}

impl ModeVideo {
	/// Computes the size of a single pixel.
	///
	/// The returned value is in count of bytes.
	#[inline]
	#[must_use]
	pub const fn pixel_size(&self) -> usize {
		let channel_size  = self.colour_depth.as_usize();
		let channel_count = self.pixel_layout.channel_count();

		// NOTE: We conventionaly guarantee that this
		// computation never overflows `usize`.
		channel_size * channel_count
	}

	/// Computes the size of a single frame, measured in
	/// pixels.
	///
	/// # Panics
	///
	/// This method will panic if the result is greater
	/// than [`usize::MAX`].
	#[inline]
	#[must_use]
	#[track_caller]
	pub const fn frame_size(&self) -> usize {
		self.width.as_usize().strict_mul(self.height.as_usize())
	}
}

const impl Default for ModeVideo {
	#[inline]
	fn default() -> Self {
		Self {
			width:        const { FrameResolution::new(90).unwrap() },
			height:       const { FrameResolution::new(320).unwrap() },
			pixel_layout: Default::default(),
			colour_depth: Default::default(),
			frame_rate:   Default::default(),
			frame_count:  Default::default(),
			format:       Default::default(),
		}
	}
}
