# Copyright (c) 2019 Shotgun Software Inc.
#
# CONFIDENTIAL AND PROPRIETARY
#
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.
import sgtk
HookBaseClass = sgtk.get_hook_baseclass()
[docs]class ContextFieldsDisplay(HookBaseClass):
    """
    Used to control the way the current context fields are displayed.
    """
[docs]    def get_entity_fields(self, entity_type):
        """
        Given a particular entity type for the current context, return a list of
        fields to query for display in the header.
        Note: the thumbnail ("image" field) query/display is handled by the
        engine and is not required to be returned by this method.
        :param entity_type: Shotgun entity type to return fields for
        :returns: ``list`` of Shotgun fields
        """
        # supported by all normal fields
        base_fields = [
            "id",
            "type",
            "tag_list",
        ]
        # supported by most entities
        std_fields = base_fields
        std_fields.extend(["code", "project", "sg_status_list", "description"])
        # ---- fields for specific entity contexts
        if entity_type == "Project":
            fields = base_fields
            fields.extend(["name", "sg_status", "sg_description"])
        elif entity_type == "Asset":
            fields = std_fields
            fields.extend(["sg_asset_type"])
        elif entity_type == "Shot":
            fields = std_fields
            fields.extend(
                ["sg_cut_in", "sg_cut_out", "sg_head_in", "sg_tail_out", "sg_sequence"]
            )
        elif entity_type == "Task":
            fields = base_fields
            fields.extend(
                [
                    "task_assignees",
                    "due_date",
                    "entity",
                    "step",
                    "sg_status_list",
                    "project",
                    "content",
                ]
            )
        else:
            fields = std_fields
        return fields 
[docs]    def get_context_html(self, entity, sg_globals):
        """
        Returns the html used to display the supplied context entity.
        This method is called once the engine has queried values for the fields
        returned from the ``get_entity_fields`` method. The supplied entity will
        be populated with the queried values for those fields.
        Note: The default implementation returns a table of field/value names
        that will display next to the entity's thumbnail. The thumbnail query,
        download, and display is handled by the engine, so the html returned
        here will be inserted to the right of that thumbnail.
        :param entity: Shotgun entity to display context fields for.
        :param sg_globals: A handle on the shotgun globals api provided via
            the shotgunutils framework. This is useful for querying display
            names for fields, statuses, etc.
        :returns: An html ``str`` that will be displayed in the panel.
        Here are some css classes that can be used to display text in various
        ways::
             The name of a queried field such as: "Type", "Name", "Shot",
             "Asset", or some other text that doesn't hold a value from PTR or
             doesn't need emphasis:
                `sg_label` - grey label color
                `sg_label_td` - same as `sg_label` but includes alignment and
                    other style for use in table data cells.
             The value of a queried field such as: "Character", "Shot01",
             "Bunny", or some other text that holds a value from PTR or needs
             emphasis:
                `sg_value` - brighter text
                `sg_value_td` - same as `sg_value` but includes alignment and
                    other style for use in table data cells.
        See the default implementation for usage examples.
        """
        if entity is None:
            # site context
            return self._get_site_html()
        # retrieve the html based on the entity type
        entity_type = entity.get("type")
        if entity_type == "Asset":
            html = self._get_asset_html(entity, sg_globals)
        elif entity_type == "Shot":
            html = self._get_shot_html(entity, sg_globals)
        elif entity_type == "Task":
            html = self._get_task_html(entity, sg_globals)
        else:
            # fallback for other entity types.
            html = self._get_entity_html(entity, sg_globals)
        return html 
    def _get_site_html(self):
        """Returns html for displaying a site context."""
        site_url = self.parent.sgtk.shotgun_url
        site_display = site_url.split("//")[-1]
        site_link = self.parent.get_panel_link(site_url, site_display)
        return """
            <table>
              <tr>
                <td class='sg_label_td'>Site:</td>
                <td class='sg_value_td'>{name}</td>
              </tr>
            </table>
            """.format(
            name=site_link,
        )
    def _get_asset_html(self, entity, sg_globals):
        """Returns html for displaying an asset context."""
        asset_link = self._get_entity_sg_link(entity["code"], entity)
        status = sg_globals.get_status_display_name(
            entity["sg_status_list"], project_id=entity["project"]["id"]
        )
        # always include name, type, and status
        html = """
            <table>
              <tr>
                <td class='sg_label_td'>Asset:</td>
                <td class='sg_value_td'>{name}</td>
              </tr>
              <tr>
                <td class='sg_label_td'>Type:</td>
                <td class='sg_value_td'>{type}</td>
              </tr>
              <tr>
                <td class='sg_label_td'>Status:</td>
                <td class='sg_value_td'>{status}</td>
              </tr>
            """.format(
            name=asset_link,
            type=entity["sg_asset_type"],
            status=status,
        )
        # tags if there are any
        if entity["tag_list"]:
            tag_display = ", ".join(entity["tag_list"])
            html += """
                <tr>
                  <td class='sg_label_td'>Tags:</td>
                  <td class='sg_value_td'>{tags}</td>
                </tr>
                """.format(
                tags=tag_display,
            )
        # description if there is one
        if entity["description"]:
            html += """
                <tr>
                  <td class='sg_label_td'>Desc:</td>
                  <td class='sg_value_td'>{desc}</td>
                </tr>
                """.format(
                desc=entity["description"]
            )
        # close up the table
        html += "</table>"
        return html
    def _get_shot_html(self, entity, sg_globals):
        """Returns html for displaying a shot context."""
        shot_link = self._get_entity_sg_link(entity["code"], entity)
        status = sg_globals.get_status_display_name(
            entity["sg_status_list"], project_id=entity["project"]["id"]
        )
        # by default show the shot url
        shot_display = shot_link
        # include seq name next to shot name if there is one.
        # display it as a field name to allow shot name to stand out
        seq = entity["sg_sequence"]
        if seq:
            seq_name = seq["name"]
            seq_link = self._get_entity_sg_link(seq_name, seq)
            shot_display = """
                {name} <span class='sg_label'>({seq_name})</span>
                """.format(
                name=shot_link,
                seq_name=seq_link,
            )
        # always include name, type, and status
        html = """
            <table>
              <tr>
                <td class='sg_label_td'>Shot:</td>
                <td class='sg_value_td'>{name}</td>
              </tr>
              <tr>
                <td class='sg_label_td'>Status:</td>
                <td class='sg_value_td'>{status}</td>
              </tr>
            """.format(
            name=shot_display,
            status=status,
        )
        # tags if there are any
        if entity["tag_list"]:
            tag_display = ", ".join(entity["tag_list"])
            html += """
                <tr>
                  <td class='sg_label_td'>Tags:</td>
                  <td class='sg_value_td'>{tags}</td>
                </tr>
                """.format(
                tags=tag_display,
            )
        # ---- show some cut info if available
        cut_display = None
        # cut in/out
        if entity["sg_cut_in"] is not None and entity["sg_cut_out"] is not None:
            cut_display = """
                    {cut_in} - {cut_out}
                """.format(
                cut_in=entity["sg_cut_in"], cut_out=entity["sg_cut_out"]
            )
        # include head/tail if set
        if (
            cut_display
            and entity["sg_head_in"] is not None
            and entity["sg_tail_out"] is not None
        ):
            cut_display = """
                    <small><span class='sg_label'>{head_in} | </span></small>
                    {cut_display}
                    <small><span class='sg_label'> | {tail_out}</span></small>
                """.format(
                head_in=entity["sg_head_in"],
                cut_display=cut_display,
                tail_out=entity["sg_tail_out"],
            )
        if cut_display:
            html += """
                <tr>
                  <td class='sg_label_td'>Cut:</td>
                  <td class='sg_value_td'>{cut_display}</td>
                </tr>
                """.format(
                cut_display=cut_display,
            )
        # description if there is one
        if entity["description"]:
            html += """
                <tr>
                  <td class='sg_label_td'>Desc:</td>
                  <td class='sg_value_td'>{desc}</td>
                </tr>
                """.format(
                desc=entity["description"]
            )
        # close up the table
        html += "</table>"
        return html
    def _get_task_html(self, entity, sg_globals):
        """Returns html for displaying a task context."""
        task_link = self._get_entity_sg_link(entity["content"], entity)
        status = sg_globals.get_status_display_name(
            entity["sg_status_list"], project_id=entity["project"]["id"]
        )
        # by default show the shot url
        task_display = task_link
        # include step name next to shot name if not the same.
        # display it as a field name to allow shot name to stand out
        step = entity["step"]
        if step:
            step_name = step["name"]
            if step_name != entity["content"]:
                task_display = """
                    {name} <span class='sg_label'>({step_name})</span>
                    """.format(
                    name=task_display,
                    step_name=step_name,
                )
        # always include name
        html = """
            <table>
              <tr>
                <td class='sg_label_td'>Task:</td>
                <td class='sg_value_td'>{name}</td>
              </tr>
            """.format(
            name=task_display
        )
        # entity
        if entity["entity"]:
            linked_entity = entity["entity"]
            if "name" in linked_entity:
                linked_entity_display = linked_entity["name"]
            else:
                linked_entity_display = linked_entity["code"]
            linked_entity_link = self._get_entity_sg_link(
                linked_entity_display, linked_entity
            )
            html += """
                  <tr>
                    <td class='sg_label_td'>{entity_type}:</td>
                    <td class='sg_value_td'>{name}</td>
                  </tr>
                """.format(
                entity_type=linked_entity["type"],
                name=linked_entity_link,
            )
        # always show the status
        html += """
              <tr>
                <td class='sg_label_td'>Status:</td>
                <td class='sg_value_td'>{status}</td>
              </tr>
            """.format(
            status=status
        )
        # artist
        if entity["task_assignees"]:
            assignee_entities = entity["task_assignees"]
            assignee_links = []
            for assignee_entity in assignee_entities:
                asignee_name = assignee_entity["name"]
                assignee_links.append(
                    self._get_entity_sg_link(asignee_name, assignee_entity)
                )
            assignee_display = ", ".join(assignee_links)
            assignee_label = "Artists" if len(assignee_entities) > 1 else "Artist"
            html += """
                  <tr>
                    <td class='sg_label_td'>{label}:</td>
                    <td class='sg_value_td'>{name}</td>
                  </tr>
                """.format(
                label=assignee_label,
                name=assignee_display,
            )
        # due date
        if entity["due_date"]:
            html += """
                  <tr>
                    <td class='sg_label_td'>Due:</td>
                    <td class='sg_value_td'>{date}</td>
                  </tr>
                """.format(
                date=entity["due_date"],
            )
        # close up the table
        html += "</table>"
        return html
    def _get_entity_html(self, entity, sg_globals):
        """Returns html for displaying a generic entity context."""
        # default to name, fall back to code
        entity_display = entity.get("name", entity.get("code"))
        entity_link = self._get_entity_sg_link(entity_display, entity)
        entity_type = entity["type"]
        # always include type/name
        html = """
            <table>
              <tr>
                <td class='sg_label_td'>{entity_type}:</td>
                <td class='sg_value_td'>{name}</td>
              </tr>
            """.format(
            entity_type=entity_type,
            name=entity_link,
        )
        # show a status if one can be determined
        status = None
        if "sg_status_list" in entity:
            status = sg_globals.get_status_display_name(
                entity["sg_status_list"], project_id=entity.get("project", {}).get("id")
            )
        elif "sg_status" in entity:
            status = entity["sg_status"]
        if status:
            html += """
                  <tr>
                    <td class='sg_label_td'>Status:</td>
                    <td class='sg_value_td'>{status}</td>
                  </tr>
                """.format(
                status=status,
            )
        # tags if there are any
        if entity["tag_list"]:
            tag_display = ", ".join(entity["tag_list"])
            html += """
                <tr>
                  <td class='sg_label_td'>Tags:</td>
                  <td class='sg_value_td'>{tags}</td>
                </tr>
                """.format(
                tags=tag_display,
            )
        # description if there is one
        desc = None
        if "description" in entity:
            desc = entity["description"]
        elif "sg_description" in entity:
            desc = entity["sg_description"]
        if desc:
            html += """
                <tr>
                  <td class='sg_label_td'>Desc:</td>
                  <td class='sg_value_td'>{desc}</td>
                </tr>
                """.format(
                desc=desc
            )
        # close up the table
        html += "</table>"
        return html
    def _get_entity_sg_link(self, text, entity):
        """
        Given some text, return html formatted link to the given entity in PTR.
        """
        url = "%s/detail/%s/%d" % (
            self.parent.sgtk.shotgun_url,
            entity["type"],
            entity["id"],
        )
        return self.parent.get_panel_link(url, text)