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

"""
quizz* related model.

Thème > id, titre, ponderation_faible, ponderation_moyenne, ponderation_forte
Question > id, id_theme, titre, niveau
Proposition > id, id_question, titre, valeur

test > id, id_theme, id_utilisateur, date
reponse > id, id_test, id_question, id_proposition, ponderation

Quizz
QCM avec cinq réponses (0 pour une mauvaise réponse, 1 pour une bonne réponse.
Trois niveaux de difficultés :
> facile = 1
> moyen = 2
> difficile = 3
Trois poids :
> Je suis sur de moi (10)
> Je pense que c'est çà (3)
> Je réponds par défaut (1)
Affichage du score et du score bonifié.
"""

from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Unicode, Integer, DateTime, Boolean
from sqlalchemy.orm import relation, synonym

from datetime import datetime

from quizz.model import DeclarativeBase, metadata, DBSession

__all__ = ['Quizz', 'Question', 'Proposition', 'Test', 'Reponse']





class Quizz(DeclarativeBase):
    """
    Quizz definition
    """

    __tablename__ = 'quizz_quizz'

    id = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(255), unique=True, nullable=False)
    weight1 = Column(Integer, default=1)
    weight2 = Column(Integer, default=3)
    weight3 = Column(Integer, default=10)
    created = Column(DateTime, default=datetime.now)
    updated = Column(DateTime, default=datetime.now)

    def __repr__(self):
        return ('<Quizz: name=%s>' % self.name).encode('utf-8')

    def __unicode__(self):
        return self.name

    def poids(self, indice):
        if indice == 3:
            return self.weight3
        elif indice == 2:
            return self.weight2
        return self.weight1

    @property
    def questions(self):
        """Return a set of questions related to this quizz."""
        return DBSession.query(Question).filter_by(id_quizz=self.id).all()


class Question(DeclarativeBase):
    """
    Question definition.
    """

    __tablename__ = 'quizz_question'

    id = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(255), unique=True, nullable=False)
    id_quizz = Column(Integer, ForeignKey('quizz_quizz.id'), nullable=False)
    quizz = relation('Quizz', foreign_keys=id_quizz)
    niveau = Column(Integer)

    def __repr__(self):
        return ('<Question: name=%s>' % self.name).encode('utf-8')

    def __unicode__(self):
        return self.name

    @property
    def propositions(self):
        """Return a set of propositions related to this question."""
        return DBSession.query(Proposition).filter_by(id_question=self.id).all()


class Proposition(DeclarativeBase):
    """
    Proposition definition
    """

    __tablename__ = 'quizz_proposition'

    id = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(255), unique=True, nullable=False)
    id_question = Column(Integer, ForeignKey('quizz_question.id'), nullable=False)
    question = relation('Question', foreign_keys=id_question)
    validite = Column(Boolean, default=True)

    def __repr__(self):
        return ('<Proposition: name=%s>' % self.name).encode('utf-8')

    def __unicode__(self):
        return self.name


class Test(DeclarativeBase):
    """
    Test definition
    """

    __tablename__ = 'quizz_test'

    id = Column(Integer, autoincrement=True, primary_key=True)
    id_quizz = Column(Integer, ForeignKey('quizz_quizz.id'), nullable=False)
    quizz = relation('Quizz', foreign_keys=id_quizz)
    id_utilisateur = Column(Integer, ForeignKey('tg_user.user_id'), nullable=False)
    utilisateur = relation('User', foreign_keys=id_utilisateur)
    date = Column(DateTime, default=datetime.now)

    @property
    def reponses(self):
        return DBSession.query(Reponse).filter_by(id_test=self.id).all()

    @property
    def note_standard(self):
        return sum([r.note_standard for r in self.reponses])

    @property
    def note_ponderee(self):
        return sum([r.note_ponderee for r in self.reponses])

    @property
    def note_ponderee_positive(self):
        return sum([r.note_ponderee_positive for r in self.reponses])

    @property
    def note_ponderee_negative(self):
        return sum([r.note_ponderee_negative for r in self.reponses])


class Reponse(DeclarativeBase):
    """
    Reponse definition
    """

    __tablename__ = 'quizz_reponse'

    id = Column(Integer, autoincrement=True, primary_key=True)
    id_test = Column(Integer, ForeignKey('quizz_test.id'), nullable=False)
    test = relation('Test', foreign_keys=id_test)
    id_question = Column(Integer, ForeignKey('quizz_question.id'), nullable=False)
    question = relation('Question', foreign_keys=id_question)
    id_proposition = Column(Integer, ForeignKey('quizz_proposition.id'), nullable=False)
    proposition = relation('Proposition', foreign_keys=id_proposition)
    weight = Column(Integer)

    def __repr__(self):
        return ('<Reponse: id=%s>' % self.id).encode('utf-8')

    def __unicode__(self):
        return self.name

    @property
    def ponderation(self):
        return self.question.quizz.poids(self.weight and self.weight or 1)

    @property
    def note_standard(self):
        return self.proposition.validite and 1 or 0

    @property
    def note_ponderee(self):
        return (self.proposition.validite and 1 or -1) * self.ponderation

    @property
    def note_ponderee_positive(self):
        return self.proposition.validite and self.ponderation or 0

    @property
    def note_ponderee_negative(self):
        return not self.proposition.validite and self.ponderation or 0

