"""
novelWriter – GUI Item Details Panel
====================================
GUI class for the project tree item details panel

File History:
Created: 2019-04-24 [0.0.1]

This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""

import logging

from PyQt5.QtCore import Qt, pyqtSlot
from PyQt5.QtGui import QFont, QPixmap
from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel

from novelwriter import CONFIG
from novelwriter.constants import trConst, nwLabels

logger = logging.getLogger(__name__)


class GuiItemDetails(QWidget):

    def __init__(self, mainGui):
        super().__init__(parent=mainGui)

        logger.debug("Create: GuiItemDetails")

        self.mainGui    = mainGui
        self.theProject = mainGui.theProject
        self.mainTheme  = mainGui.mainTheme

        # Internal Variables
        self._itemHandle  = None

        # Sizes
        hSp = CONFIG.pxInt(6)
        vSp = CONFIG.pxInt(1)
        mPx = CONFIG.pxInt(6)
        fPt = self.mainTheme.fontPointSize

        fntLabel = QFont()
        fntLabel.setBold(True)
        fntLabel.setPointSizeF(0.9*fPt)

        fntValue = QFont()
        fntValue.setPointSizeF(0.9*fPt)

        # Label
        self.labelName = QLabel(self.tr("Label"))
        self.labelName.setFont(fntLabel)
        self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)

        self.labelIcon = QLabel("")
        self.labelIcon.setAlignment(Qt.AlignRight | Qt.AlignBaseline)

        self.labelData = QLabel("")
        self.labelData.setFont(fntValue)
        self.labelData.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
        self.labelData.setWordWrap(True)

        # Status
        self.statusName = QLabel(self.tr("Status"))
        self.statusName.setFont(fntLabel)
        self.statusName.setAlignment(Qt.AlignLeft)

        self.statusIcon = QLabel("")
        self.statusIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.statusData = QLabel("")
        self.statusData.setFont(fntValue)
        self.statusData.setAlignment(Qt.AlignLeft)

        # Class
        self.className = QLabel(self.tr("Class"))
        self.className.setFont(fntLabel)
        self.className.setAlignment(Qt.AlignLeft)

        self.classIcon = QLabel("")
        self.classIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.classData = QLabel("")
        self.classData.setFont(fntValue)
        self.classData.setAlignment(Qt.AlignLeft)

        # Layout
        self.usageName = QLabel(self.tr("Usage"))
        self.usageName.setFont(fntLabel)
        self.usageName.setAlignment(Qt.AlignLeft)

        self.usageIcon = QLabel("")
        self.usageIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.usageData = QLabel("")
        self.usageData.setFont(fntValue)
        self.usageData.setAlignment(Qt.AlignLeft)
        self.usageData.setWordWrap(True)

        # Character Count
        self.cCountName = QLabel("  "+self.tr("Characters"))
        self.cCountName.setFont(fntLabel)
        self.cCountName.setAlignment(Qt.AlignRight)

        self.cCountData = QLabel("")
        self.cCountData.setFont(fntValue)
        self.cCountData.setAlignment(Qt.AlignRight)

        # Word Count
        self.wCountName = QLabel("  "+self.tr("Words"))
        self.wCountName.setFont(fntLabel)
        self.wCountName.setAlignment(Qt.AlignRight)

        self.wCountData = QLabel("")
        self.wCountData.setFont(fntValue)
        self.wCountData.setAlignment(Qt.AlignRight)

        # Paragraph Count
        self.pCountName = QLabel("  "+self.tr("Paragraphs"))
        self.pCountName.setFont(fntLabel)
        self.pCountName.setAlignment(Qt.AlignRight)

        self.pCountData = QLabel("")
        self.pCountData.setFont(fntValue)
        self.pCountData.setAlignment(Qt.AlignRight)

        # Assemble
        self.mainBox = QGridLayout(self)
        self.mainBox.addWidget(self.labelName,  0, 0, 1, 1)
        self.mainBox.addWidget(self.labelIcon,  0, 1, 1, 1)
        self.mainBox.addWidget(self.labelData,  0, 2, 1, 3)

        self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
        self.mainBox.addWidget(self.statusIcon, 1, 1, 1, 1)
        self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
        self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
        self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)

        self.mainBox.addWidget(self.className,  2, 0, 1, 1)
        self.mainBox.addWidget(self.classIcon,  2, 1, 1, 1)
        self.mainBox.addWidget(self.classData,  2, 2, 1, 1)
        self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
        self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)

        self.mainBox.addWidget(self.usageName,  3, 0, 1, 1)
        self.mainBox.addWidget(self.usageIcon,  3, 1, 1, 1)
        self.mainBox.addWidget(self.usageData,  3, 2, 1, 1)
        self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
        self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)

        self.mainBox.setColumnStretch(0, 0)
        self.mainBox.setColumnStretch(1, 0)
        self.mainBox.setColumnStretch(2, 1)
        self.mainBox.setColumnStretch(3, 0)
        self.mainBox.setColumnStretch(4, 0)

        self.mainBox.setHorizontalSpacing(hSp)
        self.mainBox.setVerticalSpacing(vSp)
        self.mainBox.setContentsMargins(mPx, mPx, mPx, mPx)

        self.setLayout(self.mainBox)

        self.updateTheme()

        # Make sure the columns for flags and counts don't resize too often
        flagWidth  = self.mainTheme.getTextWidth("Mm", fntValue)
        countWidth = self.mainTheme.getTextWidth("99,999", fntValue)
        self.mainBox.setColumnMinimumWidth(1, flagWidth)
        self.mainBox.setColumnMinimumWidth(4, countWidth)

        logger.debug("Ready: GuiItemDetails")

        return

    ###
    #  Class Methods
    ##

    def clearDetails(self):
        """Clear all the data values.
        """
        self._itemHandle = None

        self.labelIcon.setPixmap(QPixmap(1, 1))
        self.statusIcon.setPixmap(QPixmap(1, 1))
        self.classIcon.setText("")
        self.usageIcon.setText("")

        self.labelData.setText("–")
        self.statusData.setText("–")
        self.classData.setText("–")
        self.usageData.setText("–")

        self.cCountData.setText("–")
        self.wCountData.setText("–")
        self.pCountData.setText("–")

        return

    def refreshDetails(self):
        """Reload the content of the details panel.
        """
        self.updateViewBox(self._itemHandle)

    def updateTheme(self):
        """Update theme elements.
        """
        self.updateViewBox(self._itemHandle)
        return

    ##
    #  Public Slots
    ##

    @pyqtSlot(str)
    def updateViewBox(self, tHandle):
        """Populate the details box from a given handle.
        """
        if tHandle is None:
            self.clearDetails()
            return

        nwItem = self.theProject.tree[tHandle]
        if nwItem is None:
            self.clearDetails()
            return

        self._itemHandle = tHandle
        iPx = int(round(0.8*self.mainTheme.baseIconSize))

        # Label
        # =====

        theLabel = nwItem.itemName
        if len(theLabel) > 100:
            theLabel = theLabel[:96].rstrip()+" ..."

        if nwItem.isFileType():
            if nwItem.isActive:
                self.labelIcon.setPixmap(self.mainTheme.getPixmap("checked", (iPx, iPx)))
            else:
                self.labelIcon.setPixmap(self.mainTheme.getPixmap("unchecked", (iPx, iPx)))
        else:
            self.labelIcon.setPixmap(self.mainTheme.getPixmap("noncheckable", (iPx, iPx)))

        self.labelData.setText(theLabel)

        # Status
        # ======

        theStatus, theIcon = nwItem.getImportStatus(incIcon=True)
        self.statusIcon.setPixmap(theIcon.pixmap(iPx, iPx))
        self.statusData.setText(theStatus)

        # Class
        # =====

        classIcon = self.mainTheme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass])
        self.classIcon.setPixmap(classIcon.pixmap(iPx, iPx))
        self.classData.setText(trConst(nwLabels.CLASS_NAME[nwItem.itemClass]))

        # Layout
        # ======

        usageIcon = self.mainTheme.getItemIcon(
            nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, nwItem.mainHeading
        )
        self.usageIcon.setPixmap(usageIcon.pixmap(iPx, iPx))
        self.usageData.setText(nwItem.describeMe())

        # Counts
        # ======

        if nwItem.isFileType():
            self.cCountData.setText(f"{nwItem.charCount:n}")
            self.wCountData.setText(f"{nwItem.wordCount:n}")
            self.pCountData.setText(f"{nwItem.paraCount:n}")
        else:
            self.cCountData.setText("–")
            self.wCountData.setText("–")
            self.pCountData.setText("–")

        return

    @pyqtSlot(str, int, int, int)
    def updateCounts(self, tHandle, cC, wC, pC):
        """Update the counts if the handle is the same as the one we're
        already showing. Otherwise, do nothing.
        """
        if tHandle == self._itemHandle:
            self.cCountData.setText(f"{cC:n}")
            self.wCountData.setText(f"{wC:n}")
            self.pCountData.setText(f"{pC:n}")

        return

# END Class GuiItemDetails
