## $Id: interfaces.py 7688 2012-02-23 12:25:23Z henrik $
##
## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
## This program 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 2 of the License, or
## (at your option) any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
from datetime import datetime
from zope.component import getUtility
from zope.interface import Attribute, Interface
from zope import schema
from zc.sourcefactory.contextual import BasicContextualSourceFactory
from waeup.sirp.interfaces import (
    ISIRPObject, academic_sessions_vocab, validate_email, ISIRPUtils)
from waeup.sirp.schema import TextLineChoice
from waeup.sirp.university.vocabularies import CourseSource, StudyModeSource
from waeup.sirp.students.vocabularies import (
  CertificateSource, StudyLevelSource,
  contextual_reg_num_source, contextual_mat_num_source,
  GenderSource, nats_vocab,
  )
from waeup.sirp.payments.interfaces import IPaymentsContainer, IOnlinePayment

# VerdictSource can't be placed into the vocabularies module because it
# requires importing IStudentsUtils which then leads to circular imports.
class VerdictSource(BasicContextualSourceFactory):
    """A verdicts source delivers all verdicts provided
    in the portal.
    """
    def getValues(self, context):
        verdicts_dict = getUtility(IStudentsUtils).getVerdictsDict()
        return verdicts_dict.keys()

    def getToken(self, context, value):
        return value

    def getTitle(self, context, value):
        verdicts_dict = getUtility(IStudentsUtils).getVerdictsDict()
        return verdicts_dict[value]


class IStudentsUtils(Interface):
    """A collection of methods which are subject to customization.

    """
    def getPaymentDetails(category, student):
        """Get the payment dates of a student for the payment category
        specified.

        """

    def getAccommodation_details(student):
        """Determine the accommodation dates of a student.

        """

    def selectBed(available_beds):
        """Select a bed from a list of available beds.

        In the standard configuration we select the first bed found,
        but can also randomize the selection if we like.
        """

    def renderPDF(view, subject='', filename='slip.pdf',):
        """Render pdf slips for various pages.

        """

class IStudentsContainer(ISIRPObject):
    """A students container contains university students.

    """
    def addStudent(student):
        """Add an IStudent object and subcontainers.

        """

    def archive(id=None):
        """Create on-dist archive of students.

        If id is `None`, all students are archived.

        If id contains a single id string, only the respective
        students are archived.

        If id contains a list of id strings all of the respective
        students types are saved to disk.
        """

    def clear(id=None, archive=True):
        """Remove students of type given by 'id'.

        Optionally archive the students.

        If id is `None`, all students are archived.

        If id contains a single id string, only the respective
        students are archived.

        If id contains a list of id strings all of the respective
        student types are saved to disk.

        If `archive` is ``False`` none of the archive-handling is done
        and respective students are simply removed from the
        database.
        """

class IStudentNavigation(ISIRPObject):
    """Interface needed for student navigation.

    """
    def getStudent():
        """Return student object.

        """

class IStudentBase(ISIRPObject):
    """Representation of student base data.

    """
    history = Attribute('Object history, a list of messages')
    state = Attribute('Returns the registration state of a student')
    password = Attribute('Encrypted password of a student')
    certcode = Attribute('The certificate code of any chosen study course')
    depcode = Attribute('The department code of any chosen study course')
    faccode = Attribute('The faculty code of any chosen study course')
    current_session = Attribute('The current session of the student')
    current_mode = Attribute('The current mode of the student')
    fullname = Attribute('All name parts separated by hyphens')
    display_fullname = Attribute('The fullname of an applicant')

    def loggerInfo(ob_class, comment):
        """Adds an INFO message to the log file.

        """

    student_id = schema.TextLine(
        title = u'Student Id',
        required = False,
        )

    firstname = schema.TextLine(
        title = u'First Name',
        required = True,
        )

    middlename = schema.TextLine(
        title = u'Middle Name',
        required = False,
        )

    lastname = schema.TextLine(
        title = u'Last Name (Surname)',
        required = True,
        )

    sex = schema.Choice(
        title = u'Sex',
        source = GenderSource(),
        default = u'm',
        required = True,
        )

    reg_number = TextLineChoice(
        title = u'Registration Number',
        required = True,
        readonly = False,
        source = contextual_reg_num_source,
        )

    matric_number = TextLineChoice(
        title = u'Matriculation Number',
        #default = u'',
        required = False,
        readonly = False,
        source = contextual_mat_num_source,
        )

    adm_code = schema.TextLine(
        title = u'PWD Activation Code',
        default = u'',
        required = False,
        readonly = True,
        )

    email = schema.ASCIILine(
        title = u'Email',
        required = False,
        constraint=validate_email,
        )
    phone = schema.TextLine(
        title = u'Phone',
        description = u'',
        required = False,
        )

class IStudentClearance(ISIRPObject):
    """Representation of student clearance data.

    """
    date_of_birth = schema.Date(
        title = u'Date of Birth',
        required = True,
        )

    clearance_locked = schema.Bool(
        title = u'Clearance form locked',
        default = False,
        )

    clr_code = schema.TextLine(
        title = u'CLR Activation Code',
        default = u'',
        required = False,
        readonly = True,
        )

    nationality = schema.Choice(
        source = nats_vocab,
        title = u'Nationality',
        default = 'nigeria',
        required = True,
        )

class IStudentPersonal(ISIRPObject):
    """Representation of student personal data.

    """
    perm_address = schema.Text(
        title = u'Permanent Address',
        required = False,
        )

class IStudent(IStudentBase,IStudentClearance,IStudentPersonal):
    """Representation of a student.

    """

class IStudentUpdateByRegNo(IStudent):
    """Representation of a student. Skip regular reg_number validation.

    """
    reg_number = schema.TextLine(
        title = u'Registration Number',
        default = None,
        required = False,
        )

class IStudentUpdateByMatricNo(IStudent):
    """Representation of a student. Skip regular matric_number validation.

    """
    matric_number = schema.TextLine(
        title = u'Matriculation Number',
        default = None,
        required = False,
        )

class IStudentStudyCourse(ISIRPObject):
    """A container for student study levels.

    """
    certificate = schema.Choice(
        title = u'Certificate',
        source = CertificateSource(),
        default = None,
        required = False,
        )

    entry_mode = schema.Choice(
        title = u'Entry Mode',
        source = StudyModeSource(),
        default = u'ug_ft',
        required = True,
        readonly = False,
        )

    entry_session = schema.Choice(
        title = u'Entry Session',
        source = academic_sessions_vocab,
        #default = datetime.now().year,
        default = None,
        required = True,
        readonly = False,
        )

    current_session = schema.Choice(
        title = u'Current Session',
        source = academic_sessions_vocab,
        default = None,
        required = True,
        readonly = False,
        )

    current_level = schema.Choice(
        title = u'Current Level',
        source = StudyLevelSource(),
        default = None,
        required = False,
        readonly = False,
        )

    current_verdict = schema.Choice(
        title = u'Current Verdict',
        source = VerdictSource(),
        default = '0',
        required = False,
        )

    previous_verdict = schema.Choice(
        title = u'Previous Verdict',
        source = VerdictSource(),
        default = '0',
        required = False,
        )

class IStudentStudyLevel(ISIRPObject):
    """A container for course tickets.

    """
    level = Attribute('The level code')
    validation_date = Attribute('The date of validation')
    validated_by = Attribute('User Id of course adviser')

    level_session = schema.Choice(
        title = u'Session',
        source = academic_sessions_vocab,
        default = None,
        required = True,
        )

    level_verdict = schema.Choice(
        title = u'Verdict',
        source = VerdictSource(),
        default = '0',
        required = False,
        )

class ICourseTicket(ISIRPObject):
    """A course ticket.

    """
    code = Attribute('code of the original course')
    title = Attribute('title of the original course')
    credits = Attribute('credits of the original course')
    passmark = Attribute('passmark of the original course')
    semester = Attribute('semester of the original course')
    fcode = Attribute('faculty code of the original course')
    dcode = Attribute('department code of the original course')

    mandatory = schema.Bool(
        title = u'Mandatory',
        default = False,
        required = False,
        readonly = False,
        )

    score = schema.Int(
        title = u'Score',
        default = 0,
        required = False,
        readonly = False,
        )

    automatic = schema.Bool(
        title = u'Automatical Creation',
        default = False,
        required = False,
        readonly = True,
        )

    carry_over = schema.Bool(
        title = u'Carry-over Course',
        default = False,
        required = False,
        readonly = False,
        )

    def getLevel():
        """Returns the id of the level the ticket has been added to.
        """

    def getLevelSession():
        """Returns the session of the level the ticket has been added to.
        """

class ICourseTicketAdd(ICourseTicket):
    """An interface for adding course tickets.

    """
    course = schema.Choice(
        title = u'Course',
        source = CourseSource(),
        readonly = False,
        )

class IStudentAccommodation(ISIRPObject):
    """A container for student accommodation objects.

    """

class IBedTicket(ISIRPObject):
    """A ticket for accommodation booking.

    """
    bed = Attribute('The bed object.')

    bed_coordinates = schema.TextLine(
        title = u'Bed Coordinates',
        default = None,
        required = False,
        readonly = False,
        )

    bed_type = schema.TextLine(
        title = u'Bed Type',
        default = None,
        required = False,
        readonly = False,
        )

    booking_session = schema.Choice(
        title = u'Session',
        source = academic_sessions_vocab,
        default = None,
        required = True,
        readonly = True,
        )

    booking_date = schema.Datetime(
        title = u'Booking Date',
        required = False,
        readonly = True,
        )

    booking_code = schema.TextLine(
        title = u'Booking Activation Code',
        default = u'',
        required = False,
        readonly = True,
        )

    def getSessionString():
        """Returns the title of academic_sessions_vocab term.

        """

class IStudentPaymentsContainer(IPaymentsContainer):
    """A container for student payment objects.

    """

class IStudentOnlinePayment(IOnlinePayment):
    """A student payment via payment gateways.

    """
    p_session = schema.Choice(
        title = u'Payment Session',
        source = academic_sessions_vocab,
        required = False,
        )

IStudentOnlinePayment['p_session'].order = IStudentOnlinePayment[
    'p_item'].order

class IStudentChangePassword(ISIRPObject):
    """Interface needed for change pasword page.

    """

    reg_number = schema.TextLine(
        title = u'Registration Number',
        default = None,
        required = True,
        readonly = False,
        )

    email = schema.ASCIILine(
        title = u'Email Address',
        required = True,
        constraint=validate_email,
        )
