# **************************************************************************
# *                                                                        *
# *  Copyright (C) Golaem S.A. - All Rights Reserved.                      *
# *                                                                        *
# **************************************************************************

import os
from ..Qtpy.Qt import QtCore, QtGui, QtWidgets

# **********************************************************************
#
# SetMeshAssetsWidget
#
# **********************************************************************
class SetMeshAssetsDialog(QtWidgets.QDialog):
    # ------------------------------------------------------------------
    def __init__(self, parent=None):
        super(SetMeshAssetsDialog, self).__init__(parent)

        self.setMeshAssetsWidget = SetMeshAssetsWidget(self)
        if(not self.setMeshAssetsWidget.okCancelButtons is None):
            self.setMeshAssetsWidget.okCancelButtons.accepted.connect(self.accept)
            self.setMeshAssetsWidget.okCancelButtons.rejected.connect(self.reject)

        self.setWindowTitle('Add / Remove Mesh Assets')
        vertLayout = QtWidgets.QVBoxLayout()
        vertLayout.addWidget(self.setMeshAssetsWidget)
        self.setLayout(vertLayout)

    def exec_(self):
        self.setMeshAssetsWidget.updateUI()
        return super(SetMeshAssetsDialog, self).exec_()

# **********************************************************************
#
# SetMeshAssetsWidget
#
# **********************************************************************
class SetMeshAssetsWidget(QtWidgets.QWidget):
    # ------------------------------------------------------------------
    def __init__(self, parent=None):
        super(SetMeshAssetsWidget, self).__init__(parent)

        # Data Members
        self.availableMeshes = []           # ordered list of the available mesh names
        self.availableMeshesGroups = []     # list of list of availables mesh names that should be grouped
        self.selectedMeshesIndices = []     # list of mesh indices that are in the current selection
        self.okCancelButtons = None

        # Init
        self.initUI()

    # ------------------------------------------------------------------
    def initUI(self):
        #iconsDir = wrapper.WindowMayaWrapper().getIconsDir()
        self.setWindowTitle('Add / Remove Mesh Assets')

        # Main layout
        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)
        self.setLayout(self.mainLayout)

        # info widget...
        self.infoLayout = QtWidgets.QVBoxLayout()
        self.infoWidget = QtWidgets.QWidget(self)
        self.infoWidget.setLayout(self.infoLayout)
        self.mainLayout.addWidget(self.infoWidget)

        # search label and line...
        assetSearchLabel = QtWidgets.QLabel(self)
        assetSearchLabel.setText('Search: ')
        self.assetLineEdit = QtWidgets.QLineEdit(self)
        self.assetLineEdit.textChanged.connect(self.onSearchLineEditChanged)
        #... and layout
        searchLayout = QtWidgets.QHBoxLayout()
        searchWidget = QtWidgets.QWidget(self)
        searchWidget.setLayout(searchLayout)
        searchLayout.addWidget(assetSearchLabel)
        searchLayout.addWidget(self.assetLineEdit)
        self.mainLayout.addWidget(searchWidget)

        # mesh asset list...
        assetsListLabel = QtWidgets.QLabel("Available assets:", self)
        self.assetsListWidget = QtWidgets.QListWidget(self)
        self.assetsListWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.assetsListWidget.itemDoubleClicked.connect(self.on_moveToSelectionButton_clicked)
        # current selection
        selectionListLabel = QtWidgets.QLabel("Selected assets:", self)
        self.selectionListWidget = QtWidgets.QListWidget(self)
        self.selectionListWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.selectionListWidget.itemDoubleClicked.connect(self.on_removeFromSelectionButton_clicked)
        # buttons
        moveToSelectionButton = QtWidgets.QToolButton(self)
        moveToSelectionButton.setText(" >> ")
        moveToSelectionButton.setAutoRaise(True)
        moveToSelectionButton.clicked.connect(self.on_moveToSelectionButton_clicked)
        removeFromSelectionButton = QtWidgets.QToolButton(self)
        removeFromSelectionButton.setText(" << ")
        removeFromSelectionButton.setAutoRaise(True)
        removeFromSelectionButton.clicked.connect(self.on_removeFromSelectionButton_clicked)
        buttonsLayout = QtWidgets.QVBoxLayout()
        buttonsLayout.addStretch()
        buttonsLayout.addWidget(moveToSelectionButton)
        buttonsLayout.addWidget(removeFromSelectionButton)
        buttonsLayout.addStretch()
        #... and layout
        meshListsLayout = QtWidgets.QGridLayout()
        meshListsLayout.addWidget(assetsListLabel, 0, 0)
        meshListsLayout.addWidget(self.assetsListWidget, 1, 0)
        meshListsLayout.addLayout(buttonsLayout, 1, 1)
        meshListsLayout.addWidget(selectionListLabel, 0, 2)
        meshListsLayout.addWidget(self.selectionListWidget, 1, 2)
        self.mainLayout.addLayout(meshListsLayout)

        # OK Cancel buttons...
        self.okCancelButtons = QtWidgets.QDialogButtonBox(self)
        self.okCancelButtons.orientation = QtCore.Qt.Horizontal
        self.okCancelButtons.setStandardButtons(QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Cancel)
        #... and layout
        bottomButtonsLayout = QtWidgets.QHBoxLayout()
        bottomButtonsLayout.addWidget(self.okCancelButtons)
        self.mainLayout.addLayout(bottomButtonsLayout)
        
        self.updateUI()

    # ------------------------------------------------------------------
    def updateUI(self):
        #fill additional values when selection is higher than the max list
        maxValue = -1
        for iCurrentSel in self.selectedMeshesIndices:
            maxValue = max(maxValue, iCurrentSel)
        if (maxValue > -1):
            for iOutOfRangeAsset in range(len(self.availableMeshes), maxValue + 1):
                if(not (iOutOfRangeAsset in self.availableMeshes)):
                    self.availableMeshes.append("Value {} out of range".format(iOutOfRangeAsset))


        # prepare the list of groups and assets in each groups in way that is easy to iterate
        groups = list()
        availableAssetsByGroups = list()
        ungroupedAssets = list(self.availableMeshes)
        for assetGroup in self.availableMeshesGroups:
            #mesh asset might be either directly a mesh asset, or a group of mesh assets separated by a ';'
            groupNameAndAssets = assetGroup.split(':')
            groupName = ""
            assets = list()
            if(len(groupNameAndAssets)>1):
                #the groupe name and the list
                groupName = "--- {} ---".format(groupNameAndAssets[0])
                assets = groupNameAndAssets[1]
            else:
                #the list only
                groupName = "---------"
                assets = groupNameAndAssets[0]
            tmpAssets = assets.split(';')
            assets = []
            [assets.append(str(asset).strip()) for asset in tmpAssets if str(asset).strip() not in assets]

            groups.append(groupName)
            availableAssetsByGroups.append(assets)
            for asset in assets:
                if(asset in ungroupedAssets):
                    ungroupedAssets.remove(asset)

        #debug print all groups and assets
        # for iGroup in range(len(groups)):
        #     print(groups[iGroup])
        #     for asset in availableAssetsByGroups[iGroup]:
        #         print(asset)

        #fill available mesh assets values
        self.assetsListWidget.clear()
        self.selectionListWidget.clear()
        #by group
        for iGroup in range(len(groups)):
            groupItem = QtWidgets.QListWidgetItem(groups[iGroup])
            groupItem.setBackgroundColor(QtGui.QColor(120, 120, 120))
            self.assetsListWidget.addItem(groupItem)
            groupItem = QtWidgets.QListWidgetItem(groups[iGroup])
            groupItem.setBackgroundColor(QtGui.QColor(120, 120, 120))
            self.selectionListWidget.addItem(groupItem)
            for asset in availableAssetsByGroups[iGroup]:
                #add it to the correct list (selected or not)
                iAsset = self.findAssetIndex(str(asset))
                if(iAsset in self.selectedMeshesIndices):
                    self.selectionListWidget.addItem(asset)
                else:
                    self.assetsListWidget.addItem(asset)
        #assets that do not belong to any group
        if(len(ungroupedAssets)>0 and len(groups)>0):
            groupItem = QtWidgets.QListWidgetItem("--- Ungrouped assets ---")
            groupItem.setBackgroundColor(QtGui.QColor(120, 120, 120))
            self.selectionListWidget.addItem(groupItem)
            groupItem = QtWidgets.QListWidgetItem("--- Ungrouped assets ---")
            groupItem.setBackgroundColor(QtGui.QColor(120, 120, 120))
            self.assetsListWidget.addItem(groupItem)
        for asset in ungroupedAssets:
            #add it to the correct list (selected or not)
            iAsset = self.findAssetIndex(str(asset))
            if(iAsset in self.selectedMeshesIndices):
                self.selectionListWidget.addItem(asset)
            else:
                self.assetsListWidget.addItem(asset)

        #update from search field
        self.updateAssetsListFromSearch(self.assetsListWidget, self.assetLineEdit.text())
        self.updateAssetsListFromSearch(self.selectionListWidget, self.assetLineEdit.text())
        
    # ------------------------------------------------------------------
    def findAssetIndex(self, assetName):
        #find global mesh asset index
        iAsset=-1
        for iAvailableMesh in range(len(self.availableMeshes)):
            if (str(self.availableMeshes[iAvailableMesh]) == str(assetName)):
                iAsset=iAvailableMesh
                break
        return iAsset

    # ------------------------------------------------------------------
    def on_moveToSelectionButton_clicked(self):
        for selectedItem in self.assetsListWidget.selectedItems():
            for iAsset in range(len(self.availableMeshes)):
                if (self.availableMeshes[iAsset] == selectedItem.text()):
                    if(not (iAsset in self.selectedMeshesIndices)):
                        self.selectedMeshesIndices.append(iAsset)
                        break
        self.updateUI()

    # ------------------------------------------------------------------
    def on_removeFromSelectionButton_clicked(self):
        for selectedItem in self.selectionListWidget.selectedItems():
            for iAsset in range(len(self.availableMeshes)):
                if (self.availableMeshes[iAsset] == selectedItem.text()):
                    if(iAsset in self.selectedMeshesIndices):
                        self.selectedMeshesIndices.remove(iAsset)
                    break
        self.updateUI()

    # ------------------------------------------------------------------
    def onSearchLineEditChanged(self, value=None):
        widgetEdited = self.sender()  # QLineEdit, QTextEdit
        tableWidget = widgetEdited.parent().parent()  # QDialog
        for childIndex in range(len(tableWidget.children())):
            if(type(tableWidget.children()[childIndex]) == type(QtWidgets.QListWidget())):
                self.updateAssetsListFromSearch(tableWidget.children()[childIndex], value)

    # ------------------------------------------------------------------
    def updateAssetsListFromSearch(self, listWidget, searchValue):
        for iItem in range(listWidget.count()):
            listWidget.item(iItem).setHidden(searchValue is not None and (listWidget.item(iItem).text().lower().find(searchValue.lower()) == -1))

