"""


:author: Mathieu Gendron
:contact: 
:email: mgendron@theobjects.com
:organization: Object Research Systems (ORS), Inc.
:address: 
:copyright: 
:date: Mar 27 2019 09:20
:dragonflyVersion: 4.0.0.557
:UUID: 20752218509311e9a5de448a5b5d70c0
"""

__version__ = '1.0.0'

from PyQt5.QtWidgets import QFileDialog

from ORSModel import VisualRuler
from OrsLibraries.workingcontext import WorkingContext
from OrsLibraries.preferences import Preferences
from ORSServiceClass.menuItems.contextualMenuItem import ContextualMenuItem
from ORSServiceClass.actionAndMenu.menu import Menu
from ORSServiceClass.decorators.infrastructure import interfaceMethod
from OrsHelpers.ListHelper import ListHelper
from OrsHelpers.formatHelper import FormatHelper
from ORSServiceClass.ORSWidget.orsfiledialog import OrsFileDialog


class DemoMenuItemSaveRulerPropertiesToCSV_20752218509311e9a5de448a5b5d70c0(ContextualMenuItem):

    @classmethod
    def getIsSelectionValid(cls, aCollectionOfObjects):
        """
        :param aCollectionOfObjects: a list of objects currently being selected, i.e. on which the menu item could be applied.
        :return: if True, the menu item will be displayed.
        """
        
        if aCollectionOfObjects is None or len(aCollectionOfObjects) == 0:
            return False

        selectionIsOnlyRulers = all([isinstance(obj, VisualRuler)
                                     for obj in aCollectionOfObjects])
        return selectionIsOnlyRulers

    @classmethod
    def getMenuItemForSelection(cls, aCollectionOfObjects):
        """
        Returns the menu item
        :param aCollectionOfObjects: a list of objects currently being selected, i.e. on which the menu item will be applied.
        :return: Menu
        """
        
        collectionString = ListHelper.asPythonCollectionString(aCollectionOfObjects)
        myMenu = Menu(title='Save Properties to CSV...',
                      id_='DemoMenuItemSaveRulerPropertiesToCSV_20752218509311e9a5de448a5b5d70c0',
                      section='',
                      action='DemoMenuItemSaveRulerPropertiesToCSV_20752218509311e9a5de448a5b5d70c0.menuItemEntryPoint({collection})'.format(collection=str(collectionString)))
        return myMenu

    @classmethod
    def menuItemEntryPoint(cls, collectionString):
        """
        Will be executed when the menu item is selected.
        :param collectionString: a list of objects representation currently being selected, i.e. on which the menu item will be applied.
        """
        
        # aCollectionOfObjects is a Python list of objects currently being selected
        aCollectionOfObjects = ListHelper.fromPythonCollection(collectionString, asPythonList=True)

        selectedFilename, filter_ = OrsFileDialog.getSaveFileName(caption='Select a file to export in CSV')

        if selectedFilename == '':
            # The user cancelled the operation
            return

        cls.exportRulerPropertiesToCSV(aCollectionOfObjects, selectedFilename)

    @classmethod
    @interfaceMethod
    def exportRulerPropertiesToCSV(cls, listOfRulers, filename):
        """
        Exports ruler information in a CSV file

        :param listOfRulers: rulers to put in the CSV file
        :type listOfRulers: ORSModel.ors.VisualRuler
        :count listOfRulers: [1, None]
        :param filename: CSV file name
        :type filename: file saving
        """

        # Opening the file
        try:
            fio = open(filename, 'w', encoding='utf-16')
        except Exception as exc:
            return

        # Getting the CSV delimiter
        delimiter = Preferences.getCSVDelimiter()

        # Column headers
        defaultLengthUnit = Preferences.getDefaultLengthUnit()
        lengthUnitAbbreviation = 'm'
        if defaultLengthUnit is not None:
            lengthUnitAbbreviation = defaultLengthUnit.getUnitAbbreviation()

        lengthWithUnit = f'Length ({lengthUnitAbbreviation})'
        columnNames = ['Title', lengthWithUnit]
        cls._writeLineInCSVFile(fio, columnNames, delimiter)

        # Values
        currentView = WorkingContext.getCurrentView(None)
        timestep = 0
        if currentView is not None:
            timestep = currentView.getCurrentTimeStep()

        for aRuler in listOfRulers:
            if aRuler is not None:
                aRulerTitle = aRuler.getTitle()
                aRulerLength = aRuler.getLength(timestep, None)
                if defaultLengthUnit is not None:
                    aRulerLengthInUnit = defaultLengthUnit.getReferenceUnitConvertedToUnit(aRulerLength)
                else:
                    aRulerLengthInUnit = aRulerLength

                aRulerLengthInUnitStr = FormatHelper.formatNumber(aRulerLengthInUnit)

                listOfStr = [aRulerTitle, aRulerLengthInUnitStr]
                cls._writeLineInCSVFile(fio, listOfStr, delimiter)

        # Close the file
        fio.close()

    @classmethod
    def _writeLineInCSVFile(cls, fio, listOfStr, delimiter='\t'):
        strToWrite = delimiter.join(listOfStr) + '\n'
        fio.write(strToWrite)
