--- loncom/interface/lonstatistics.pm	2006/05/30 12:46:09	1.136
+++ loncom/interface/lonstatistics.pm	2010/09/12 17:40:33	1.148.2.5
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonstatistics.pm,v 1.136 2006/05/30 12:46:09 www Exp $
+# $Id: lonstatistics.pm,v 1.148.2.5 2010/09/12 17:40:33 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -28,19 +28,7 @@
 #
 ###
 
-=pod
-
-=head1 NAME
-
-lonstatistics
-
-=head1 SYNOPSIS
 
-Main handler for statistics and chart.
-
-=over 4
-
-=cut
 
 package Apache::lonstatistics;
 
@@ -76,36 +64,8 @@ use Apache::lonpercentage;
 use Apache::lonstudentsubmissions();
 use Apache::lonsurveyreports();
 use Apache::longradinganalysis();
-use lib '/home/httpd/lib/perl/';
 use LONCAPA;
 
-#######################################################
-#######################################################
-
-=pod
-
-=item Package Variables
-
-=item @FullClasslist The full classlist
-
-=item @Students The students we are concerned with for this invocation
-
-=item @Sections The sections available in this class
-
-=item @Groups The groups available in the class
-
-=item $curr_student The student currently being examined
-
-=item $prev_student The student previous in the classlist
-
-=item $next_student The student next in the classlist
-
-=over
-
-=cut 
-
-#######################################################
-#######################################################
 #
 # Classlist variables
 #
@@ -113,43 +73,7 @@ my $curr_student;
 my $prev_student;
 my $next_student;
 
-#######################################################
-#######################################################
-
-=pod
-
-=item &clear_classlist_variables()
-
-undef the following package variables:
-
-=over
-
-=item @FullClasslist
-
-=item @Students
-
-=item @Sections
-
-=item @Groups
-
-=item %StudentData
-
-=item @StudentDataOrder
-
-=item @SelectedStudentData
-
-=item $curr_student
-
-=item $prev_student
-
-=item $next_student
-
-=back
-
-=cut
 
-#######################################################
-#######################################################
 sub clear_classlist_variables {
     undef(@FullClasslist);
     undef(@Students);
@@ -162,45 +86,7 @@ sub clear_classlist_variables {
     undef($next_student);
 }
 
-#######################################################
-#######################################################
 
-=pod
-
-=item &PrepareClasslist()
-
-Build up the classlist information.  The classlist information is kept in
-the following package variables:
-
-=over
-
-=item @FullClasslist
-
-=item @Students
-
-=item @Sections
-
-=item @Groups 
-
-=item %StudentData
-
-=item @SelectedStudentData
-
-=item $curr_student
-
-=item $prev_student
-
-=item $next_student
-
-=back
-
-$curr_student, $prev_student, and $next_student may not be defined, depending
-upon the calling context.
-
-=cut
-
-#######################################################
-#######################################################
 sub PrepareClasslist {
     my %Sections;
     &clear_classlist_variables();
@@ -313,7 +199,11 @@ sub PrepareClasslist {
     if ($env{'request.course.sec'} !~ /^\s*$/) {
         @Sections = ($env{'request.course.sec'});
     } else {
-        @Sections = sort {$a cmp $b} keys(%Sections);
+        @Sections = sort {
+	    if ($a == $a && $b == $b ) { return $a <=> $b; }
+	    return $a cmp $b;
+	} keys(%Sections);
+
         unshift(@Sections,'all'); # Put 'all' at the front of the list
     }
     # Sort the groups
@@ -371,19 +261,7 @@ sub PrepareClasslist {
     return;
 }
 
-#######################################################
-#######################################################
-
-=pod
 
-=item get_selected_sections
-
-Returns an array of the selected sections
-
-=cut
-
-#######################################################
-#######################################################
 sub get_selected_sections {
     my @selected_sections = 
 	&Apache::loncommon::get_env_multiple('form.Section');
@@ -401,19 +279,7 @@ sub get_selected_sections {
     return @selected_sections;
 }
 
-#######################################################
-#######################################################
-                                                                                    
-=pod
-                                                                                    
-=item get_selected_groups
-                                                                                    
-Returns an array of the selected groups
-                                                                                    
-=cut
-                                                                                    
-#######################################################
-#######################################################
+
 sub get_selected_groups {
     my @selected_groups =
         &Apache::loncommon::get_env_multiple('form.Group');
@@ -427,21 +293,8 @@ sub get_selected_groups {
     return @selected_groups;
 }
                                                                                     
-=pod
-
-=item &section_and_enrollment_description
-
-Returns a string describing the currently selected section(s), group(s) and 
-enrollment status.  
 
-Inputs: mode = 'plaintext' or 'localized'  (defaults to 'localized')
-    'plaintext' is used for example in Excel spreadsheets.
-Returns: scalar description string.
 
-=cut
-
-#######################################################
-#######################################################
 sub section_and_enrollment_description {
     my ($mode) = @_;
     if (! defined($mode)) { $mode = 'localized'; }
@@ -449,9 +302,9 @@ sub section_and_enrollment_description {
     my @groups = &Apache::lonstatistics::get_selected_groups();
     my $description;
     if ($mode eq 'localized') {
-        $description = &mt('Unable to determine section, groups and enrollment');
+        $description = &mt('Unable to determine section, groups and access status');
     } elsif ($mode eq 'plaintext') {
-        $description = 'Unable to determine section, groups and enrollment';
+        $description = 'Unable to determine section, groups and access status';
     } else {
         $description = 'Bad parameter passed to lonstatistics::section_and_enrollment_description';
         &Apache::lonnet::logthis($description);
@@ -459,15 +312,15 @@ sub section_and_enrollment_description {
     $description = &section_or_group_text($mode,'section',@sections).
 	' '.&section_or_group_text($mode,'group',@groups);
     if ($mode eq 'localized') {
-        $description .= &mt(' [_1] enrollment status.',$env{'form.Status'});
+        $description .= ' '.&mt($env{'form.Status'}.' access status.');
     } elsif ($mode eq 'plaintext') {
-        $description .= ' '.$env{'form.Status'}.' enrollment status.';
+        $description .= ' '.$env{'form.Status'}.' access status.';
     }
     return $description;
 }
 
-#######################################################
-#######################################################
+
+
 
 sub section_or_group_text {
     my ($mode,$type,@items) = @_;
@@ -485,21 +338,21 @@ sub section_or_group_text {
                              );
     if (scalar(@items) == 1 && $items[0] ne 'all') {
         if ($mode eq 'localized') {
-            $text = &mt('[_1] [_2].',$phrases{$type}{single},$items[0]);
+            $text = &mt($phrases{$type}{single}.' [_1].',$items[0]);
         } elsif ($mode eq 'plaintext') {
             $text = $phrases{$type}{single}.' '.$items[0].'.';
 
         }
     } elsif (scalar(@items) && $items[0] eq 'all') {
         if ($mode eq 'localized') {
-            $text = &mt('[_1].',$phrases{$type}{all});
+            $text = &mt($phrases{$type}{all}.'.');
         } elsif ($mode eq 'plaintext') {
             $text = $phrases{$type}{all}.'.';
         }
     } elsif (scalar(@items)) {
         my $lastitem = pop(@items);
         if ($mode eq 'localized') {
-            $text = &mt('[_1] [_2] and [_3].',$phrases{$type}{plural},
+            $text = &mt($phrases{$type}{plural}.' [_1] and [_2].',
                         join(', ',@items),$lastitem);
         } elsif ($mode eq 'plaintext') {
             $text = $phrases{$type}{plural}.' '.join(', ',@items).' and '.
@@ -510,16 +363,6 @@ sub section_or_group_text {
 }
 
 
-=pod
-
-=item get_students
-
-Returns a list of the selected students
-
-=cut
-
-#######################################################
-#######################################################
 sub get_students {
     if (! @Students) {
         &PrepareClasslist()
@@ -527,84 +370,26 @@ sub get_students {
     return @Students;
 }
 
-#######################################################
-#######################################################
-
-=pod
-
-=item &current_student()
 
-Returns a pointer to a hash containing data about the currently
-selected student.
 
-=cut
-
-#######################################################
-#######################################################
 sub current_student { 
     return $curr_student;
 }
 
-#######################################################
-#######################################################
-
-=pod
-
-=item &previous_student()
 
-Returns a pointer to a hash containing data about the student prior
-in the list of students.  Or something.  
 
-=cut
-
-#######################################################
-#######################################################
 sub previous_student { 
     return $prev_student;
 }
 
-#######################################################
-#######################################################
-
-=pod
-
-=item &next_student()
 
-Returns a pointer to a hash containing data about the next student
-to be viewed.
 
-=cut
-
-#######################################################
-#######################################################
 sub next_student { 
     return $next_student;
 }
 
-##############################################
-##############################################
 
-=pod 
 
-=item &StudentDataSelect($elementname,$status,$numvisible,$selected)
-
-Returns html for a selection box allowing the user to choose one (or more) 
-of the fields of student data available (fullname, username, id, section, etc)
-
-=over 4
-
-=item $elementname The name of the HTML form element
-
-=item $status 'multiple' or 'single' selection box
-
-=item $numvisible The number of options to be visible
-
-=back
-
-=cut
-
-##############################################
-##############################################
 sub StudentDataSelect {
     my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {
@@ -615,7 +400,7 @@ sub StudentDataSelect {
     my $Str = "\n";
     $Str .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {
-        $Str .= 'multiple="true" ';
+        $Str .= 'multiple="multiple" ';
     }
     $Str .= 'size="'.$numvisible.'" >'."\n";
     #
@@ -644,22 +429,8 @@ sub StudentDataSelect {
     return $Str;
 }
 
-#######################################################
-#######################################################
 
-=pod
 
-=item &get_selected_maps($elementname)
-
-Input: Name of the <select> form element used to specify the maps.
-
-Returns: Array of symbs of selected maps or the description 'all'.
-   If form.$elementname does not exist, 'all' is returned.
-
-=cut
-
-#######################################################
-#######################################################
 sub get_selected_maps {
     my ($elementname) = @_;
     my @selected_maps = 
@@ -675,25 +446,8 @@ sub get_selected_maps {
 }
 
 
-#######################################################
-#######################################################
-
-=pod
-
-=item &selected_sequences_with_assessments
 
-Retrieve the sequences which were selected by the user to show.  
 
-Input: $mode: scalar.  Either 'selected' or 'all'.  If not specified,
-    'selected' is used.
-
-Returns: an array containing a navmap object and navmap resources, 
-    or an array containing a scalar with an error message.
-
-=cut
-
-#######################################################
-#######################################################
 sub selected_sequences_with_assessments {
     my ($mode) = @_;
     $mode = 'selected' if (! defined($mode));
@@ -702,10 +456,24 @@ sub selected_sequences_with_assessments
         return ('Can not open Coursemap');
     }
     #
-    my @sequences = $navmap->retrieveResources(undef,
+    my $mapurl;
+    if (&Apache::loncommon::needs_gci_custom()) {
+        my $cid = $env{'request.course.id'};
+        if ($cid) {
+            $mapurl = '/uploaded/'.$env{'course.'.$cid.'.domain'}.'/'.$env{'course.'.$cid.'.num'}.'/default_1261144274.sequence';
+        }
+    }
+    my @sequences = $navmap->retrieveResources($mapurl,
                                                sub { shift->is_map(); },1,0,1);
+    unless (&Apache::loncommon::needs_gci_custom()) {
+        my $toplevelseq = $navmap->getById('0.0');
+        if (!grep(/^\Q$toplevelseq\E$/,@sequences)) {
+            unshift(@sequences,$toplevelseq);
+        }
+    }
+
     my @sequences_with_assessments;
-    for my $sequence ($navmap->getById('0.0'), @sequences) {
+    foreach my $sequence (@sequences) {
 	if ($navmap->hasResource($sequence,sub { shift->is_problem(); },0,1)){
             push(@sequences_with_assessments,$sequence);
         }
@@ -728,31 +496,7 @@ sub selected_sequences_with_assessments
     return $navmap,@sequences_to_show;
 }
 
-##############################################
-##############################################
-
-=pod 
-
-=item &map_select($elementname,$status,$numvisible,$restriction) 
-
-Returns html for a selection box allowing the user to choose one (or more) 
-of the sequences in the course.  The values of the sequences are the symbs.
-If the top sequence is selected, the value 'top' will result.
-
-=over 4
-
-=item $elementname The name of the HTML form element
-
-=item $status 'multiple' or 'single' selection box
-
-=item $numvisible The number of options to be visible
-
-=back
-
-=cut
 
-##############################################
-##############################################
 sub map_select {
     my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {
@@ -766,16 +510,18 @@ sub map_select {
     my $form = "\n";
     $form .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {
-        $form .= 'multiple="true" ';
+        $form .= 'multiple="multiple" ';
     }
     $form .= 'size="'.$numvisible.'" >'."\n";
-    #
-    # Put in option for 'all'
-    $form .= '    <option value="all" ';
-    if ($selected_maps[0] eq 'all') {
-        $form .= 'selected ';
+    unless (&Apache::loncommon::needs_gci_custom()) {
+        #
+        # Put in option for 'all'
+        $form .= '    <option value="all" ';
+        if ($selected_maps[0] eq 'all') {
+            $form .= 'selected ';
+        }
+        $form .= ">all</option>\n";
     }
-    $form .= ">all</option>\n";
     #
     # Loop through the sequences
     my @sequences = &selected_sequences_with_assessments('all');
@@ -787,10 +533,14 @@ sub map_select {
     }
     foreach my $seq (@sequences){
         $form .= '    <option value="'.$seq->symb.'" ';
-        foreach (@selected_maps) {
-            if ($seq->symb eq $_) {
-                $form .= 'selected ';
-                last;
+        if ((&Apache::loncommon::needs_gci_custom()) && (@selected_maps == 1)) {
+            $form .= 'selected ';
+        } else {
+            foreach (@selected_maps) {
+                if ($seq->symb eq $_) {
+                    $form .= 'selected ';
+                    last;
+                }
             }
         }
         $form .= '>'.$seq->compTitle."</option>\n";
@@ -799,31 +549,7 @@ sub map_select {
     return $form;
 }
 
-##############################################
-##############################################
 
-=pod 
-
-=item &SectionSelect($elementname,$status,$numvisible) 
-
-Returns html for a selection box allowing the user to choose one (or more) 
-of the sections in the course.  
-
-Uses the package variables @Sections
-=over 4
-
-=item $elementname The name of the HTML form element
-
-=item $status 'multiple' or 'single' selection box
-
-=item $numvisible The number of options to be visible
-
-=back
-
-=cut
-
-##############################################
-##############################################
 sub SectionSelect {
     my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {
@@ -839,7 +565,7 @@ sub SectionSelect {
     my $Str = "\n";
     $Str .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {
-        $Str .= 'multiple="true" ';
+        $Str .= 'multiple="multiple" ';
     }
     $Str .= 'size="'.$numvisible.'" >'."\n";
     #
@@ -858,31 +584,7 @@ sub SectionSelect {
     return $Str;
 }
 
-##############################################
-##############################################
-                                                                                    
-=pod
-                                                                                    
-=item &GroupSelect($elementname,$status,$numvisible)
-                                                                                    
-Returns html for a selection box allowing the user to choose one (or more)
-of the groups in the course.
-                                                                                    
-Uses the package variables @Groups
-=over 4
-                                                                                    
-=item $elementname The name of the HTML form element
-                                                                                    
-=item $status 'multiple' or 'single' selection box
-                                                                                    
-=item $numvisible The number of options to be visible
-                                                                                    
-=back
-                                                                                    
-=cut
-                                                                                    
-##############################################
-##############################################
+
 sub GroupSelect {
     my ($elementname,$status,$numvisible)=@_;
     if ($numvisible < 1) {
@@ -898,7 +600,7 @@ sub GroupSelect {
     my $Str = "\n";
     $Str .= '<select name="'.$elementname.'" ';
     if ($status ne 'single') {
-        $Str .= 'multiple="true" ';
+        $Str .= 'multiple="multiple" ';
     }
     $Str .= 'size="'.$numvisible.'" >'."\n";
     #
@@ -917,8 +619,8 @@ sub GroupSelect {
 }
 
 
-##################################################
-##################################################
+
+
 sub DisplayClasslist {
     my ($r)=@_;
     &Apache::lonhtmlcommon::add_breadcrumb
@@ -931,7 +633,7 @@ sub DisplayClasslist {
     $Str .= '<tr>';
     $Str .= '<th align="center"><b>'.&mt('Sections').'</b></th>';
     $Str .= '<th align="center"><b>'.&mt('Groups').'</b></th>';
-    $Str .= '<th align="center"><b>'.&mt('Enrollment Status').'</b></th>';
+    $Str .= '<th align="center"><b>'.&mt('Access Status').'</b></th>';
     $Str .= '</tr>'.$/;
     $Str .= '<tr>';
     $Str .= '<td>'.
@@ -957,46 +659,55 @@ sub DisplayClasslist {
     my @selected_sections = &get_selected_sections();
     if (! @Students) {
         if ($selected_sections[0] eq 'all') { 
-            if (lc($env{'form.Status'}) eq 'any') {
-                $Str .= '<h2>'.
-                    &mt('There are no students in the course.').
-                    '</h2>';
-            } elsif (lc($env{'form.Status'}) eq 'active') {
-                $Str .= '<h2>'.
+            if (lc($env{'form.Status'}) eq 'active') {
+                $Str .= '<p class="LC_info">'.
                 &mt('There are no currently enrolled students in the course.').
-                    '</h2>';
+                    '</p>';
             } elsif (lc($env{'form.Status'}) eq 'expired') {
-                $Str .= '<h2>'.
+                $Str .= '<p class="LC_info">'.
                     &mt('There are no previously enrolled students in the course.').
-                        '</h2>';
+                        '</p>';
+            } elsif (lc($env{'form.Status'}) eq 'future') {
+                $Str .= '<p class="LC_info">'.
+                    &mt('There are no students with future access in the course.').
+                        '</p>';
+            } else { # 'any' and any others
+               $Str .= '<p class="LC_info">'.
+                    &mt('There are no students in the course.').
+                    '</p>';
             }
         } else { 
-            my $sections;
-            if (lc($env{'form.Status'}) eq 'any') {
-                $Str .= '<h2>'.
-                    &mt('There are no students in the selected sections.').
-                    '</h2>';
-            } elsif (lc($env{'form.Status'}) eq 'active') {
-                $Str .= '<h2>'.
+            if (lc($env{'form.Status'}) eq 'active') {
+                $Str .= '<p class="LC_info">'.
                     &mt('There are no currently enrolled students in the selected sections.').
-                    '</h2>';
+                    '</p>';
             } elsif (lc($env{'form.Status'}) eq 'expired') {
-                $Str .= '<h2>'.
+                $Str .= '<p class="LC_info">'.
                     &mt('There are no previously enrolled students in the selected sections.').
-                    '</h2>';
+                    '</p>';
+            } elsif (lc($env{'form.Status'}) eq 'future') {
+                $Str .= '<p class="LC_info">'.
+                    &mt('There are no students with future access in the selected sections.').
+                        '</p>';
+            } else { # 'any' and any others
+                $Str .= '<p class="LC_info">'.
+                    &mt('There are no students in the selected sections.').
+                    '</p>';
             }
         }
-        $Str.= '<a href="/adm/statistics?reportSelected=student_assessment">'.
-            &mt('Click here to return to the chart').'</a>';
+        $Str.= '<p>'
+              .'<a href="/adm/statistics?reportSelected=student_assessment">'
+              .&mt('Return to the chart').'</a>'
+              .'</p>';
         $r->print($Str);
         $r->rflush();
         return;
     }
 
-    # "Click" is asinine but it is probably not my place to change the world.
-    $Str .= '<h2>Click on a students name or username to view their chart</h2>';
-    $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
-    $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
+    $Str .= '<h2>'.&mt('Select One Student').'</h2>'
+           .'<p>'.&mt("Click on a student's name or username to view their chart").'</p>'
+           .&Apache::loncommon::start_data_table()
+           .&Apache::loncommon::start_data_table_header_row();
     foreach my $field (@Fields) {
         $Str .= '<th><a href="/adm/statistics?'.
             'reportSelected=student_assessment&'.
@@ -1004,17 +715,11 @@ sub DisplayClasslist {
             'sort='.$field.'">'.&mt($field).
             '</a></th>';
     }
-    $Str .= '</tr>'."\n";
+    $Str .= &Apache::loncommon::end_data_table_header_row();
     #
-    my $alternate = 0;
     foreach my $student (@Students) { # @Students is a package variable
         my $sname = $student->{'username'}.':'.$student->{'domain'};
-        if($alternate) {
-            $Str .= '<tr bgcolor="#ffffe6">';
-        } else {
-            $Str .= '<tr bgcolor="#ffffc6">';
-        }
-        $alternate = ($alternate + 1) % 2;
+        $Str .= &Apache::loncommon::start_data_table_row();
         #
         foreach my $field (@Fields) {
             $Str .= '<td>';
@@ -1024,7 +729,7 @@ sub DisplayClasslist {
                 $Str .= '&sort='.&escape($env{'form.sort'});
                 $Str .= '&SelectedStudent=';
                 $Str .= &escape($sname).'">';
-                $Str .= $student->{$field}.'&nbsp';
+                $Str .= $student->{$field}.'&nbsp;';
                 $Str .= '</a>';
             } elsif ($field eq 'status') {
                 $Str .= &mt($student->{$field});
@@ -1033,9 +738,9 @@ sub DisplayClasslist {
             }
             $Str .= '</td>';
         }
-        $Str .= "</tr>\n";
+        $Str .= &Apache::loncommon::end_data_table_row();
     }
-    $Str .= '</table></td></tr></table>'."\n";
+    $Str .= &Apache::loncommon::end_data_table();
     #
     $r->print($Str);
     $r->rflush();
@@ -1043,72 +748,74 @@ sub DisplayClasslist {
     return;
 }
 
-##############################################
-##############################################
+
+
 sub CreateMainMenu {
     #
     # Define menu data
-    my @reports = ({ internal_name => 'problem_statistics',
-                     name => &mt('Overall Problem Statistics'),
-                     short_description => 
-    &mt('Student performance statistics on all problems.'),
-                 },
-                   { internal_name => 'problem_analysis',
-                     name => &mt('Detailed Problem Analysis'),
-                     short_description => 
-    &mt('Detailed statistics and graphs of student performance on problems.'),
-                 },
-                   { internal_name => 'submissiontime_analysis',
-                     name => &mt('Submission Time Plots'),
-                     short_description => 
-    &mt('Display and analysis of submission times on assessments.'),
-                 },
-                   { internal_name => 'student_submission_reports',
-                     name => &mt('Student Submission Reports'),
-                     short_description => 
-    &mt('Prepare reports of student submissions.'),
-                 },
-                   { internal_name => 'survey_reports',
-                     name => &mt('Survey Reports'),
-                     short_description => 
-    &mt('Prepare reports on survey results.'),
-                 },
-                   { internal_name => 'correct_problems_plot',
-                     name => &mt('Correct Problems Plot'),
-                     short_description => 
-    &mt('Display a histogram of student performance in the course.'),
-                 },
-#                   { internal_name => 'grading_analysis',
-#                     name => &mt('Detailed Grading Analysis'),
-#                     short_description => 
-#    &mt('Display statistics about who graded who.'),
-#                 },
-#                   { internal_name => 'student_assessment',
-#                     name => &mt('Problem Status Chart'),
-#                     short_description => 
-#    &mt('Brief view of each students performance in course.'),
-#                 },
-                   # 'percentage'  => 'Correct-problems Plot',
-                   # 'activitylog' => 'Activity Log',
-                   );
-    #
-    # Create the menu
-    my $Str;
-    $Str .= '<h2>'.&mt('Please select a report to generate').'</h2>';
-    foreach my $reportdata (@reports) {
-        $Str .='    <h3><a href="/adm/statistics?reportSelected='.
-            $reportdata->{'internal_name'}.'" >'.
-            $reportdata->{'name'}."</a></h3>\n";
-        $Str .= '    '.('&nbsp;'x8).$reportdata->{'short_description'}.
-            "\n";
+    my @reports = (
+	    {categorytitle => 'Statistics and Analyses',
+         items => [
+            {url => '/adm/statistics?reportSelected=problem_statistics',
+			 permission => 'F',
+             icon => 'document-open.png',
+             linktext => ('Overall Problem Statistics'),
+             linktitle => ('Student performance statistics on all problems.')},
+       
+            {url => '/adm/statistics?reportSelected=problem_analysis',
+			 permission => 'F',
+             icon => 'edit-find.png',
+             linktext => ('Detailed Problem Analysis'),
+             linktitle => ('Detailed statistics and graphs of student performance on problems.')},
+         ]},
+        {categorytitle => 'Plots',
+         items => [
+            {url => '/adm/statistics?reportSelected=submissiontime_analysis',
+			 permission => 'F',
+             icon => 'subtimpl.png',
+             linktext => ('Submission Time Plots'),
+             linktitle => ('Display and analysis of submission times on assessments.')},
+      
+            {url => '/adm/statistics?reportSelected=correct_problems_plot',
+			 permission => 'F',
+             icon => 'coprplot.png',
+             linktext => ('Correct Problems Plot'),
+             linktitle => ('Display a histogram of student performance in the course.')},
+         ]});
+    if (&Apache::loncommon::needs_gci_custom()) {
+        push(@reports,
+        {categorytitle => 'Reports',
+         items => [
+            {url => '/adm/statistics?reportSelected=student_submission_reports',
+                         permission => 'F',
+             icon => 'edit-copy.png',
+             linktext => ('Student Submission Reports'),
+             linktitle => ('Prepare reports of student submissions.')},
+         ]});
+    } else {
+        push(@reports,
+        {categorytitle => 'Reports',
+         items => [
+            {url => '/adm/statistics?reportSelected=student_submission_reports',
+			 permission => 'F',
+             icon => 'edit-copy.png',
+             linktext => ('Student Submission Reports'),
+             linktitle => ('Prepare reports of student submissions.')},
+                    
+            {url => '/adm/statistics?reportSelected=survey_reports',
+			 permission => 'F',
+             icon => 'docs.png',
+			 linktext => ('Survey Reports'),
+             linktitle => ('Prepare reports on survey results.')},
+         ]});
     }
-    $Str .="</dl>\n";
-    #
-    return $Str;
+    
+return &Apache::lonhtmlcommon::generate_menu(@reports);
+ 
 }
 
-##############################################
-##############################################
+
+
 sub handler {
     my $r=shift;
     my $c = $r->connection();
@@ -1138,6 +845,28 @@ sub handler {
     &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;
     if ($r->header_only) { return OK; }
+    my $gcicustom = &Apache::loncommon::needs_gci_custom();
+    if ($gcicustom) {
+        my $now = time;
+        my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+        my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+        my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
+        my $duedate = $courseopt->{$env{'request.course.id'}.'.0.duedate'};
+        if ((!$duedate) || ($duedate > $now)) {
+            $r->print(&Apache::loncommon::start_page("Course Statistics"));
+            $r->print('<h3>'.&mt('Display of statistics').'</h3>');
+            if ($duedate > $now) { 
+                $r->print('<p>'.&mt('Aggregate test performance data will be available after the Concept Test end date: [_1].',
+                         &Apache::lonlocal::locallocaltime($duedate)).'</p>');
+            } else {
+                $r->print('<p>'.
+                          &mt('Aggregate test performance data unavailable without definition of an end date for the Concept Test.').'</p>');
+            }
+            $r->print(&Apache::loncommon::end_page());
+            return OK;
+        }
+    }
+
     #
     # Extract form elements from query string
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
@@ -1173,15 +902,16 @@ ENDSTYLE
     #
         if (! &Apache::lonmysql::verify_sql_connection()) {
             my $serveradmin = $r->dir_config('lonAdmEMail');
-            $r->print('<h2><font color="Red">'.
+            $r->print('<h2 class="LC_error">'.
                       &mt('Unable to connect to database!').
-                      '</font></h2>');
-            $r->print('<p>'.
-                      &mt('Please notify the server administrator ').
-                      '<b>'.$serveradmin.'</b></p>');
+                      '</h2>');
+            $r->print('<p>'
+                     .&mt('Please notify the server administrator [_1]',
+                         ,'<b>'.$serveradmin.'</b>')
+                     .'</p>');
             $r->print('<p>'.
                       &mt('Course Statistics and Charts cannot be '.
-                          'retrieved until the database is restarted.  '.
+                          'retrieved until the database is restarted. '.
                           'Your data is intact but cannot be displayed '.
                           'at this time.').'</p>');
             $r->print(&Apache::loncommon::end_page());
@@ -1222,9 +952,9 @@ ENDSTYLE
             &Apache::lonsubmissiontimeanalysis::BuildSubmissionTimePage($r,$c);
         } elsif($GoToPage eq 'student_submission_reports') {
             &Apache::lonhtmlcommon::add_breadcrumb
-                ({href=>
-                  '/adm/statistics?reportselected=student_submission_reports',
-                  text=>'Student Submission Reports'});
+            ({href=>
+              '/adm/statistics?reportselected=student_submission_reports',
+              text=>'Student Submission Reports'});
             &Apache::lonstudentsubmissions::BuildStudentSubmissionsPage($r,$c);
         } elsif($GoToPage eq 'survey_reports') {
             &Apache::lonhtmlcommon::add_breadcrumb
@@ -1242,7 +972,11 @@ ENDSTYLE
             &Apache::lonhtmlcommon::add_breadcrumb
                 ({href=>'/adm/statistics?reportselected=student_assessment',
                   text=>'Chart'});
-            &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);
+            if ($gcicustom) {
+                $r->print(&mt('Only aggregate performance data are available for Concept Tests.'));  
+            } else {
+                &Apache::lonstudentassessment::BuildStudentAssessmentPage($r,$c);
+            }
         } elsif($GoToPage eq 'grading_analysis') {
             &Apache::lonhtmlcommon::add_breadcrumb
                 ({href=>'/adm/statistics?reportselected=grading_anaylsis',
@@ -1260,17 +994,227 @@ ENDSTYLE
 
 1;
 
-#######################################################
-#######################################################
+__END__
 
 =pod
 
+=head1 NAME
+
+lonstatistics
+
+=head1 SYNOPSIS
+
+Main handler for statistics and chart.
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+
+=head1 PACKAGE VARIABLES
+
+=over
+
+=item @FullClasslist The full classlist
+
+=item @Students The students we are concerned with for this invocation
+
+=item @Sections The sections available in this class
+
+=item @Groups The groups available in the class
+
+=item $curr_student The student currently being examined
+
+=item $prev_student The student previous in the classlist
+
+=item $next_student The student next in the classlist
+
 =back
 
-=cut
+=head1 SUBROUTINES
 
-#######################################################
-#######################################################
+=over
 
-__END__
+=item &clear_classlist_variables()
+
+undef the following package variables:
+
+=over 4
+
+=item * @FullClasslist
+
+=item * @Students
+
+=item * @Sections
+
+=item * @Groups
+
+=item * %StudentData
+
+=item * @StudentDataOrder
+
+=item * @SelectedStudentData
+
+=item * $curr_student
+
+=item * $prev_student
+
+=item * $next_student
+
+=back
+
+=item &PrepareClasslist()
+
+Build up the classlist information.  The classlist information is kept in
+the following package variables:
+
+=over 4 
+
+=item * @FullClasslist
+
+=item * @Students
+
+=item * @Sections
+
+=item * @Groups 
+
+=item * %StudentData
+
+=item * @SelectedStudentData
+
+=item * $curr_student
+
+=item * $prev_student
+
+=item * $next_student
+
+=back
+
+$curr_student, $prev_student, and $next_student may not be defined, depending
+upon the calling context.
+
+=item get_selected_sections()
+
+Returns an array of the selected sections
+
+=item get_selected_groups()
+                                                                                    
+Returns an array of the selected groups
+
+=item &section_and_enrollment_description()
+
+Returns a string describing the currently selected section(s), group(s) and 
+access status.  
+
+Inputs: mode = 'plaintext' or 'localized'  (defaults to 'localized')
+    'plaintext' is used for example in Excel spreadsheets.
+Returns: scalar description string.
+
+=item section_or_group_text()
+
+=item get_students()
+
+Returns a list of the selected students
+
+=item &current_student()
+
+Returns a pointer to a hash containing data about the currently
+selected student.
+
+=item &previous_student()
+
+Returns a pointer to a hash containing data about the student prior
+in the list of students.  Or something. 
+
+=item &next_student()
+
+Returns a pointer to a hash containing data about the next student
+to be viewed. 
+
+=item &StudentDataSelect($elementname,$status,$numvisible,$selected)
+
+Returns html for a selection box allowing the user to choose one (or more) 
+of the fields of student data available (fullname, username, id, section, etc)
+
+=over 4
+
+=item * $elementname The name of the HTML form element
+
+=item * $status 'multiple' or 'single' selection box
+
+=item * $numvisible The number of options to be visible
+
+=back
+
+=item &get_selected_maps($elementname)
+
+Input: Name of the <select> form element used to specify the maps.
+
+Returns: Array of symbs of selected maps or the description 'all'.
+   If form.$elementname does not exist, 'all' is returned.
+
+=item &selected_sequences_with_assessments()
+
+Retrieve the sequences which were selected by the user to show.  
+
+Input: $mode: scalar.  Either 'selected' or 'all'.  If not specified,
+    'selected' is used.
+
+Returns: an array containing a navmap object and navmap resources, 
+    or an array containing a scalar with an error message.
+
+=item &map_select($elementname,$status,$numvisible,$restriction) 
+
+Returns html for a selection box allowing the user to choose one (or more) 
+of the sequences in the course.  The values of the sequences are the symbs.
+If the top sequence is selected, the value 'top' will result.
+
+=over 4
+
+=item * $elementname The name of the HTML form element
+
+=item * $status 'multiple' or 'single' selection box
+
+=item * $numvisible The number of options to be visible
+
+=back
+
+=item &SectionSelect($elementname,$status,$numvisible) 
+
+Returns html for a selection box allowing the user to choose one (or more) 
+of the sections in the course.  
+
+Uses the package variables @Sections
+
+=over 4
+
+=item * $elementname The name of the HTML form element
+
+=item * $status 'multiple' or 'single' selection box
+
+=item * $numvisible The number of options to be visible
+
+=back
+
+=item &GroupSelect($elementname,$status,$numvisible)
+                                                                                    
+Returns html for a selection box allowing the user to choose one (or more)
+of the groups in the course.
+                                                                                    
+Uses the package variables @Groups
+
+=over 4
+                                                                                    
+=item * $elementname The name of the HTML form element
+                                                                                    
+=item * $status 'multiple' or 'single' selection box
+                                                                                    
+=item * $numvisible The number of options to be visible
+                                                                                    
+=back
+
+=item CreateMainMenu()
+
+=back
+
+=cut