# Copyright (c) 2018-2021, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#
__all__ = ["AbstractStageColumnDelegate", "StageColumnItem"]

from pxr import Sdf, Usd
from typing import List
from .stage_item import StageItem

import abc
import omni.ui as ui


class StageColumnItem:  # pragma: no cover
    """
    It's not clear which data we need to pass to build_widget. It's path, but
    there are potentially other information the column has. To keep API
    unchanged over the time, we pass data in a struct. It also allow to pass
    custom data with deriving from this class.
    """

    def __init__(self, path: Sdf.Path, stage: Usd.Stage, enabled: bool, expanded: bool = True):
        """
        ## Arguments
            `path`: Full path to the item
            `stage`: USD Stage
            `enabled`: When false, the widget should be grayed out
        """

        self._path = path
        self._stage = stage
        self._enabled = enabled
        self._expanded = expanded

    @property
    def path(self):
        return self._path

    @property
    def stage(self):
        return self._stage

    @property
    def enabled(self):
        return self._enabled

    @property
    def expanded(self):
        return self._expanded


class AbstractStageColumnDelegate(metaclass=abc.ABCMeta):  # pragma: no cover
    """
    An abstract object that is used to put the widget to the file browser
    asynchronously.
    """

    def destroy(self):
        """Place to release resources."""
        pass

    @property
    def initial_width(self):
        """The initial width of the column."""

        return ui.Fraction(1)

    @property
    def minimum_width(self):
        return ui.Pixel(10)

    def build_header(self, **kwargs):
        """
        Build the header widget. If the column is sortable,
        stage widget will help to build a background rectangle
        that has hover state to tell user if the column is sortable so
        all columns don't need to build that by themself. You can override
        this function to build customized widgets as column header.
        """

        pass

    @abc.abstractmethod
    async def build_widget(self, item: StageColumnItem, **kwargs):
        """
        Build the widget for the given path. Works inside Frame in async
        mode. Once the widget is created, it will replace the content of the
        frame. It allow to await something for a while and create the widget
        when the result is available.

        Args:
            item (StageColumnItem): DEPRECATED. It includes the non-cached simple prim
                information. It's better to use keyword argument `stage_item` instead, which
                provides cached rich information about the prim influened by this column.

        Keyword Arguments:
            stage_model (StageModel): The instance of current StageModel.
            stage_item (StageItem): The current StageItem to build. It's possible that
                stage_item is None when TreeView enabled display of root node.
        """

        pass

    def on_header_hovered(self, hovered: bool):
        """Callback when header area is hovered."""
        pass

    def on_stage_items_destroyed(self, items: List[StageItem]):
        """
        Called when stage items are destroyed to give opportunity to delegate to release
        corresponding resources.
        """

        pass

    @property
    def sortable(self):
        """
        Whether this column is sortable or not. When it's True, stage widget will build header
        widget with hover and selection state to tell user it's sortable. This is only used
        to instruct user that this column is sortable from UX.
        """

        return False

    @property
    def order(self):
        """
        The order to sort columns. The columns are sorted in ascending order from left to right of the stage widget.
        So the smaller the order is, the closer the column is to the left of the stage widget.
        """

        return 0
