Index: /waeup/branches/ulif-rewrite/src/waeup/university/certificate.py
===================================================================
--- /waeup/branches/ulif-rewrite/src/waeup/university/certificate.py	(revision 4561)
+++ /waeup/branches/ulif-rewrite/src/waeup/university/certificate.py	(revision 4562)
@@ -9,5 +9,6 @@
 from waeup.interfaces import (ICertificate, ICertificateContainer,
                               ICertificateCourse, ICourse, IDepartment)
-from waeup.viewlets import FormWrapMixin, Index, Manage, MainArea
+from waeup.viewlets import (FormWrapMixin, Index, Manage, MainArea,
+                            AddCertificateCourse)
 from waeup.utils.helpers import getName
 
@@ -52,6 +53,9 @@
         code = "%s_%s" % (course.code, level)
         self[code] = CertificateCourse(course, level, core_or_elective)
-
-    def delCourseRef(self, code):
+        self[code].__parent__ = self
+        self[code].__name__ = code
+        self._p_changed = True
+
+    def delCourseRef(self, code, level=None):
         """Delete a course denoted by its code.
         """
@@ -59,4 +63,7 @@
             if self[key].getCourseCode() != code:
                 continue
+            if level is not None and str(self[key].level) != str(level):
+                # found a course with correct key but wrong level...
+                continue
             del self[key]
             self._p_changed = True
@@ -113,9 +120,20 @@
     grok.order(2)
 
+    def getURLAndName(self, context):
+        url = self.view.url(context)
+        name = getName(context)
+        return (url, name)
+    
     def render(self):
-        return '''<h5>%s</h5><h4>%s</h4><h3>%s</h3>''' % (
-            getName(self.context.__parent__.__parent__.__parent__),
-            getName(self.context.__parent__.__parent__),
-            self.context.title)
+        url1, name1 = self.getURLAndName(
+            self.context.__parent__.__parent__.__parent__)
+        url2, name2 = self.getURLAndName(
+            self.context.__parent__.__parent__)
+        url3 = self.view.url(self.context)
+        name3 = self.context.title
+        return '''<h5><a href="%s">%s</a></h5>
+                  <h4><a href="%s">%s</a></h4>
+                  <h3><a href="%s">%s</a></h3>''' % (
+            url1, name1, url2, name2, url3, name3)
 
 class DisplayForm(grok.DisplayForm):
@@ -178,13 +196,141 @@
     grok.order(2)
 
-    def render(self):
-        result = '<h3>Courses</h4>\n'
+    def update(self):
+        if 'delcourse' in self.request.form:
+            code = self.request.form['code']
+            level = self.request.form['level']
+            self.context.delCourseRef(code, level=level)
+        return
+        
+    def getCourseList(self):
+        def cmpCourses(a, b):
+            if a['level'] < b['level']:
+                return -1
+            if a['level'] > b['level']:
+                return 1
+            if a['mandatory'] != b['mandatory']:
+                if a['mandatory'] == False and b['mandatory'] == True:
+                    return -1
+                return 1
+            if a['code'] < b['code']:
+                return -1
+            if a['code'] > b['code']:
+                return 1
+            return 0
+
+        entries = []
+        levels = dict()
         for key, course in self.context.items():
             certcourse = self.context[key]
             course = certcourse.course
-            result += '<div><a href="%s">%s</a>%s (%s / %s)</div>' % (
-                self.view.url(course), course.code, course.title,
-                certcourse.level, certcourse.core_or_elective)
-        return result
+            level = certcourse.level
+            mandatory = certcourse.core_or_elective
+            title = course.title
+            code = course.code
+            course_url = self.view.url(self.context[key])
+            semester = course.semester
+
+            new_entry = dict(
+                level=level, mandatory=mandatory, url=course_url,
+                title=title, code=code, semester=semester)
+            if str(level) not in levels.keys():
+                levels[str(level)] = dict()
+            if str(semester) not in levels[str(level)].keys():
+                levels[str(level)][str(semester)] = []
+            levels[str(level)][str(semester)].append(new_entry)
+        return levels
+
+
+class AddCertificateCourseForm(grok.AddForm):
+    grok.context(Certificate)
+    
+    form_fields = grok.AutoFields(ICertificateCourse)
+    label = 'Add a course'
+
+    @grok.action('Add course')
+    def addCertcourse(self, **data):
+        try:
+            self.context.addCourseRef(**data)
+        except DuplicationError:
+            self.status = Invalid('The chosen course is already part of'
+                                  'this certificate')
+            return
+        self.redirect(self.url(self.context))
+
+    @grok.action('Cancel')
+    def cancel(self, **data):
+        self.redirect(self.url(self.context))
+        return
+
+class AddCertificateCourse(FormWrapMixin, grok.Viewlet):
+    """A viewlet that wraps the `AddCertificateCourseForm`.
+    """
+    grok.viewletmanager(MainArea)
+    grok.context(ICertificate)
+    grok.view(AddCertificateCourse)
+    grok.require('waeup.manageUniversity')
+
+    formview_name = 'addcertificatecourseform' # The name of the formview we
+                                               # want to be rendered in this
+                                               # viewlet.
+
+class DisplayCertCourseForm(grok.DisplayForm):
+    grok.context(ICertificateCourse)
+    form_fields = grok.AutoFields(ICertificateCourse)
+
+class CertCourseContent(FormWrapMixin, grok.Viewlet):
+    """A viewlet that wraps the `DisplayForm`.
+    """
+    grok.viewletmanager(MainArea)
+    grok.context(ICertificateCourse)
+    grok.view(Index)
+    grok.order(2)
+    formview_name = 'displaycertcourseform' # The name of the formview we want
+                                            # to be rendered in this viewlet.
+
+class ManageCertCourseForm(grok.EditForm):
+    """Manage the basic properties of a `CertificateCourse` instance.
+    """
+    grok.context(ICertificateCourse)
+    form_fields = grok.AutoFields(ICertificateCourse)
+
+    @property
+    def label(self):
+        # Set certificate name as form label
+        return 'Edit certificate course %s' % self.context.course.code
+        return self.form_fields['title'].field.get(self.context)
+    
+    @grok.action('Save and return')
+    def saveAndReturn(self, **data):
+        parent = self.context.__parent__
+        if self.context.level == data['level']:
+            self.applyData(self.context, **data)
+        else:
+            # The level changed. We have to create a new certcourse as
+            # the key of the entry will change as well...
+            old_level = self.context.level
+            parent.addCourseRef(**data)
+            parent.delCourseRef(data['course'].code, level=old_level)
+        self.redirect(self.url(parent))
+        return
+
+    @grok.action('Cancel')
+    def cancel(self, **data):
+        self.redirect(self.url(self.context))
+        return
+
+class ManageCertificateCourse(FormWrapMixin, grok.Viewlet):
+    """A viewlet that renders the `ManageCertCourseForm`.
+    """
+    grok.viewletmanager(MainArea)
+    grok.context(ICertificateCourse)
+    grok.view(Manage)
+    grok.name('manage')
+    #grok.require('waeup.manageUniversity')
+    
+    formview_name = 'managecertcourseform' # The name of the formview
+                                           # we want to be rendered
+                                           # in this viewlet.
+
     
 @grok.subscribe(ICourse, grok.IObjectRemovedEvent)
