"""
This file is part of the Tetris project.

Written 2023 by Maarten Tromp <maarten@geekabit.nl>


Website
-------
https://www.geekabit.nl/projects/tetris-window/


License
-------
CC0 (no copyright, public domain)
The person who associated a work with this deed has dedicated the work to the public domain by
waiving all of his or her rights to the work worldwide under copyright law, including all related
and neighbouring rights, to the extent allowed by law. You can copy, modify, distribute and perform
the work, even for commercial purposes, all without asking permission.
https://creativecommons.org/share-your-work/public-domain/cc0/
This file is part of the Tetris project.
"""


# imports
import json
#import logging


class Screen:
	"""
	Screen class. It holds screen dimensions, contents and some functions to manipulate them.
	"""

	# constants
	background_colour = (0, 0, 0)
	width = 10
	height = 30


	def __init__(self):
		"""
		Only a single instance of this class will be created.

		Parameters
		----------
		none
		"""

		# public variables
		self.dirty = False

		# private variables
		self._buf = [] # screen buffer, a 2 dimensional list of RGB values

		# init
		for y in range(self.height):
			self._buf.append([])
			for _ in range(self.width):
				self._buf[y].append(self.background_colour)


	def set_pixel(self, coordinates, rgb):
		"""
		Set single specified pixel to specified colour.

		Parameters
		----------
		coordinates: tuple of 2 numbers
			Pixel X and Y coordinates.
		rgb: tuple of 3 numbers
			Contains RGB value as 3x unsigned short int [0..255].

		Returns
		-------
		none
		"""

		assert len(coordinates) == 2, f"coordinates: {coordinates}"
		(x, y) = coordinates
		assert 0 <= x <= self.width - 1 and 0 <= y <= self.height - 1, f"invalid coordinates x: {x}, y: {y}"

		assert len(rgb) == 3, f"invalid rgb: {rgb}"
		(r, g, b) = rgb
		assert 0 <= r <= 255 and  0 <= g <= 255 and 0 <= b <= 255, f"r: {r}, g: {g}, b: {b}"

		self._buf[y][x] = [round(val) for val in rgb]
		self.dirty = True


	def get_pixel(self, coordinates):
		"""
		Get colour of specified single pixel.

		Parameters
		----------
		coordinates: tuple of 2 numbers
			Pixel X and Y coordinates.

		Returns
		-------
		list
			List contains RGB value as 3x unsigned short int (0..255).
		"""

		assert len(coordinates) == 2, f"coordinates: {coordinates}"
		(x, y) = coordinates
		assert 0 <= x < self.width and 0 <= y < self.height, f"x: {x}, y: {y}"

		return self._buf[y][x]


	def clear(self):
		"""
		Clear display buffer.

		Parameters
		----------
		none

		Returns
		-------
		none
		"""

		for y in range(self.height):
			for x in range(self.width):
				self._buf[y][x] = self.background_colour


	def dim(self, dim):
		"""
		Dim display buffer.

		Parameters
		----------
		dim: float [0..1]
			Dimming multiplier for buffer. Value of 1 leaves buffer unchanged.

		Returns
		-------
		none
		"""

		assert 0 <= dim <= 1, f"invalid dim: {dim}"

		# It is not possible to reach a value of 0 with dim facter > .5

		for y in range(self.height):
			for x in range(self.width):
				self._buf[y][x] = [round(val * dim) for val in self._buf[y][x]]
		self.dirty = True


	def dump(self):
		"""
		Export (dump) screen contents as JSON.

		Parameters
		----------
		none

		Returns
		-------
		Screen buffer contents, formatted as JSON.
		"""

		j = json.dumps({"screen": self._buf})
		self.dirty = False
		return j
