__author__ = "Aaron Randreth"
__copyright__ = "Copyright 2015+, Consortium MonPaGe"
__license__ = "Creative Commons 4.0 By-Nc-Sa"
__maintainer__ = "Roland Trouville"
__email__ = "contact.monpage@gmail.com"
__status__ = "Production"

from typing import Optional

import pyqtgraph as pg
from PySide6.QtGui import QBrush, QPen


class AudioCursor(pg.LinearRegionItem):
	"""
	A visual cursor that represents the current playback position within a selected audio region.

	This cursor is designed to move across a parent LinearRegionItem, typically representing
	the progress of audio playback. It creates a shaded area from the start of the parent region
	to the current playback position.

	Attributes:
		parent_region: The LinearRegionItem this cursor is bound to
		parent_region_was_movable: Stores whether the parent region was movable before playback
	"""

	parent_region: pg.LinearRegionItem
	""" The LinearRegionItem this cursor is bound to """

	parent_region_was_movable: bool
	""" Stores whether the parent region was movable before playback """

	def __init__(
		self,
		parent_region: pg.LinearRegionItem,
		pen: Optional[QPen] = None,
		brush: Optional[QBrush] = None,
		**kargs,
	):
		"""
		Initialize the audio cursor with a reference to its parent region.

		Args:
			parent_region: The LinearRegionItem this cursor is bound to
			pen: Custom pen for drawing the cursor boundaries
			brush: Custom brush for filling the cursor region
			**kargs: Additional arguments passed to LinearRegionItem constructor
		"""

		if pen is None:
			pen = pg.mkPen(color="#000055AA", width=1)
		if brush is None:
			brush = pg.mkBrush(color="#00FF0055")

		super().__init__(pen=pen, brush=brush, movable=False, **kargs)

		self.parent_region = parent_region
		self.parent_region_was_movable = parent_region.movable

		self.hide()

	def follow_parent(self):
		"""
		Synchronize the cursor with its parent region.

		Sets the cursor at the beginning of the parent region and
		ensures it can only move within the bounds of the parent region.
		"""

		lbound, ubound = self.parent_region.getRegion()
		self.setRegion((lbound, lbound))
		self.setBounds((lbound, ubound))

	def advance(self, progress: float):
		"""
		Advance the cursor to represent playback progress.

		Args:
			progress: A float between 0.0 and 1.0 representing the playback progress
				within the parent region (0.0 = start, 1.0 = end)
		"""

		lbound, ubound = self.parent_region.getRegion()
		duration = ubound - lbound

		self.setRegion((lbound, lbound + duration * progress))

	def start(self):
		"""
		Start cursor playback mode.

		Makes the parent region immovable during playback, positions
		the cursor at the start of the parent region, and makes the cursor visible.
		"""

		self.parent_region.setMovable(False)
		self.follow_parent()
		self.show()

	def stop(self):
		"""
		Stop cursor playback mode.

		Hides the cursor, resets its position, and restores
		the parent region's original movability state.
		"""

		self.hide()
		self.follow_parent()
		self.parent_region.setMovable(self.parent_region_was_movable)
