from .dprx import *
from .modules.fec import FecRx
from .modules.capturer.bulk.bulk_capturer import BulkCapturer
from .modules.edid.edid import DisplayIdSink
from .modules.panel_replay import SinkPanelReplay, SinkPanelSelfRefresh
from typing import Optional


class DPRX4xx(DPRX):

    """

    Main class of `DPRX4xx` object.
    Inherited from class `DPRX`.
    Class describes capabilities of 400th (4XX) series of DP and USB-C devices in Sink (RX - receiver) role.

    Attributes:
        __fec (FecTx): object of `FecTx`.
        __bulk_capturer (BulkCapturer): object of `BulkCapturer`
        __display_id (DisplayIdSink): object of `DisplayIdSink`
        __panel_replay (SinkPanelReplay): object of `SinkPanelReplay`
        __psr (SinkPanelSelfRefresh): object of `SinkPanelSelfRefresh`

    """

    def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
        super().__init__(port_io, memory_manager, capturer)

        hw_caps = port_io.get(TSI_DPRX_HW_CAPS_R, DPRXHWCaps)[1]
        self.__fec = FecRx(port_io, self.dpcd)
        self.__bulk_capturer = BulkCapturer(capturer, memory_manager)
        self.__display_id = DisplayIdSink(port_io, hw_caps.mst_stream_count)
        self.__panel_replay = SinkPanelReplay(port_io) if hw_caps.pr != 0 else None
        self.__psr = SinkPanelSelfRefresh(port_io) if hw_caps.psr != 0 else None

    @property
    def fec(self) -> FecRx:
        """

        Should be used to control FEC functionality on Sink (RX - receiver) side.

        Returns:
            object of `FecRx` type.
        """
        return self.__fec

    @property
    def bulk_capturer(self) -> BulkCapturer:
        """

        Should be used to control Bulk capturer functionality on Sink (RX - receiver) side.

        Returns:
            object of `BulkCapturer` type.
        """
        return self.__bulk_capturer

    @property
    def display_id(self) -> DisplayIdSink:
        """

        Should be used to control DisplayID functionality on Sink (RX - receiver) side.

        Returns:
            object of `DisplayIdSink` type.
        """
        return self.__display_id

    @property
    def panel_replay(self) -> Optional[SinkPanelReplay]:
        """

        Should be used to control Panel Replay on Sink (RX - receiver) side.

        Returns:
            object of `SinkPanelReplay` type.
        """
        return self.__panel_replay

    @property
    def panel_self_refresh(self) -> Optional[SinkPanelSelfRefresh]:
        """

        Should be used to control Panel Self Refresh on Sink (RX - receiver) side.

        Returns:
            object of `SinkPanelSelfRefresh` type.
        """
        return self.__psr
