# -*- coding: utf-8 -*-

# basket.py
# This file is part of qarte-5
#    
# Author: Vincent Vande Vyvre <vincent.vandevyvre@oqapy.eu>
# Copyright: 2011-2024 Vincent Vande Vyvre
# Licence: GPL3
# Home page: https://launchpad.net/qarte
#
# Dowloading basket

from PyQt5.QtCore import (Qt, pyqtSignal, QSize, QMimeData, QPoint, QTimer,
                          QCoreApplication, QItemSelectionModel, )
from PyQt5.QtGui import (QIcon, QPixmap, QDrag, )
from PyQt5.QtWidgets import (QTableWidget, QAbstractItemView, QApplication,
                             QTableWidgetItem, QToolButton, QWidget, 
                             QVBoxLayout)

#from arteconcert import ConcertItem


class Basket(QTableWidget):
    itemAdded = pyqtSignal(int)
    def __init__(self, ui, driver, parent=None):
        super().__init__(parent)
        self.ui = ui
        self.core = ui.core
        self.driver = driver
        self.lst_movies = []
        self.setShowGrid(False)
        self.setDragEnabled(True)
        self.setDragDropMode(QAbstractItemView.InternalMove)
        self.setDefaultDropAction(Qt.CopyAction)
        self.setDropIndicatorShown(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.verticalHeader().hide()
        self.horizontalHeader().hide()
        self.setIconSize(QSize(85, 48))
        self.setColumnCount(3)
        self.setColumnWidth(0, 85)
        self.setColumnWidth(1, 165)
        self.setColumnWidth(2, 24)

    def mousePressEvent(self, event):
        self.idx = False
        mod = QApplication.keyboardModifiers()
        idx = self.indexAt(event.pos())
        btn = event.button()
        if btn == 1 and not idx.isValid():
            self.clearSelection()

        elif btn == 1 and idx.isValid():
            self.idx = idx

        QTableWidget.mousePressEvent(self, event)

    def startDrag(self, event):
        item = self.currentItem() 
        pixmap = item.icon().pixmap(QSize(100, 60))
        data = str(item.row())
        mimeData = QMimeData()
        mimeData.setText("task:%s" % data)
        drag = QDrag(self)
        drag.setPixmap(pixmap)
        drag.setMimeData(mimeData)
        drag.setHotSpot(QPoint(50, 60))
        res = drag.exec_(Qt.MoveAction)

    def dragEnterEvent(self, event):
        if event.mimeData().hasText():
            event.accept()

        else:
            event.ignore()

    def dragMoveEvent(self, event):
        idx = self.indexAt(event.pos())
        if idx.isValid() and event.mimeData().hasText():
            event.setDropAction(Qt.MoveAction)
            self.highlight_item(self.indexAt(event.pos()))

        elif str(event.mimeData().text()).startswith('new'):
            event.setDropAction(Qt.MoveAction)

        else:
            event.setDropAction(Qt.MoveAction)

    def dragLeaveEvent(self, event):
        pass

    def dropEvent(self, event):
        idx = self.indexAt(event.pos())
        if not event.mimeData().hasText():
            event.ignore()
            return

        data = str(event.mimeData().text())
        if "task" in data:
            task = int(data.split(":")[1])
            if idx.isValid() and idx != self.idx:
                self.move_item_to(self.idx.row(), idx.row())

        elif data.startswith('new'):
            self.add_object(int(data.split(' ')[1]))

    def move_item_to(self, src, dest):
        if not dest and self.driver.is_loading:
            # Don't shift the item 0 if is loading
            if src == 1:
                return

            dest == 1

        ic = self.item(src, 0).icon()
        txt = self.item(src, 1).text()
        video = self.remove_item(src, True)
        self.insertRow(dest)
        self.setRowHeight(dest, 48)
        item = QTableWidgetItem()
        item.setIcon(ic)
        self.setItem(dest, 0, item)
        item = QTableWidgetItem()
        item.setText(txt)
        self.setItem(dest, 1, item)
        if self.driver == "Concert":
            item = TableButton(dest, 'remove', item)
            self.setCellWidget(dest, 2, item)

        else:
            item = TableButtons(dest, item)
            self.setCellWidget(dest, 2, item)

        self.update_buttons()
        self.lst_movies.insert(dest, video)
        self.driver.downloader.shift_task(src, dest)

    def remove_item(self, item, shifted=False):
        """Remove one item from table and from list.

        """
        if isinstance(item, int):
            idx = item

        else:
            idx = self.lst_movies.index(item)

        self.removeRow(idx)
        try:
            video = self.lst_movies.pop(idx)
        except IndexError:
            # Already removed by the user
            video = None
        if not shifted:
            try:
                self.driver.downloader.remove_task(idx)
            except:
                # arte_concert don't have an attribute downloader
                pass
        self.clearSelection()
        self.update_buttons()
        if not self.rowCount():
            self.driver.on_empty_list()

        return video

    def remove_first(self):
        self.removeRow(0)
        self.lst_movies.pop(0)

    def is_empty(self):
        return not self.rowCount()

    def print_titles(self):
        """Debugging function"""
        for v in self.lst_movies:
            print(v.title)

    def highlight_item(self, idx):
        self.clearSelection()
        self.selectionModel().setCurrentIndex(idx, QItemSelectionModel.Select)

    def update_buttons(self):
        for r in range(self.rowCount()):
            # There's no item in column 2 for the concerts basket
            if self.cellWidget(r, 2) is not None:
                self.cellWidget(r, 2).row_ = r

    def config_download(self, movie):
        self.driver.configure_downloading(movie)

    def add_concert(self, video, pixmap):
        """Add an item concert into the basket.

        Args:
        video -- instance of ConcertItem
        pixmap -- the image used into the viewer
        """
        text = video.fname
        if text is None:
            text = video.title

        text = self.format_text(text)
        r = self.rowCount()
        self.insertRow(r)
        self.setRowHeight(r, 48) 
        item = QTableWidgetItem()
        item.setIcon(QIcon(pixmap))
        self.setItem(r, 0, item)
        item = QTableWidgetItem()
        item.setText(text)
        self.setItem(r, 1, item)
        item = TableButton(video, 'remove', self)
        self.setCellWidget(r, 2, item)
        self.lst_movies.append(video)

    def add_object(self, idx, settings=True):
        """Add a video into the basket.

        Args:
        idx -- index of video
        settings -- if True, display the button settings.
                    Not used in arte concerts
        """
        if self.driver.is_in_category:
            video = self.ui.arte_list.video_items[idx].item

        else:
            video = self.driver.videos[idx]

        if video in self.lst_movies:
            self.ui.arte_list.clearSelection()
            return

        def send_signal():
            self.itemAdded.emit(idx)

        img = QPixmap(video.pixmap)
        text = self.format_text(video.fname)
        r = self.rowCount()
        self.insertRow(r)
        self.setRowHeight(r, 48) 
        item = QTableWidgetItem()
        item.setIcon(QIcon(img))
        self.setItem(r, 0, item)
        item = QTableWidgetItem()
        item.setText(text)
        self.setItem(r, 1, item)
        item = TableButtons(video, self)
        self.setCellWidget(r, 2, item)

        self.lst_movies.append(video)
        QCoreApplication.processEvents()
        self.ui.tv_basket_buttons.dwnld_btn.setEnabled(True)
        self.ui.action_Download.setEnabled(True)
        self.ui.arte_list.clearSelection()
        timer = QTimer()
        timer.singleShot(300, send_signal)
        timer.start()

    def rename(self, row, txt):
        """Rename an item.

        Args:
        row -- row
        txt -- new name
        """
        self.item(row, 1).setText(txt)

    def format_text(self, txt):
        if len(txt) > 32:
            txt = txt[:28] + "..."

        return txt

    def format_text_(self, txt):
        """Format the movie's title.

        Args:
        txt -- title

        Returns:
        Formated text
        """
        if len(txt) < 31:
            return txt

        form = ""
        while 1:
            chain = txt[:31]
            count = len(chain) - 1
            while 1:
                if chain[count]  in [" ", "_", "-"]:
                    break

                count -= 1
                if count == 0:
                    count = len(chain) - 1
                    break

            form = form + chain[:count] + "\n"
            txt = txt[count+1:]
            if not txt:
                break

            elif len(txt) < 31:
                form = form + txt + "\n"
                break

        return form[:-1]

    def disable_settings(self):
        """Disable the settings for the video that is downloading.

        """
        try:
            self.cellWidget(0, 3).setEnabled(False)
            self.cellWidget(0, 2).setEnabled(False)
        except:
            pass

class TableButton(QToolButton):
    def __init__(self, item, feature, parent=None):
        super().__init__()
        self.item = item
        self.feature = feature
        self.table = parent
        self.setIconSize(QSize(20, 20))
        self.set_icon()
        self.clicked.connect(self.send_signal)
        self.setStyleSheet("""
                QToolButton {background-color: qlineargradient(
                    x1: 0, y1: 0, x2: 0, y2: 1,
                    stop: 0 #FFFFFF, stop: 0.4 #FAFAFA,
                    stop: 0.5 #FDFDFD, stop: 1.0 #F0F0F0);
                    border-radius: 4px;
                    padding: 2px;}
                QToolButton:hover {border: 2px solid #CC1D00;}
                QToolButton:pressed {background-color: qlineargradient(
                    x1: 0, y1: 0, x2: 0, y2: 1,
                    stop: 0 #000000, stop: 0.4 #050505,
                    stop: 0.5 #606060, stop: 1.0 #101010);}""")

    def set_icon(self):
        icon = QIcon()
        if self.feature == 'settings':
            pix = QPixmap('medias/settings.png')

        else:
            pix = QPixmap('medias/list-remove.png')
        icon.addPixmap(pix, QIcon.Normal, QIcon.Off)
        self.setIcon(icon)

    def send_signal(self, b):
        if self.feature == 'remove':
            self.table.remove_item(self.item)

        else:
            self.table.config_download(self.item)

class TableButtons(QWidget):
    def __init__(self, video, parent=None):
        super().__init__()
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        self.settings_btn = TableButton(video, "settings", parent)
        layout.addWidget(self.settings_btn)
        self.remove_btn = TableButton(video, "remove", parent)
        layout.addWidget(self.remove_btn)




