# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/course/info.php
--- moodle/course/info.php Base (1.42)
+++ moodle/course/info.php Locally Modified (Based On 1.42)
@@ -33,6 +33,8 @@
         print_error('coursehidden', '', $CFG->wwwroot .'/');
     }
 
+    $PAGE->set_context($context);
+    $PAGE->set_pagelayout('course');
     $PAGE->set_url('/course/info.php', array('id' => $course->id));
     $PAGE->set_title(get_string("summaryof", "", $course->fullname));
     $PAGE->set_heading('Course info');
Index: moodle/course/lib.php
--- moodle/course/lib.php Base (1.735)
+++ moodle/course/lib.php Locally Modified (Based On 1.735)
@@ -1856,7 +1856,68 @@
     }
 }
 
+/**
+ * This function generates a structured array of courses and categories.
+ *
+ * The depth of categories is limited by $CFG->maxcategorydepth however there
+ * is no limit on the number of courses!
+ *
+ * Suitable for use with the course renderers course_category_tree method:
+ * $renderer = $PAGE->get_renderer('core','course');
+ * echo $renderer->course_category_tree(get_course_category_tree());
+ *
+ * @global moodle_database $DB
+ * @param int $id
+ * @param int $depth
+ */
+function get_course_category_tree($id = 0, $depth = 0) {
+    global $DB;
+    $viewhiddencats = has_capability('moodle/category:viewhiddencategories', get_context_instance(CONTEXT_SYSTEM));
+    $categories = get_child_categories($id);
+    $categoryids = array();
+    foreach ($categories as $key => &$category) {
+        if (!$category->visible && !$viewhiddencats) {
+            unset($categories[$key]);
+            continue;
+        }
+        $categoryids[$category->id] = $category;
+        if (empty($CFG->maxcategorydepth) || $depth <= $CFG->maxcategorydepth) {
+            list($category->categories, $subcategories) = get_course_category_tree($category->id, $depth+1);
+            $categoryids = array_merge($categoryids, $subcategories);
+            $category->courses = array();
+        }
+    }
 
+    if ($depth > 0) {
+        // This is a recursive call so return the required array
+        return array($categories, $categoryids);
+    }
+
+    // The depth is 0 this function has just been called so we can finish it off
+
+    list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
+    list($catsql, $catparams) = $DB->get_in_or_equal(array_keys($categoryids));
+    $sql = "SELECT
+            c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.guest,c.cost,c.currency,c.category
+            $ccselect
+            FROM {course} c
+            $ccjoin
+            WHERE c.category $catsql ORDER BY c.sortorder ASC";
+    if ($courses = $DB->get_records_sql($sql, $catparams)) {
+        // loop throught them
+        foreach ($courses as $course) {
+            if ($course->id == SITEID) {
+                continue;
+            }
+            context_instance_preload($course);
+            if (!empty($course->visible) || has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $course->id))) {
+                $categoryids[$course->category]->courses[$course->id] = $course;
+            }
+        }
+    }
+    return $categories;
+}
+
 /**
  * Recursive function to print out all the categories in a nice format
  * with or without courses included
Index: moodle/course/renderer.php
--- moodle/course/renderer.php No Base Revision
+++ moodle/course/renderer.php Locally New
@@ -0,0 +1,157 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle 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.
+//
+// Moodle 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 Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Renderer for use with the course section and all the goodness that falls
+ * within it.
+ *
+ * This renderer should contain methods useful to courses, and categories.
+ *
+ * @package   moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * The core course renderer
+ *
+ * Can be retrieved with the following:
+ * $renderer = $PAGE->get_renderer('core','course');
+ */
+class core_course_renderer extends plugin_renderer_base {
+
+    /**
+     * A cache of strings
+     * @var stdClass
+     */
+    protected $strings;
+
+    /**
+     * Override the constructor so that we can initialise the string cache
+     *
+     * @param moodle_page $page
+     * @param string $target
+     */
+    public function __construct(moodle_page $page, $target) {
+        $this->strings = new stdClass;
+        parent::__construct($page, $target);
+    }
+
+    /**
+     * Renderers a structured array of courses and categories into a nice
+     * XHTML tree structure.
+     *
+     * This method was designed initially to display the front page course/category
+     * combo view. The structure can be retrieved by get_course_category_tree()
+     *
+     * @param array $structure
+     * @return string
+     */
+    public function course_category_tree(array $structure) {
+        $this->strings->allowguests = get_string('allowguests');
+        $this->strings->requireskey = get_string('requireskey');
+        $this->strings->summary = get_string('summary');
+
+        // Generate an id and the required JS call to make this a nice widget
+        $id = html_writer::random_id('course_category_tree');
+        $this->page->requires->js_init_call('M.util.init_toggle_class_on_click', array($id, '.category.with_children', 'collapsed'));
+
+        // Start content generation
+        $content = html_writer::start_tag('div', array('class'=>'course_category_tree', 'id'=>$id));
+        foreach ($structure as $category) {
+            $content .= $this->course_category_tree_category($category);
+        }
+        $content .= html_writer::start_tag('div', array('class'=>'controls'));
+        $content .= html_writer::tag('div', get_string('collapseall'), array('class'=>'addtoall expandall'));
+        $content .= html_writer::tag('div', get_string('expandall'), array('class'=>'removefromall collapseall'));
+        $content .= html_writer::end_tag('div');
+        $content .= html_writer::end_tag('div');
+        
+        // Return the course category tree HTML
+        return $content;
+    }
+
+    /**
+     * Renderers a category for use with course_category_tree
+     *
+     * @param array $category
+     * @param int $depth
+     * @return string
+     */
+    protected function course_category_tree_category(stdClass $category, $depth=1) {
+        $content = '';
+        $hassubcategories = (count($category->categories)>0);
+        $hascourses = (count($category->courses)>0);
+        $classes = array('category');
+        if ($category->parent != 0) {
+            $classes[] = 'subcategory';
+        }
+        if ($hassubcategories || $hascourses) {
+            $classes[] = 'with_children';
+            if ($depth > 1) {
+                $classes[] = 'collapsed';
+            }
+        }
+        $content .= html_writer::start_tag('div', array('class'=>join(' ', $classes)));
+        $content .= html_writer::start_tag('div', array('class'=>'category_label'));
+        $content .= html_writer::link(new moodle_url('/course/category.php', array('id'=>$category->id)), $category->name, array('class'=>'category_link'));
+        $content .= html_writer::end_tag('div');
+        if ($hassubcategories) {
+            $content .= html_writer::start_tag('div', array('class'=>'subcategories'));
+            foreach ($category->categories as $subcategory) {
+                $content .= $this->course_category_tree_category($subcategory, $depth+1);
+            }
+            $content .= html_writer::end_tag('div');
+        }
+        if ($hascourses) {
+            $content .= html_writer::start_tag('div', array('class'=>'courses'));
+            $coursecount = 0;
+            foreach ($category->courses as $course) {
+                $classes = array('course');
+                $coursecount ++;
+                $classes[] = ($coursecount%2)?'odd':'even';
+                $content .= html_writer::start_tag('div', array('class'=>join(' ', $classes)));
+                $content .= html_writer::link(new moodle_url('/course/view.php', array('id'=>$course->id)), $course->fullname, array('class'=>'course_link'));
+                $content .= html_writer::start_tag('div', array('class'=>'course_info clearfix'));
+
+                if ($course->guest ) {
+                    $image = html_writer::empty_tag('img', array('src'=>$this->output->pix_url('i/guest'), 'alt'=>$this->strings->allowguests));
+                    $content .= html_writer::tag('div', $image, array('course_info_spacer'));
+                } else {
+                    $content .= html_writer::tag('div', '', array('course_info_spacer'));
+                }
+                if ($course->password) {
+                    $image = html_writer::empty_tag('img', array('src'=>$this->output->pix_url('i/key'), 'alt'=>$this->strings->requireskey));
+                    $content .= html_writer::tag('div', $image, array('course_info_spacer'));
+                } else {
+                    $content .= html_writer::tag('div', '', array('course_info_spacer'));
+                }
+                if ($course->summary) {
+                    $image = html_writer::empty_tag('img', array('src'=>$this->output->pix_url('i/info'), 'alt'=>$this->strings->summary));
+                    $content .= html_writer::link(new moodle_url('/course/info.php', array('id'=>$course->id)), $image, array('title'=>$this->strings->summary));
+                } else {
+                    $content .= html_writer::tag('div', '', array('course_info_spacer'));
+                }
+                $content .= html_writer::end_tag('div');
+                $content .= html_writer::end_tag('div');
+            }
+            $content .= html_writer::end_tag('div');
+        }
+        $content .= html_writer::end_tag('div');
+        return $content;
+    }
+}
Index: moodle/index.php
--- moodle/index.php Base (1.255)
+++ moodle/index.php Locally Modified (Based On 1.255)
@@ -196,11 +196,9 @@
             break;
 
             case FRONTPAGECATEGORYCOMBO:
-
                 echo $OUTPUT->heading(get_string('categories'), 2, 'headingblock header');
-                echo $OUTPUT->box_start('generalbox categorybox');
-                print_whole_category_list(NULL, NULL, NULL, -1, true);
-                echo $OUTPUT->box_end();
+                $renderer = $PAGE->get_renderer('core','course');
+                echo $renderer->course_category_tree(get_course_category_tree());
                 print_course_search('', false, 'short');
             break;
 
Index: moodle/lang/en/moodle.php
--- moodle/lang/en/moodle.php Base (1.528)
+++ moodle/lang/en/moodle.php Locally Modified (Based On 1.528)
@@ -250,6 +250,7 @@
 $string['clicktohideshow'] = 'Click to expand or collapse';
 $string['clicktochange'] = 'Click to change';
 $string['closewindow'] = 'Close this window';
+$string['collapseall'] = 'Collapse all';
 $string['commentincontext'] = 'Find this comment in context';
 $string['comments'] = 'Comments';
 $string['comparelanguage'] = 'Compare and edit current language';
@@ -675,6 +676,7 @@
 $string['existingcreators'] = 'Existing course creators';
 $string['existingstudents'] = 'Enrolled students';
 $string['existingteachers'] = 'Existing teachers';
+$string['expandall'] = 'Expand all';
 $string['expirynotify'] = 'Enrolment expiry notification';
 $string['expirynotifyemail'] = 'The following students in this course are expiring after exactly {$a->threshold} days:
 
Index: moodle/lib/javascript-static.js
--- moodle/lib/javascript-static.js Base (1.154)
+++ moodle/lib/javascript-static.js Locally Modified (Based On 1.154)
@@ -393,6 +393,36 @@
     });
 };
 
+/**
+ * Finds all nodes that match the given CSS selector and attaches events to them
+ * so that they toggle a given classname when clicked.
+ *
+ * @param {YUI} Y
+ * @param {string} id An id containing elements to target
+ * @param {string} cssselector A selector to use to find targets
+ * @param {string} toggleclassname A classname to toggle
+ */
+M.util.init_toggle_class_on_click = function(Y, id, cssselector, toggleclassname) {
+    var node = Y.one('#'+id);
+    node.all(cssselector).each(function(node){
+        node.on('click', function(e){
+            e.stopPropagation();
+            if (e.target.get('nodeName')!='A' && e.target.get('nodeName')!='IMG') {
+                this.toggleClass(toggleclassname);
+            }
+        }, node);
+    });
+    // Attach this click event to the node rather than all selectors... will be much better
+    // for performance
+    node.on('click', function(e){
+        if (e.target.hasClass('addtoall')) {
+            node.all(cssselector).addClass(toggleclassname);
+        } else if (e.target.hasClass('removefromall')) {
+            node.all(cssselector+'.'+toggleclassname).removeClass(toggleclassname);
+        }
+    }, node);
+}
+
 //=== old legacy JS code, hopefully to be replaced soon by M.xx.yy and YUI3 code ===
 
 function popupchecker(msg) {
Index: moodle/lib/moodlelib.php
--- moodle/lib/moodlelib.php Base (1.1386)
+++ moodle/lib/moodlelib.php Locally Modified (Based On 1.1386)
@@ -7021,6 +7021,7 @@
             'condition'   => NULL,
             'completion'  => NULL,
             'countries'   => NULL,
+            'course'      => 'course',
             'currencies'  => NULL,
             'dbtransfer'  => NULL,
             'debug'       => NULL,
Index: moodle/mod/assignment/index.php
--- moodle/mod/assignment/index.php Base (1.53)
+++ moodle/mod/assignment/index.php Locally Modified (Based On 1.53)
@@ -29,6 +29,7 @@
 $PAGE->set_url('/mod/assignment/index.php', array('id'=>$course->id));
 $PAGE->navbar->add($strassignments);
 $PAGE->set_title($strassignments);
+$PAGE->set_heading($course->fullname);
 echo $OUTPUT->header();
 
 if (!$cms = get_coursemodules_in_course('assignment', $course->id, 'cm.idnumber, m.assignmenttype, m.timedue')) {
Index: moodle/theme/base/style/course.css
--- moodle/theme/base/style/course.css Base (1.3)
+++ moodle/theme/base/style/course.css Locally Modified (Based On 1.3)
@@ -86,3 +86,18 @@
 .topics-format {margin-top: 8px;min-width: 763px;}
 #page-course-user .section {border-width:1px;border-style:solid;padding:10px;}
 .categoryboxcontent {border-width:1px;border-style:solid;}
+
+/* Course and category combo list on front page */
+.course_category_tree .controls {visibility: hidden;}
+.course_category_tree .controls div {display:inline;cursor:pointer;}
+.course_category_tree .category.with_children .category_label {background-image:url([[pix:moodle|t/expanded]]);background-repeat: no-repeat;}
+.course_category_tree .category_label {padding-left:13px;}
+.course_category_tree .category .courses .course_link {display:block;background-image:url([[pix:moodle|i/course]]);background-repeat: no-repeat;padding-left:18px;}
+.course_category_tree .category .course {position:relative;}
+.course_category_tree .category .course_info {position:absolute;right:0;top:0;}
+.course_category_tree .category .course_info a,
+.course_category_tree .category .course_info div {float:left;width:16px;height:16px;}
+.jsenabled .course_category_tree .controls {visibility: visible;}
+.jsenabled .course_category_tree .category.with_children.collapsed .category_label {background-image:url([[pix:moodle|t/collapsed]]);}
+.jsenabled .course_category_tree .category.with_children.collapsed .subcategories,
+.jsenabled .course_category_tree .category.with_children.collapsed .courses {display:none;}
Index: moodle/theme/standard/style/course.css
--- moodle/theme/standard/style/course.css Base (1.1)
+++ moodle/theme/standard/style/course.css Locally Modified (Based On 1.1)
@@ -85,3 +85,21 @@
 .categorypicker {text-align:center;margin-bottom:10px;}
 .path-course-report-outline .loginfo {text-align:center;margin: 1em;}
 .categorylist {width: 90%;margin:0 auto;text-align: left;}
+
+/* Course and category combo list on front page */
+.course_category_tree .controls {margin-bottom:5px;text-align:right;float:right;}
+.course_category_tree .controls div {padding-right:2em;font-size:75%;}
+.course_category_tree .category {background-color:#FFF;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border:1px solid #ddd;margin-bottom:10px;}
+.course_category_tree .category .category {margin:5px;}
+.course_category_tree .category .subcategories {background-color:inherit;padding-left:16px;border:1px solid #FFF;}
+.course_category_tree .category.with_children .category_label {background-position:3px 3px;}
+.course_category_tree .category_link .category_link {font-size:95%;}
+.course_category_tree .category_label {padding-left:13px;}
+.course_category_tree .category_link {display:block;margin:5px;font-size:120%;font-weight:bold;}
+.course_category_tree .category .courses {background-color:inherit;padding-left:16px;}
+.course_category_tree .category .courses .course_link {margin:5px;}
+.course_category_tree .category .course {border:1px solid #f9f9f9;border-bottom-color: #eee;border-right-width:0;}
+.course_category_tree .category .course:last-child {border-bottom-color:#f6f6f6;}
+.course_category_tree .category .course.even {background-color:#f6f6f6;border-color:#eee;border-top-color: #f9f9f9;}
+.course_category_tree .category .course_info {right:3px;top:3px;}
+.course_category_tree .category .course:hover {background-color:#eee;}
