from PyQt4.QtGui import *
from PyQt4.QtCore import *

from mainwindow import Ui_MainWindow
from loginform import Ui_loginForm
from TDBBrowserWidget import TDBBrowserWidget
import lechat_rc

from logging import warning, debug, critical
from lechat.ChangeSet import *
from ObjectClassWidget import ObjectClassWidget

from lechat.lechatConfig import *

from qtreactor import qt4reactor
qt4reactor.install()
from twisted.internet import reactor

class ApplicationWidget:
    def __init__(self, argv):
        self._app = QApplication.instance()

    def show(self):
        reactor.run()
        reactor.stop()
        reactor.runUntilCurrent()

class MainWidget(QMainWindow, Ui_MainWindow):

    def __init__(self, ui):

        self.ui = ui
        QMainWindow.__init__(self)

        # Set up the user interface from Designer.
        self.setupUi(self)

        self.userTabs = {}
        self.userList.setWidget(self.ui.browser_ui.widget)

        self.tabs = QTabWidget(self.centralwidget)
        self.centralWidgetLayout.addWidget(self.tabs)
        self.tabs.show()

        QObject.connect(self.actionReload, SIGNAL("triggered()"), self.reload)
        QObject.connect(self.actionQuitter, SIGNAL("triggered()"), self.quit)
        QObject.connect(self.actionCreateUser, SIGNAL("triggered()"), self.createUser)
        #QObject.connect(self.actionCreateDomain, SIGNAL("triggered()"), self.createDomain)
        #QObject.connect(self.actionCreateHost, SIGNAL("triggered()"), self.createHost)
        QObject.connect(self.actionLoadChangeSet, SIGNAL("triggered()"), self.loadChangeSet)
        QObject.connect(self.actionSaveChangeSet, SIGNAL("triggered()"), self.saveChangeSet)
        #QObject.connect(self.actionDisconnect, SIGNAL("triggered()"), self.dbDisconnect)

    def createUser(self):
        self.ui.createEntry('/people')

    def createDomain(self):
        self.ui.createEntry('/domains')

    def createHost(self):
        self.ui.createEntry('/hosts')

    def loadChangeSet(self):
        filename = QFileDialog.getOpenFileName(self, "Load changeset", QDir.homePath())
        self.ui.changeset.loadFromString( file(filename).read() )
        self.ui.changeset_changed.raiseEvent()
        
    def saveChangeSet(self):
        filename = QFileDialog.getSaveFileName(self, "Save changeset", QDir.homePath())
        fd = open(filename, 'w')
        fd.write( repr(self.ui.changeset))
        fd.close()

    def dbDisconnect(self):
        self.ui.db_disconnected.raiseEvent()
        
    def applyChanges(self, checked):
        "Apply changes on server"
        self.statusbar.showMessage("Application des modifications...")
        subprocess.call( ['echo', 'ssh', 'root@arml.praksys.net', '/usr/bin/env',
                          'python', '/root/migrationtools/createuser.py'] )
        self.statusbar.clearMessage()
        
    def reload(self):
        self.ui.db_changed.raiseEvent()

    def exit_(self):
        print 'exiting...'
        reactor.stop()
        
    def quit(self):
        self.close()

class LoginFormWidget(QDialog, Ui_loginForm):

    def __init__(self, ui):

        self.ui = ui
        
        QDialog.__init__(self)

        self.setupUi(self)

        defaults = {'server': 'http://localhost:7080/',
                    'base_dn': 'dc=abadcafe',
                    'login': 'admin',
                    'password': 'secret'}

        QObject.connect(self.loginOkButton, SIGNAL("clicked()"), self.loginOkButtonClicked)
        
    def loginOkButtonClicked(self):
        self.ui.parent.validate_login.raiseEvent()

    def setData(self, values):
        """
        Sets widget data, given a dictionnary of values, keyed by field name.
        """
        for k, attr in values.items():
            if self.edit_fields.has_key(k):
                w = self.edit_fields[k]
                w.setText(attr)
            
    def getData(self):
        """
        Actualise ui's object values from widget.

        Returns a dictionnary of Attribute objects keyed by attribute name.
        """
        result = {}
        for k, w in self.edit_fields.items():
                value = w.text()
                if value:
                    result[k] = str(value)
        return result

class ChangeSetWidget(QWidget):
    def __init__(self, ui):
        QWidget.__init__(self)

        self.ui = ui
        
        self.setObjectName("changeSet")

        self.changeSetWidgetLayout = QVBoxLayout(self)
        self.changeSetWidgetLayout.setMargin(9)
        self.changeSetWidgetLayout.setSpacing(6)
        self.changeSetWidgetLayout.setObjectName("changeSetWidgetLayout")

        self.changeSetTreeWidget = QTreeWidget(self)

        self.changeSetTreeWidget.setAlternatingRowColors(True)
        self.changeSetTreeWidget.setSortingEnabled(True)
        self.changeSetTreeWidget.setColumnCount(3)
        self.changeSetTreeWidget.setObjectName("changeSetTreeWidget")
        self.changeSetTreeWidget.headerItem().setText(0,"Entry")
        self.changeSetTreeWidget.headerItem().setText(1,"Ancienne valeur")
        self.changeSetTreeWidget.headerItem().setText(2,"Nouvelle valeur")
        self.changeSetTreeWidget.headerItem().setText(3,"Annuler")
        self.changeSetWidgetLayout.addWidget(self.changeSetTreeWidget)

        hboxLayout = QHBoxLayout()
        hboxLayout.setMargin(0)
        hboxLayout.setSpacing(6)
        hboxLayout.setObjectName("hboxlayout")

        spacerItem = QSpacerItem(201,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        hboxLayout.addItem(spacerItem)
                
        self.commitButton = QPushButton(self)
        self.commitButton.setAutoDefault(True)
        self.commitButton.setObjectName("commitChangesButton")
        self.commitButton.setEnabled(False)
        hboxLayout.addWidget(self.commitButton)
        
        self.cancelButton = QPushButton(self)
        self.cancelButton.setAutoDefault(True)
        self.cancelButton.setObjectName("commitChangesButton")
        self.cancelButton.setEnabled(False)
        hboxLayout.addWidget(self.cancelButton)

        self.changeSetWidgetLayout.addLayout(hboxLayout)

        self.retranslateUi(self)

        QObject.connect(self.commitButton, SIGNAL("clicked()"), self.commitChanges)
        QObject.connect(self.cancelButton, SIGNAL("clicked()"), self.cancelChanges)
        QObject.connect(self.changeSetTreeWidget, SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"),
                        self.userDoubleClicked)

    def retranslateUi(self, changeSet):
        changeSet.setWindowTitle(QApplication.translate("changeSet", "Modifications",
                                                              None, QApplication.UnicodeUTF8))
        changeSet.commitButton.setText(QApplication.translate("changeSet", "Appliquer",
                                                                    None, QApplication.UnicodeUTF8))
        changeSet.cancelButton.setText(QApplication.translate("changeSet", "Tout annuler",
                                                                    None, QApplication.UnicodeUTF8))

    def commitChanges(self):
        self.ui.commit()
    
    def cancelChanges(self):
        self.ui.clear()
    
    def userDoubleClicked(self, item, i):
        if i == 0:
            while item.parent():
                item = item.parent()
            user = str( item.text(0) )
            self.ui.parent.editEntry(user)
        elif i == 3:
            if item.parent():
                attribute = str( item.text(0) )
                user = str ( item.parent().text(0) )
                self.ui.cancel( user, attribute )
            else:
                user = str ( item.text(0) )
                value = str ( item.text(1) )
                self.ui.cancel( user )
        
    def updateChangeSet(self):
        self.changeSetTreeWidget.clear()
        
        icon = QIcon(":/lechat/resources/stop.png")

        changes = self.ui.parent.changeset

        #debug("updated changeset : %s" % changes)

        if changes.isEmpty():
            #debug('no pending changes')
            self.cancelButton.setEnabled(False)
            self.commitButton.setEnabled(False)
        else:
            subitems = {}
            for dn in changes.changes.keys():
                for mod in changes.changes[dn]:
                    if not subitems.has_key(mod.path):
                        subitems[mod.path] = QTreeWidgetItem([QString( mod.path ), '', '', ''])
                        subitems[mod.path].setIcon(3, icon)
                        self.changeSetTreeWidget.addTopLevelItem(subitems[mod.path])
                    if mod.op == OP_DELETE:
                        item = QTreeWidgetItem( [ QString( mod.path ), '[Effacer]', '', '' ] )
                        item.setTextAlignment(1, Qt.AlignCenter)
                        subitems[mod.path].addChild(item)
                    elif mod.op == OP_RENAME:
                        item = QTreeWidgetItem( [ '[Renomer]',
                                                  QString.fromUtf8( mod.old ),
                                                  QString.fromUtf8( mod.new ) ] )
                        subitems[mod.path].addChild(item)
                    elif mod.op == OP_MODIFY:
                        for k, v in mod.new.items():
                            if mod.old.has_key(k):
                                _old = ', '.join( [str(o) for o in mod.old[k]] )
                            else:
                                _old = ''
                            _new = ', '.join( [str(n) for n in v] )
                            subitem = QTreeWidgetItem( [ QString( k ),
                                                         QString.fromUtf8(_old),
                                                         QString.fromUtf8(_new), ''] )
                            subitems[mod.path].addChild(subitem)
                    elif mod.op == OP_CREATE:
                        item = QTreeWidgetItem( [ '[Creation]',
                                                  '',
                                                  QString.fromUtf8( mod.new ), '' ] )
                        subitems[mod.path].addChild(item)

            self.changeSetTreeWidget.resizeColumnToContents(0)
            self.changeSetTreeWidget.resizeColumnToContents(1)
            self.changeSetTreeWidget.resizeColumnToContents(2)
            self.changeSetTreeWidget.resizeColumnToContents(3)

            self.cancelButton.setEnabled(True)
            self.commitButton.setEnabled(True)



