from PySide2 import QtCore, QtGui, QtWidgets
import maya.api.OpenMaya as om2
import errno
import maya.OpenMayaUI as omui
import os
import shutil
import sys
from . import const

if sys.version_info > (3,):
    long = int


class MessageBoxQt(object):
    @classmethod
    def showQuestion(cls, parent, windowName, message, buttonA="Continue", buttonB="Cancel", buttonC=None,
                     icon="Question"):
        """Simple function for a dialog window with two or three buttons with changeable button names.

        buttonC=None will not show the third button.

        Icons are "NoIcon", "Warning", "Question", "Information" or "Critical"

        Returns strings "A", "B" or "C" depending on the button pressed.

        :param parent: The parent widget, can leave as None and will parent to Maya
        :type parent: object
        :param windowName: The name title of the window
        :type windowName: str
        :param message: The message/question as presented to the user inside the window
        :type message: str
        :param buttonA: The string name of the first button
        :type buttonA: str
        :param buttonB: The string name of the second button
        :type buttonB: str
        :param buttonC: The string name of the third (optional) button, if None is ignored
        :type buttonC: str

        :return buttonPressed: The button pressed, either "A", "B" or "C"
        :rtype buttonPressed: str
        """
        box = QtWidgets.QMessageBox(parent=parent)
        if icon == "Warning":
            box.setIcon(QtWidgets.QMessageBox.Warning)
        elif icon == "Question":
            box.setIcon(QtWidgets.QMessageBox.Question)
        elif icon == "Information":
            box.setIcon(QtWidgets.QMessageBox.Information)
        elif icon == "Critical":
            box.setIcon(QtWidgets.QMessageBox.Critical)
        elif icon == "NoIcon":
            box.setIcon(QtWidgets.QMessageBox.NoIcon)
        box.setWindowTitle(windowName)
        box.setText(message)
        buttonA_pressed = box.addButton(buttonA, QtWidgets.QMessageBox.YesRole)
        buttonB_pressed = box.addButton(buttonB, QtWidgets.QMessageBox.NoRole)
        if buttonC:
            buttonC_pressed = box.addButton(buttonC, QtWidgets.QMessageBox.NoRole)
        else:
            buttonC_pressed = None
        box.exec_()
        if box.clickedButton() == buttonA_pressed:
            return "A"
        elif box.clickedButton() == buttonB_pressed:
            return "B"
        elif box.clickedButton() == buttonC_pressed:
            return "C"
        else:
            return None

def mayaMainWindow():
    from shiboken2 import wrapInstance as wrapinstance
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapinstance(long(main_window_ptr), QtWidgets.QWidget)

def errorPopup(errorMessage):
    """Handle when an error occurs

    Show the error in an error message window.
    """
    flags = QtWidgets.QMessageBox.StandardButton.Ok
    QtWidgets.QMessageBox.warning(mayaMainWindow(), "Error!", errorMessage, flags)


def successPopup(message):
    """Message when successful
    """
    QtWidgets.QMessageBox.information(mayaMainWindow(), "Information", message)


def parentDir(path, num=1):
    """ Get the parent directory

    :param path: str
    :param num: Number of times it should iterate through the parents
    :return:
    """
    for p in range(num):
        path = os.path.dirname(path)
    return path

def saveFileTxt(formattedText, newfile):
    """Saves a string to a file

    :param formattedText: the text
    :type formattedText: str
    :param newfile: the file to be saved full path
    :type newfile: str
    """
    with open(newfile, "w") as fileInstance:
        fileInstance.write(formattedText)


def makeDirectory(directory):
    """Creates a new directory with error checking

    :param directory: a full path to a directory to create
    :type directory:

    :return directoryExists: True if the directory was created or it exists. False if wasn't created
    :rtype directoryExists: bool
    """
    try:
        if os.path.isdir(directory):
            return True  # already exists
        os.mkdir(directory)
        return True
    except OSError:
        message = "The directory could not be created: {} \n\n{}".format(directory, const.DID_NOT_INSTALL)
        om2.MGlobal.displayError(message)
        errorPopup(message)
        return False


def copyDirectory(src, dst, ignorePattern=None):
    """Copies the directory tree using shutil.copytree

    :param src: the Source directory to copy.
    :type src: str
    :param dst: the destination directory.
    :type dst: str

    :return directoryExists: True if the directory was copied. False if wasn't created
    :rtype directoryExists: bool
    """
    try:
        if ignorePattern:
            shutil.copytree(src, dst, ignore=shutil.ignore_patterns(*ignorePattern))
            return True
        shutil.copytree(src, dst)

    except OSError as exc:
        if exc.errno == errno.ENOTDIR:
            shutil.copy(src, dst)
        else:
            message = "Failed to copy directory {} to destination: {}\n\n{}".format(src, dst, const.DID_NOT_INSTALL)
            om2.MGlobal.displayError(message)
            errorPopup(message)
            return False
    return True