# -*- coding: utf-8 -*-

# Copyright 2009 Manik Bhattacharjee (manik-listes at altern.org)
#
# This file is part of PyVote.
#
# PyVote is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyVote is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyVote.  If not, see <http://www.gnu.org/licenses/>.



import sys, PyQt4
from PyQt4 import QtGui, QtCore
from CreerScrutinUI import Ui_mainDialog


class CreerScrutinWindow(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)

        # Configure l'interface utilisateur à partir du fichier généré par Qt4 Designer
        self.ui = Ui_mainDialog()
        self.ui.setupUi(self)
        print "INIT"
        self.changeTypeScrutin("")

        # Connecte les boutons aux fonctions associées.
        self.connect(self.ui.addElecteurBouton, QtCore.SIGNAL("clicked()"),self.addElecteur)
        self.connect(self.ui.addCandidatBouton, QtCore.SIGNAL("clicked()"),self.addCandidat)
        self.connect(self.ui.supprimeElecteurBouton, QtCore.SIGNAL("clicked()"),self.supprimeElecteur)
        self.connect(self.ui.supprimeCandidatBouton, QtCore.SIGNAL("clicked()"),self.supprimeCandidat)
        self.connect(self.ui.chargerScrutinBouton, QtCore.SIGNAL("clicked()"), self.chargerScrutin)
        self.connect(self.ui.sauverScrutinBouton, QtCore.SIGNAL("clicked()"), self.sauverScrutin)
        # Changement du type de scrutin
        self.connect(self.ui.typeScrutinCombo, QtCore.SIGNAL("currentIndexChanged(QString)"), self.changeTypeScrutin)

        # Met la date courante en début et fin de scrutin
        self.ui.dateDebut.setDateTime(QtCore.QDateTime.currentDateTime ())
        self.ui.dateFin.setDateTime(QtCore.QDateTime.currentDateTime ())


    # Quand l'utilisateur ferme la fenetre, demander une confirmation
    def closeEvent(self, event):
        reply = QtGui.QMessageBox.question(self, 'Message',u"Voulez-vous vraiment quitter ?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    # Fonction appelée pour ajouter un électeur
    def addElecteur(self):
        if self.ui.electeurEdit.text() == "":
                return
        self.ui.electeurList.addItem(self.ui.electeurEdit.text())
        self.ui.electeurEdit.setText("")

    #Fonction appelée pour ajouter un candidat
    def addCandidat(self):
        if self.ui.candidatEdit.text() == "": # Pas de nouveau nom dans la case -> on ignore
                return
        self.ui.candidatList.addItem(self.ui.candidatEdit.text())
        self.ui.candidatEdit.setText("")

    # Supprime l'électeur sélectionné dans la liste
    def supprimeElecteur(self):
        electeur = self.ui.electeurList.takeItem(self.ui.electeurList.currentRow())
        electeur = None

    # Supprime le candidat sélectionné dans la liste
    def supprimeCandidat(self):
        candidat = self.ui.candidatList.takeItem(self.ui.candidatList.currentRow())
        candidat = None


    # Renvoie une table de hachage contenant les parametres du scrutin
    def getScrutinHash( self, typeScrutin ):
            scrHash = {}
            if typeScrutin == "Vote unique":
                scrHash["Sieges a pourvoir"] = self.ui.aPourvoirSpin.value()

            elif typeScrutin == "Vote unique transferable":
                scrHash["Sieges a pourvoir"] = self.ui.aPourvoirSpin.value()

            elif typeScrutin == "Vote par assentiment":
                scrHash["Sieges a pourvoir"] = self.ui.aPourvoirSpin.value()
                scrHash["Methode de calcul"] = unicode(self.ui.methodeCalculCombo.currentText())
                scrHash["Notes entieres"] = (self.ui.entierCheck.checkState() == QtCore.Qt.Checked)
                scrHash["Note minimale"] = self.ui.noteMinSpin.value()
                scrHash["Note maximale"] = self.ui.noteMaxSpin.value()
                scrHash["Note par defaut"] = self.ui.noteDefautSpin.value()

            else:
                    self.erreur(u"Type de scrutin inconnu : impossible de sauver ses paramètres !")
            return scrHash


    # Remplit les paramètres du scrutin dans l'interface à partir d'une table de hachage
    def setScrutinHash( self, h, typeScrutin):
            if typeScrutin == "Vote unique":
                self.ui.aPourvoirSpin.setValue(h["Sieges a pourvoir"])

            elif typeScrutin == "Vote unique transferable":
                self.ui.aPourvoirSpin.setValue(h["Sieges a pourvoir"])

            elif typeScrutin == "Vote par assentiment":
                self.ui.aPourvoirSpin.setValue(h["Sieges a pourvoir"])
                i = self.ui.methodeCalculCombo.findText(h["Methode de calcul"])
                if i == -1:
                        self.erreur (u"Methode de calcul inconnue"+h["Methode de calcul"])
                else:
                        self.ui.methodeCalculCombo.setCurrentIndex(i)

                if h["Notes entieres"] == True:
                        self.ui.entierCheck.setCheckState(QtCore.Qt.Checked)
                else:
                        self.ui.entierCheck.setCheckState(QtCore.Qt.Unchecked)

                self.ui.noteMinSpin.setValue(h["Note minimale"])
                self.ui.noteMaxSpin.setValue(h["Note maximale"])
                self.ui.noteDefautSpin.setValue(h["Note par defaut"])

            else:
                self.erreur ( u"Type de scrutin inconnu, impossible de charger ses paramètres !" )


    # Pour faire plus propre, utiliser Pickle : la on a une solution rapide qui marche
    #
    # Le fichier contient ligne par ligne :
    # SCRUTIN FILE version 1.0
    # NomScrutin
    # Date debut
    # Date fin
    # TypeScrutin
    # DonneesDuTypeDeScrutin
    # ListeElecteurs
    # ListeCandidats
    # Description detaillee au format HTML en une seule ligne
    # SCRUTIN FILE version 1.0

    # Lecture d'un fichier Scrutin
    def chargerScrutin(self):
        filename = QtGui.QFileDialog.getOpenFileName ( self, "Charger un scrutin existant...", "", "Scrutin (*.scrutin)")
        # Si l'utilisateur a annulé
        if filename is None or filename == "":
                return
        #Ouverture du fichier
        f = open(filename, 'r')
        #On vérifie que la première ligne est la bonne
        if eval(f.readline()) != "SCRUTIN FILE version 1.0":
                self.erreur (u"Fichier invalide : l'en tête est incorrect !")
                return
        # Intitulé du scrutin
        self.ui.intituleEdit.setText(eval(f.readline()))

        # Date de début
        dt = eval(f.readline().replace ( "\n", "" ))
        self.ui.dateDebut.setDateTime(QtCore.QDateTime.fromString(dt, QtCore.Qt.ISODate))

        #Date de fin
        dt = eval(f.readline().replace ( "\n", "" ))
        self.ui.dateFin.setDateTime(QtCore.QDateTime.fromString(dt, QtCore.Qt.ISODate))

        # type de scrutin
        typeS = eval(f.readline()).replace ( "\n", "" )
        i = self.ui.typeScrutinCombo.findText(typeS)
        if i == -1:
                self.erreur (u"Impossible de retrouver le type de scrutin '"+unicode(typeS)+"'")
        else:
                self.ui.typeScrutinCombo.setCurrentIndex(i)
        # Données spécifiques du scrutin
        self.setScrutinHash(eval(f.readline()), typeS)

        # Mettre à jour l'affichage
        self.changeTypeScrutin("")

        # Liste des électeurs
        self.ui.electeurList.clear()
        for t in eval(f.readline()):
                elec = t.replace ( "\n", "" )
                self.ui.electeurList.addItem(elec)

        # Liste des candidats
        self.ui.candidatList.clear()
        for t in eval(f.readline()):
                cand = t.replace ( "\n", "" )
                self.ui.candidatList.addItem(cand)

        # Description détaillée
        self.ui.scrutinDescriptionText.setHtml(eval(f.readline()))

        # Dernière vérification
        if eval(f.readline()) != "SCRUTIN FILE version 1.0":
                 self.erreur (u"Fichier invalide : la dernière ligne est incorrecte !")
                 return
        f.close()

    # Ecriture d'un fichier Scrutin
    def sauverScrutin(self):
        filename = QtGui.QFileDialog.getSaveFileName ( self, u"Enregistrer le scrutin", "", "Scrutin (*.scrutin)")
        if filename is None or filename == "": # L'utilisateur a annulé -> on sort
                return
        # Création et ouverture du fichier
        f = open(filename, 'w')

        # En-tête
        f.write(repr("SCRUTIN FILE version 1.0")+"\n")

        # Nom du scrutin
        f.write(repr(unicode(self.ui.intituleEdit.text()))+"\n")

        # Date de début
        f.write(repr(str(self.ui.dateDebut.dateTime().toString(QtCore.Qt.ISODate)))+"\n")
        # Date de fin
        f.write(repr(str(self.ui.dateFin.dateTime().toString(QtCore.Qt.ISODate)))+"\n")

        # Type de scrutin
        f.write(repr(str(self.ui.typeScrutinCombo.currentText()))+"\n")
        # Paramètres du scrutin
        f.write(repr(self.getScrutinHash(str(self.ui.typeScrutinCombo.currentText())))+"\n")

        # Liste des électeurs
        items = [unicode(self.ui.electeurList.item(index).text()) for index in xrange(self.ui.electeurList.count())]
        f.write(repr(items)+"\n")

        # Liste des candidats
        items = [unicode(self.ui.candidatList.item(index).text()) for index in xrange(self.ui.candidatList.count())]
        f.write(repr(items)+"\n")

        # Description détaillée
        s = repr(unicode(self.ui.scrutinDescriptionText.toHtml()))
        f.write(s.replace ( "\n", " " ) + "\n")

        # Fin du fichier
        f.write(repr("SCRUTIN FILE version 1.0") + "\n")
        f.close()

    # Met à jour l'affichage des paramètres du scrutin en fonction du type de scrutin
    def changeTypeScrutin(self, texte):
        print "Type de scrutin changé"
        typeScrutin = self.ui.typeScrutinCombo.currentText()
        if typeScrutin == "Vote unique":
           self.ui.label_noteMin.setVisible(False)
           self.ui.label_noteMax.setVisible(False)
           self.ui.label_noteDefaut.setVisible(False)
           self.ui.entierCheck.setVisible(False)
           self.ui.methodeCalculCombo.setVisible(False)
           self.ui.noteMinSpin.setVisible(False)
           self.ui.noteMaxSpin.setVisible(False)
           self.ui.noteDefautSpin.setVisible(False)

        elif typeScrutin == "Vote unique transferable":
           self.ui.label_noteMin.setVisible(False)
           self.ui.label_noteMax.setVisible(False)
           self.ui.label_noteDefaut.setVisible(False)
           self.ui.entierCheck.setVisible(False)
           self.ui.methodeCalculCombo.setVisible(False)
           self.ui.noteMinSpin.setVisible(False)
           self.ui.noteMaxSpin.setVisible(False)
           self.ui.noteDefautSpin.setVisible(False)

        elif typeScrutin == "Vote par assentiment":
           self.ui.label_noteMin.setVisible(True)
           self.ui.label_noteMax.setVisible(True)
           self.ui.label_noteDefaut.setVisible(True)
           self.ui.entierCheck.setVisible(True)
           self.ui.methodeCalculCombo.setVisible(True)
           self.ui.noteMinSpin.setVisible(True)
           self.ui.noteMaxSpin.setVisible(True)
           self.ui.noteDefautSpin.setVisible(True)

        else:
           self.erreur(u"Type de vote inconnu !"+unicode(typeScrutin))

    # Fonction pour afficher une erreur
    def erreur( self, message ):
        QtGui.QMessageBox.warning(self, "Scrutin", message)


if __name__ == "__main__":
   app = QtGui.QApplication(sys.argv)
   window = CreerScrutinWindow()

   window.show()
   sys.exit(app.exec_())