__all__ = ("compileUi", "loadUiType", "loadUi")

import time

from PyQt4.QtCore import PYQT_VERSION_STR
from PyQt4.uic.Compiler import indenter, compiler


_header = """# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '%s'
#
# Created: %s
#      by: PyQt4 UI code generator %s
#
# WARNING! All changes made in this file will be lost!

"""


_pyqt3_wrapper_code = """
class %(widgetname)s(QtGui.%(baseclass)s, %(uiclass)s):
\tdef __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
\t\tQtGui.%(baseclass)s.__init__(self, parent, f)

\t\tself.setupUi(self)
"""


_display_code = """
if __name__ == "__main__":
\timport sys
\tapp = QtGui.QApplication(sys.argv)
\t%(widgetname)s = QtGui.%(baseclass)s()
\tui = %(uiclass)s()
\tui.setupUi(%(widgetname)s)
\t%(widgetname)s.show()
\tsys.exit(app.exec_())
"""


def compileUi(uifile, pyfile, execute=False, indent=4, pyqt3_wrapper=False):
    """compileUi(uifile, pyfile, execute=False, indent=4, pyqt3_wrapper=False)

    Creates a Python module from a Qt Designer .ui file.
    
    uifile is a file name or file-like object containing the .ui file.
    pyfile is the file-like object to which the Python code will be written to.
    execute is optionally set to generate extra Python code that allows the
    code to be run as a standalone application.  The default is False.
    indent is the optional indentation width using spaces.  If it is 0 then a
    tab is used.  The default is 4.
    pyqt3_wrapper is optionally set to generate extra code that allows the code
    to be used as it would be with PyQt v3.
    """
    try:
        uifname = uifile.name
    except AttributeError:
        uifname = uifile

    indenter.indentwidth = indent

    pyfile.write(_header % (uifname, time.ctime(), PYQT_VERSION_STR))

    winfo = compiler.UICompiler().compileUi(uifile, pyfile)

    if pyqt3_wrapper:
        indenter.write_code(_pyqt3_wrapper_code % winfo)

    if execute:
        indenter.write_code(_display_code % winfo)


def loadUiType(uifile):
    """loadUiType(uifile) -> (form class, base class)

    Load a Qt Designer .ui file and return the generated form class and the Qt
    base class.

    uifile is a file name or file-like object containing the .ui file.
    """
    import sys

    from PyQt4 import QtGui

    if sys.hexversion >= 0x03000000:
        from PyQt4.uic.port_v3.string_io import StringIO
    else:
        from PyQt4.uic.port_v2.string_io import StringIO

    code_string = StringIO()
    winfo = compiler.UICompiler().compileUi(uifile, code_string)

    ui_globals = {}
    exec(code_string.getvalue(), ui_globals)

    return (ui_globals[winfo["uiclass"]], getattr(QtGui, winfo["baseclass"]))


def loadUi(uifile, baseinstance=None):
    """loadUi(uifile, baseinstance=None) -> widget

    Load a Qt Designer .ui file and return an instance of the user interface.

    uifile is a file name or file-like object containing the .ui file.
    baseinstance is an optional instance of the Qt base class.  If specified
    then the user interface is created in it.  Otherwise a new instance of the
    base class is automatically created.
    """
    from PyQt4.uic.Loader.loader import DynamicUILoader

    return DynamicUILoader().loadUi(uifile, baseinstance)
