/*
    SPDX-FileCopyrightText: Copyright (C) 2022 The Qt Company Ltd.
    SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
    SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
    SPDX-FileCopyrightText: 2023 David Redondo <kde@david-redondo.de>
    SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-or-later
*/

import QtQuick
import QtQuick.Layouts
import QtQuick.Templates as T
import org.kde.kirigami as Kirigami
import org.kde.qqc2desktopstyle.private as StylePrivate
import org.kde.desktop.private as Private

T.TreeViewDelegate {
    id: controlRoot

    implicitWidth: leftMargin + __contentIndent + implicitContentWidth  + rightMargin + (mirrored ? leftPadding : rightPadding)
    implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight, implicitIndicatorHeight) + topPadding + bottomPadding

    // This is the default size of the indicator when using Breeze aka pixelMetric("treeviewindentation")
    indentation: indicator ? indicator.width : 20

    leftMargin: Kirigami.Units.smallSpacing
    rightMargin: Kirigami.Units.smallSpacing
    spacing:  Kirigami.Units.smallSpacing

    leftPadding: !mirrored ? leftMargin + __contentIndent : 0
    rightPadding: mirrored ? leftMargin + __contentIndent : 0
    verticalPadding: Kirigami.Units.smallSpacing

    leftInset: TableView.view ? 0 : horizontalPadding / 2
    rightInset: TableView.view ? 0 : horizontalPadding / 2
    topInset: TableView.view ? 0 : Math.ceil(verticalPadding / 2)
    bottomInset: TableView.view ? 0 : Math.ceil(verticalPadding / 2)

    Kirigami.Theme.colorSet: highlighted ? Kirigami.Theme.Selection : Kirigami.Theme.View
    Kirigami.Theme.inherit: false

    highlighted: controlRoot.selected || controlRoot.current
               || ((controlRoot.treeView.selectionBehavior === TableView.SelectRows
               || controlRoot.treeView.selectionBehavior === TableView.SelectionDisabled)
               && controlRoot.row === controlRoot.treeView.currentRow)

    icon.width: Kirigami.Units.iconSizes.smallMedium
    icon.height: Kirigami.Units.iconSizes.smallMedium

    T.ToolTip.visible: (Kirigami.Settings.tabletMode ? down : hovered) && (contentItem.truncated ?? false)
    T.ToolTip.text: action instanceof Kirigami.Action ? action.tooltip : controlRoot.model.display
    T.ToolTip.delay: Kirigami.Settings.tabletMode ? Qt.styleHints.mousePressAndHoldInterval : Kirigami.Units.toolTipDelay

    required property int row
    required property int column
    required property var model
    readonly property real __contentIndent: !isTreeNode ? 0 : (depth * indentation) + (indicator ? indicator.width + spacing : 0)

    Loader {
        id: mainIndicator
        active: controlRoot.isTreeNode

        sourceComponent: StylePrivate.StyleItem {
            readonly property real __indicatorIndent: controlRoot.leftMargin + (controlRoot.depth * controlRoot.indentation)
            x: !controlRoot.mirrored ? __indicatorIndent : controlRoot.width - __indicatorIndent - width
            height: controlRoot.height
            width: pixelMetric("treeviewindentation")
            hover: hover.hovered
            elementType: "itembranchindicator"
            on: controlRoot.expanded
            selected: controlRoot.highlighted || controlRoot.checked || (controlRoot.pressed && !controlRoot.checked)
            properties: {
                "isItem": true,
                "hasChildren": true,
                "hasSibling": controlRoot.treeView.model.rowCount(controlRoot.treeView.index(controlRoot.row, controlRoot.column).parent) > controlRoot.row + 1
            }
            HoverHandler {
                id: hover
            }
        }

    }

    // The indicator is only visible when the item has children, so  this is only the closest branch indicator (+arrow) - the rest of the branch indicator lines are below
    indicator: mainIndicator.item

    // The rest of the branch indicators, this is outside of the background so consumers can freely
    // modify it without losing it
    StylePrivate.ItemBranchIndicators {
        visible: controlRoot.isTreeNode
        height: parent.height
        x: controlRoot.mirrored ? controlRoot.width - controlRoot.leftMargin - width : controlRoot.leftMargin
        modelIndex: controlRoot.treeView.index(controlRoot.row, controlRoot.column)
        selected: controlRoot.highlighted || controlRoot.checked || (controlRoot.pressed && !controlRoot.checked)
        rootIndex: controlRoot.treeView.rootIndex
    }

    background: Private.DefaultListItemBackground {
        Kirigami.Theme.colorSet: Kirigami.Theme.View
        Kirigami.Theme.inherit: false
        // This is intentional and ensures the inset is not directly applied to
        // the background, allowing it to determine how to handle the inset.
        anchors.fill: parent
        control: controlRoot
    }

    contentItem: RowLayout {
        LayoutMirroring.enabled: controlRoot.mirrored
        spacing: controlRoot.spacing

        property alias truncated: textLabel.truncated

        Kirigami.Icon {
            Layout.alignment: Qt.AlignVCenter
            visible: controlRoot.icon.name !== "" || controlRoot.icon.source.toString() !== "" || controlRoot.model.decoration !== undefined
            source: controlRoot.icon.name !== "" ? controlRoot.icon.name : controlRoot.icon.source.toString() !== "" ? controlRoot.icon.source : controlRoot.model.decoration
            Layout.preferredHeight: controlRoot.icon.height
            Layout.preferredWidth: controlRoot.icon.width
            selected: controlRoot.highlighted || controlRoot.checked || (controlRoot.pressed && !controlRoot.checked)
        }
        Label {
            id: textLabel

            Layout.fillWidth: true
            Layout.fillHeight: true

            text: controlRoot.model.display
            font: controlRoot.font
            color: controlRoot.highlighted || controlRoot.checked || (controlRoot.pressed && !controlRoot.checked)
                ? Kirigami.Theme.highlightedTextColor
                : (controlRoot.enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor)
            elide: Text.ElideRight
            visible: text !== ""
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
        }
    }
}
