##
## interfaces.py
## Login : <uli@pu.smp.net>
## Started on  Sun Jun 27 11:06:23 2010 Uli Fouquet
## $Id$
## 
## Copyright (C) 2010 Uli Fouquet
## 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
##
"""Interfaces for JAMB data tables and related components.
"""
from waeup.sirp.interfaces import IWAeUPObject
from zc.sourcefactory.basic import BasicSourceFactory
from zope.interface import Interface
from zope import schema

class GenderSource(BasicSourceFactory):
    """A gender source delivers basically a mapping
       ``{'m': 'male', 'f': 'female'}``

       Using a source, we make sure that the tokens (which are
       stored/expected for instance from CSV files) are something one
       can expect and not cryptic IntIDs.
    """
    def getValues(self):
        return ['m', 'f']

    def getToken(self, value):
        return value[0].lower()
        
    def getTitle(self, value):
        if value == 'm':
            return 'male'
        if value == 'f':
            return 'female'

class IJAMBDataTable(IWAeUPObject):
    """A table containing JAMB data.
    """
    import_datetime = schema.Datetime(
        title = u'Datetime of import of contained data.',
        required = False,
        )

    importer_username = schema.TextLine(
        title = u'Name of user who initiated import.',
        required = False,
        )

    def __iter__():
        """An iterator over all data elements.
        """

    def keys():
        """Get iterator over all registration numbers of data.
        """

    def items():
        """Get iterator over tuples of registration numbers and datasets.
        """

    def clear():
        """Clear all data contained.

        This will also erase any import data.
        """

    def importFromCSV(filepath, username=None):
        """Import data from filepath.

        `filepath` - the path to the CSV file to import data from.

        `username` - the (optional) username of the importing person.
        """
        
class IResultEntry(IWAeUPObject):
    subject = schema.TextLine(
        title = u'Subject',
        description = u'The subject',
        required=False,
        )
    score = schema.TextLine(
        title = u'Score',
        description = u'The score',
        required=False,
        )

class IApplicantBaseData(IWAeUPObject):
    """The data for an applicant.

    This is a base interface with no field (except ``reg_no``)
    required. For use with importers, forms, etc., please use one of
    the derived interfaces below, which set more fields to required
    state, depending on use-case.
    """
    reg_no = schema.TextLine(
        title = u'JAMB Registration Number',
        )
    access_code = schema.TextLine(
        title = u'Access Code',
        required = False,
        )
    serial = schema.TextLine(
        title = u'Serial Number',
        required = False,
        )
    course1 = schema.TextLine(
        title = u'1st Choice Course of Study',
        required = False,
        )
    course2 = schema.TextLine(
        title = u'2nd Choice Course of Study',
        required = False,
        )
    course3 = schema.TextLine(
        title = u'3rd Choice Course of Study',
        required = False,
        )
    firstname = schema.TextLine(
        title = u'First Name',
        required = False,
        )
    middlenames = schema.TextLine(
        title = u'Middle Names',
        required = False,
        )
    lastname = schema.TextLine(
        title = u'Surname/Full Name',
        required = False,
        )
    jamb_age = schema.Int(
        title = u'Age (provided by JAMB)',
        required = False,
        )
    date_of_birth = schema.Date(
        title = u'Date of Birth',
        required = False,
        )
    jamb_state = schema.TextLine(
        title = u'State (provided by JAMB)',
        required = False,
        )
    jamb_lga = schema.TextLine(
        title = u'LGA (provided by JAMB)',
        required = False,
        )
    lga = schema.TextLine(
        # XXX: should be choice
        title = u'State/LGA (confirmed by applicant)',
        required = False,
        )
    sex = schema.Choice(
        title = u'Sex',
        source = GenderSource(),
        default = u'm',
        required = False,
        )
    email = schema.TextLine(
        title = u'Email',
        required = False,
        )
    phone = schema.TextLine(
        title = u'Phone',
        required = False,
        )
    passport = schema.Bool(
        title = u'Passport Photograph',
        default = True,
        required = False,
        )
    aos = schema.TextLine(
        # XXX: should be choice
        title = u'Area of Specialisation',
        required = False,
        )
    subj1 = schema.TextLine(
        # XXX: should be choice
        title = u'1st Choice of Study',
        required = False,
        )
    subj2 = schema.TextLine(
        # XXX: should be choice
        title = u'2nd Choice of Study',
        required = False,
        )
    subj3 = schema.TextLine(
        # XXX: should be choice
        title = u'3rd Choice of Study',
        required = False,
        )
    #
    # Higher Educational Data
    #
    hq_matric_no = schema.TextLine(
        title = u'Former Matric Number',
        required = False,
        )
    hq_type = schema.TextLine(
        title = u'Higher Qualification',
        required = False,
        )
    hq_grade = schema.TextLine(
        title = u'Higher Qualification Grade',
        required = False,
        )
    hq_school = schema.TextLine(
        title = u'School Attended',
        required = False,
        )
    hq_session = schema.TextLine(
        title = u'Session Obtained',
        required = False,
        )
    hq_disc = schema.TextLine(
        title = u'Discipline',
        required = False,
        )
    #
    # First sitting data
    #
    fst_sit_fname = schema.TextLine(
        title = u'Full Name',
        required = False,
        )
    fst_sit_no = schema.TextLine(
        title = u'Exam Number',
        required = False,
        )
    fst_sit_date = schema.Date(
        title = u'Exam Date (dd/mm/yyyy)',
        required = False,
        )
    fst_sit_type = schema.TextLine(
        # XXX: Should be choice
        title = u'Exam Type',
        required = False,
        )
    fst_sit_results = schema.List(
        title = u'Results',
        required = False,
        value_type = schema.Object(
            title = u'Entries',
            schema = IResultEntry,
            required = False,
            )
        )
    scd_sit_fname = schema.TextLine(
        title = u'Full Name',
        required = False,
        )
    scd_sit_no = schema.TextLine(
        title = u'Exam Number',
        required = False,
        )
    scd_sit_date = schema.Date(
        title = u'Exam Date (dd/mm/yyyy)',
        required = False,
        )
    scd_sit_type = schema.TextLine(
        # XXX: Should be choice
        title = u'Exam Type',
        required = False,
        )
    scd_sit_results = schema.TextLine(
        # XXX: Should be nested list of choices
        title = u'Results',
        required = False,
        )
    #
    # JAMB scores
    #
    eng_score = schema.TextLine(
        title = u"'English' score",
        required = False,
        )
    subj1score = schema.TextLine(
        title = u'1st Choice of Study Score',
        required = False,
        )
    subj2score = schema.TextLine(
        title = u'2nd Choice of Study Score',
        required = False,
        )
    subj3score = schema.TextLine(
        title = u'3rd Choice of Study Score',
        required = False,
        )
    # XXX: Total score???
    
    #
    # Application Data
    #
    application_date = schema.Date(
        title = u'Application Date',
        required = False,
        )
    status = schema.TextLine(
        # XXX: should be 'status' type
        title = u'Application Status',
        required = False,
        )
    screening_date = schema.Date(
        title = u'Screening Date',
        required = False,
        )
    screening_type = schema.TextLine(
        # XXX: schould be choice
        title = u'Screening Type',
        required = False,
        )
    screening_score = schema.TextLine(
        title = u'Screening Score',
        required = False,
        )
    screening_venue = schema.TextLine(
        title = u'Screening Venue',
        required = False,
        )
    total_score = schema.TextLine(
        title = u'Total Score',
        required = False,
        )
    course_admitted = schema.TextLine(
        # XXX: should be choice
        title = u'Admitted Course of Study',
        required = False,
        )
    department = schema.TextLine(
        # XXX: if we have a course, dept. is not necessary
        title = u'Department',
        required = False,
        )
    faculty = schema.TextLine(
        # XXX: if we have a course, faculty is not necessary
        title = u'Faculty',
        required = False,
        )
    entry_session = schema.TextLine(
        # XXX: should be choice
        # XXX: should have sensible default: upcoming session
        title = u'Entry Session',
        required = False,
        )
    notice = schema.Text(
        title = u'Notice',
        required = False,
        )
    student_id = schema.TextLine(
        title = u'Student ID',
        required = False,
        )
    import_record_no = schema.TextLine(
        title = u'Import Record No.',
        required = False,
        )
    imported_by = schema.TextLine(
        title = u'Imported By',
        required = False,
        )
    import_date = schema.Datetime(
        title = u'Import Date',
        required = False,
        )
    import_from = schema.TextLine(
        title = u'Import Source',
        required = False,
        )

    
class IApplicant(IApplicantBaseData):
    """An applicant.

    This is basically the applicant base data. Here we repeat the
    fields from base data only with the `required` attribute of
    required attributes set to True (which is the default).
    """
    access_code = schema.TextLine(
        title = u'Access Code',
        )
    course1 = schema.TextLine(
        title = u'1st Choice Course of Study',
        )
    firstname = schema.TextLine(
        title = u'First Name',
        )
    middlenames = schema.TextLine(
        title = u'Middle Names',
        )
    lastname = schema.TextLine(
        title = u'Surname/Full Name',
        )
    date_of_birth = schema.Date(
        title = u'Date of Birth',
        )
    jamb_state = schema.TextLine(
        title = u'State (provided by JAMB)',
        )
    jamb_lga = schema.TextLine(
        title = u'LGA (provided by JAMB)',
        )
    lga = schema.TextLine(
        # XXX: should be choice
        title = u'State/LGA (confirmed by applicant)',
        )
    sex = schema.Choice(
        title = u'Sex',
        source = GenderSource(),
        default = u'm',
        )
    passport = schema.Bool(
        title = u'Passport Photograph',
        default = True,
        )
    #
    # Higher Educational Data
    #

    #
    # First sitting data
    #
    fst_sit_fname = schema.TextLine(
        title = u'Full Name',
        )

    #
    # Second sitting data
    #
    scd_sit_fname = schema.TextLine(
        title = u'Full Name',
        )
    #
    # JAMB scores
    #
    
    #
    # Application Data
    #
    application_date = schema.Date(
        title = u'Application Date',
        )
    status = schema.TextLine(
        # XXX: should be 'status' type
        title = u'Application Status',
        )
    screening_date = schema.Date(
        title = u'Screening Date',
        )
    screening_type = schema.TextLine(
        # XXX: schould be choice
        title = u'Screening Type',
        )
    screening_score = schema.TextLine(
        title = u'Screening Score',
        )
    entry_session = schema.TextLine(
        # XXX: should be choice
        # XXX: should have sensible default: upcoming session
        title = u'Entry Session',
        )
    import_record_no = schema.TextLine(
        title = u'Import Record No.',
        )
    imported_by = schema.TextLine(
        title = u'Imported By',
        )
    import_date = schema.Datetime(
        title = u'Import Date',
        )
    import_from = schema.TextLine(
        title = u'Import Source',
        )

class IApplicantPDEImportData(IApplicantBaseData):
    """Data for applicants, that passed PDE screening.

    This data set should be suitable for imports from JAMB tables. It
    is also basicall the basic applicant data from
    :class:`IApplicantBaseData` only with the required fields set.

    """
    firstname = schema.TextLine(
        title = u'First Name',
        required = True,
        )
    middlenames = schema.TextLine(
        title = u'Middle Names',
        required = True,
        )
    lastname = schema.TextLine(
        title = u'Surname/Full Name',
        required = True,
        )
    date_of_birth = schema.Date(
        title = u'Date of Birth',
        required = True,
        )
    jamb_state = schema.TextLine(
        title = u'State (provided by JAMB)',
        required = True,
        )
    jamb_lga = schema.TextLine(
        title = u'LGA (provided by JAMB)',
        required = True,
        )
    course1 = schema.TextLine(
        title = u'1st Choice Course of Study',
        required = True,
        )
    screening_date = schema.Date(
        title = u'Screening Date',
        required = True,
        )
    screening_type = schema.TextLine(
        # XXX: schould be choice
        title = u'Screening Type',
        required = True,
        )
    screening_venue = schema.TextLine(
        title = u'Screening Venue',
        required = True,
        )
    entry_session = schema.TextLine(
        # XXX: should be choice
        # XXX: should have sensible default: upcoming session
        title = u'Entry Session',
        required = True,
        )
    
class IApplicantContainer(IWAeUPObject):
    """A container for applicants.
    """
