File:  [LON-CAPA] / loncom / interface / loncoursegroups.pm
Revision 1.4: download - view: text, annotated - select for diffs
Tue Nov 22 00:01:41 2005 UTC (18 years, 5 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_1_X, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_0_99_1, HEAD
Modify lonnet::get_coursegroups() to return a hash for consistency with other lonnet routines, and move sanity checking functionality to loncommon::coursegroups. Additional routines in lonnet to find out about groups.  Some fix-ups to loncoursegroups.pm

#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA 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.
#
# LON-CAPA 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 LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#

package Apache::loncoursegroups;

use strict;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonhtmlcommon;
use Apache::lonlocal;
use Apache::lonnavmaps;
use Apache::Constants qw(:common :http);

sub handler {
    my ($r) = @_;

    &Apache::loncommon::content_type($r,'text/html');
    $r->send_http_header;
                                                                                
    if ($r->header_only) {
        return OK;
    }

    #  Needs to be in a course
    if (! ($env{'request.course.fn'})) {
        # Not in a course
        $env{'user.error.msg'}=
     "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
        return HTTP_NOT_ACCEPTABLE;
    }

    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                            ['action','refpage']);
                                                                                      
    my $function = &Apache::loncommon::get_users_function();
    my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
    my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};

    my $view_permission =
          &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
    my $manage_permission =
          &Apache::lonnet::allowed('mdg',$env{'request.course.id'});

    &Apache::lonhtmlcommon::clear_breadcrumbs();

    my %functions = (
                      email => 'E-mail',
                      discussion => 'Discussion boards',
                      chat => 'Chat',
                      files => 'File repository',
                      roster => 'Membership roster',
                      homepage => 'Group home page',
                    );

    my %idx = ();
    $idx{id} = &Apache::loncoursedata::CL_ID();
    $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
    $idx{udom} = &Apache::loncoursedata::CL_SDOM();
    $idx{uname} = &Apache::loncoursedata::CL_SNAME();

    my $action = $env{'form.action'};
    if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
        if ($view_permission || $manage_permission) {
            &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
                        \%functions,\%idx,$view_permission,$manage_permission);
        } else {
            $r->print('You do not have group administration '.
                      'privileges in this course');
        }
    } else {
        &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,
                                          $view_permission,$manage_permission);
    }
    return OK;
}

sub print_main_menu {
    my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
                                                          $manage_permission)
                                                                          = @_;
    $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'),
                                                 undef,undef,undef,$function));
    &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>"/adm/coursegroups",
          text=>"Course Groups",});
    $r->print(&Apache::lonhtmlcommon::breadcrumbs
                (undef,'Course Groups'));
    &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                          $view_permission,$manage_permission);
    $r->print(&footer());
    return;
}

sub display_groups {
    my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
                                                          $manage_permission) = @_;
    my %curr_groups = ();
    my %grp_info = ();
    my $rowColor1 = "#dddddd";
    my $rowColor2 = "#eeeeee";

    $r->print('<br /><br />');
    if ($view_permission) {
        my %curr_groups;
        if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
            $r->print(&Apache::lonhtmlcommon::start_pick_box());
            $r->print(<<"END");
      <table border="0" cellpadding="4" cellspacing="1">
       <tr bgcolor="$tabcol" align="center">
        <td><b>Action</b></td>
        <td><b><a href="javascript:changeSort('groupname')">Group Name</a></b></td>
        <td><b><a href="javascript:changeSort('description')">Description</a></b></td>
        <td><b><a href="javascript:changeSort('creator')">Creator</a></b>
        </td>
        <td><b><a href="javascript:changeSort('creation')">Created</a></b>
        </td>
        <td><b><a href="javascript:changeSort('modified')">Last Modified</a></b>
        </td>
        <td><b>Functionality</b>
        </td>
        <td><b><a href="javascript:changeSort('quota')">Quota (Mb)</a></b></td>
        <td><b><a href="javascript:changeSort('totalmembers)">Members</a></b></td>
        <td><b><a href="javascript:changeSort('totalfiles')">Files</a></b></td>
        <td><b><a href="javascript:changeSort('boards')">Discussion boards</a></b></td>
        <td><b><a href="javascript:changeSort('diskuse')">Disk use</a></b></td>
       </tr>
END
            my %Sortby = ();
            foreach my $group (sort(keys(%curr_groups))) {
                %{$grp_info{$group}} = 
                                  &Apache::loncommon::get_group_settings(
                                                         $curr_groups{$group});
                my $members_result = &group_members($cdom,$cnum,$group,\%grp_info);
                my $files_result = &group_files($group,\%grp_info); 
                if ($env{'form.sortby'} eq 'groupname') {
                    push(@{$Sortby{$group}},$group);
                } elsif ($env{'form.sortby'} eq 'description') {
                    push(@{$Sortby{$grp_info{$group}{'description'}}},
                                                                     $group);
                } elsif ($env{'form.sortby'} eq 'creator') {
                    push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);
                } elsif ($env{'form.sortby'} eq 'creation') {
                    push(@{$Sortby{$grp_info{$group}{'creation'}}},$group);
                } elsif ($env{'form.sortby'} eq 'modified') {
                    push(@{$Sortby{$grp_info{$group}{'modified'}}},$group);
                } elsif ($env{'form.sortby'} eq 'quota') {
                    push(@{$Sortby{$grp_info{$group}{'quota'}}},$group);
                } elsif ($env{'form.sortby'} eq 'totalmembers') {
                    push(@{$Sortby{$grp_info{$group}{'totalmembers'}}},
                                                                       $group);
                } elsif ($env{'form.sortby'} eq 'totalfiles') {
                    push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},
                                                                       $group);
                } elsif ($env{'form.sortby'} eq 'boards') {
                    push(@{$Sortby{$grp_info{$group}{'boards'}}},$group);
                } elsif ($env{'form.sortby'} eq 'diskuse') {
                    push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group);
                } else {
                    push(@{$Sortby{$group}},$group);
                }
            }
            my $rowNum = 0;
            my $rowColor;
            foreach my $key (sort(keys(%Sortby))) {
                foreach my $group (@{$Sortby{$key}}) {
                    if ($rowNum %2 == 1) {
                        $rowColor = $rowColor1;
                    } else {
                        $rowColor = $rowColor2;
                    }
                    my $description = 
                   &Apache::lonnet::unescape($grp_info{$group}{'description'});
                    my $creator = $grp_info{$group}{'creator'};
                    my $creation = $grp_info{$group}{'creation'};
                    my $modified = $grp_info{$group}{'modified'}; 
                    my $quota = $grp_info{$group}{'quota'};
                    my $totalmembers = $grp_info{$group}{'totalmembers'};
                    my $totalfiles = $grp_info{$group}{'totalfiles'};
                    my $boards = $grp_info{$group}{'boards'};
                    my $diskuse = $grp_info{$group}{'diskuse'};
                    my $functionality;
                    foreach my $tool (sort keys(%{$functions})) {
                        if (defined($grp_info{$group}{functions}{$tool})) {
                            $functionality .= ' '.$tool;
                        }
                    }
                    if (!$functionality) {
                        $functionality = 'None available';
                    }
                    $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
   <a href="/adm/'.$cdom.'/'.$cnum.'/'.$group.'/grppg?register=1"/>View</a>&nbsp;<a href="/adm/coursegroups?action=modify&group='.$group.'">Modify</a></td><td><small>'.$group.'</small></td><td><small>'.$description.'</small></td><td><small>'.$creator.'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($creation).'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($modified).'</small></td><td><small>'.$functionality.'</small></td><td><small>'.$quota.'</small></td><td><small>'.$totalmembers.'</small></td><td><small>'.$totalfiles.'</small></td><td><small>'.$boards.'</small></td><td><small>'.$diskuse.'</small></td></tr>');
                    $rowNum ++;
                }
            }
            $r->print('</table>');
            $r->print(&Apache::lonhtmlcommon::end_pick_box());
        } else {
            $r->print('No groups exist');
        }
    } else {
        my @coursegroups = split(/:/,$env{'request.course.groups'});
        if (@coursegroups > 0) {
            my %curr_groups;
            if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
                foreach my $group (@coursegroups) {
                    my %group_info =  &Apache::loncommon::get_group_settings(
                                                   $curr_groups{$group});
                    my $description = &Apache::lonnet::unescape(
                                                     $group_info{description});
                    my ($uname,$udom) = split(/:/,$group_info{creator});
                    $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
                }
            }
        } else {
            $r->print('You are not currently a member of any active groups in this course');
        }
    }
    return;
}

sub group_administration {
    my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                     $view_permission,$manage_permission) = @_;
    my %sectioncount = ();
    my @tools = ();
    my @types = ();
    my @roles = ();
    my @sections = ();
    my %users = ();
    my %userdata = ();
    my @members = ();
    my %usertools = ();

    my $state = $env{'form.state'};
    my ($groupname,$description,$startdate,$enddate);

    if ($action eq 'create') {
        if ($state eq '') {
            $state = 'pick_name';
        } else {
            ($startdate,$enddate) = &get_dates_from_form();
            if (defined($env{'form.groupname'})) {
                $groupname = $env{'form.groupname'};
            }
            if (defined($env{'form.description'})) {
                $description = $env{'form.description'};
            }
            if (defined($env{'form.tool'})) {
                @tools=&Apache::loncommon::get_env_multiple('form.tool');
            }
            if (defined($env{'form.member'})) {
                @members = &Apache::loncommon::get_env_multiple('form.member');
                foreach my $user (@members) {
                    %{$usertools{$user}} = ();
                }
            }
        }
    }

    my %toolprivs = ();
    %{$toolprivs{'email'}} = (
                                 sgm => 'Send group mail',
                                 sgb => 'Broadcast mail',
                             );
    %{$toolprivs{'discussion'}} =  (
                                     cgb => 'Create boards',
                                     pgd => 'Post',
                                     pag => 'Anon. posts',
                                     rgi => 'Get identities', 
                                     vgb => 'View boards',
                                   );
    %{$toolprivs{'chat'}} =  (
                                pgc => 'Chat',
                             );
    %{$toolprivs{'files'}} =  (
                                 rgf => 'Retrieve',
                                 ugf => 'Upload',
                                 dgf => 'Delete',
                              );
    %{$toolprivs{'roster'}} = (
                                 vgm => 'View',
                              );
    %{$toolprivs{'homepage'}} = (
                                vgh => 'View page',
                                mgh => 'Modify page',
                              );
    my %fixedprivs = ();
    %{$fixedprivs{'email'}} = ('sgm' => 1);
    %{$fixedprivs{'discussion'}} = ('vgb' => 1);
    %{$fixedprivs{'chat'}} = ('pgc' => 1);
    %{$fixedprivs{'files'}} = ('rgf' => 1);
    %{$fixedprivs{'roster'}} = ('vgm' => 1);
    %{$fixedprivs{'homepage'}} = ('vgh' => 1);

    my %elements = ();
    %{$elements{'create'}} = ();
    %{$elements{'modify'}} = ();
    %{$elements{'create'}{'pick_name'}} = (
        startdate_month => 'selectbox',
        startdate_hour => 'selectbox',
        enddate_month => 'selectbox',
        enddate_hour => 'selectbox',
        types => 'selectbox',
        roles => 'selectbox',
        startdate_day => 'text',
        startdate_year => 'text',
        startdate_minute => 'text',
        startdate_second => 'text',
        enddate_day => 'text',
        enddate_year => 'text',
        enddate_minute => 'text',
        enddate_second => 'text',
        groupname => 'text',
        description => 'text',
        tool => 'checkbox',
        granularity => 'radio',
        no_end_date => 'checkbox',
    );
    %{$elements{'create'}{'pick_members'}} = (
        member => 'checkbox',
    );
    if (($action eq 'create') && ($state eq 'pick_name')) {
        my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,
                           \%sectioncount);
        if ($numsections > 0) {
            $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
        }
    }
                                                                                      
    if (($action eq 'create') && (($state eq 'pick_members') ||
                                  ($state eq 'pick_privs'))) {
        if (defined($env{'form.types'})) {
            @types=&Apache::loncommon::get_env_multiple('form.types');
        }
        if (defined($env{'form.roles'})) {
            @roles=&Apache::loncommon::get_env_multiple('form.roles');
        }
        if (defined($env{'form.sectionpick'})) {
            @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
            if (grep/^_all$/,@sections) {
                @sections = sort {$a cmp $b} keys(%sectioncount);
            }
        }
        &build_members_list($cdom,$cnum,\@types,\@roles,
                        \@sections,\%users,\%userdata);
        if ((keys(%users) > 0) && (@tools > 0)) {
            foreach my $tool (@tools) {
                if ($env{'form.granularity'} eq 'Yes') {
                    $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox';
                }
            }
            $elements{'create'}{'pick_members'}{'specificity'} = 'radio';
        }
    }

    if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') &&
         ($env{'form.specificity'} eq 'No')))) {
        foreach my $tool (@tools) {
            my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);
            foreach my $user (@values) {
                unless(exists($usertools{$user}{$tool})) {
                    $usertools{$user}{$tool} = 1;
                }
            }
        }
        if (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) {
            foreach my $member (@members) {
                foreach my $tool (keys(%{$usertools{$member}})) {
                    foreach my $priv (keys(%{$toolprivs{$tool}})) {
                        unless (exists($fixedprivs{$tool}{$priv})) {
                            $elements{'create'}{'pick_privs'}{'userpriv_'.$priv} =
                                                                   'checkbox';
                        }
                    }
                }
            }
        }
    }
 
    my $jscript;
    if ($env{'form.action'} eq 'create') {
        $jscript = &Apache::loncommon::check_uncheck_jscript();
    }
    $jscript .= qq|
function nextPage(formname,nextstate) {
    formname.state.value= nextstate;
    formname.submit();
}
function backPage(formname,prevstate) {
    formname.state.value = prevstate;
    formname.submit();
}
                                                                                      
|;
                                                                                      
    $jscript .= &Apache::lonhtmlcommon::set_form_elements(
                           \%{$elements{$action}{$state}});


    my $loaditems =  &onload_action($action,$state);
    $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'),
                               $jscript,$action,$state,$function,$loaditems));

    if ($env{'form.refpage'} eq 'enrl') {
        &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>"/adm/dropadd",
          text=>"Enrollment Manager",
          faq=>9,bug=>'Instructor Interface',});
    } else {
        &Apache::lonhtmlcommon::add_breadcrumb
       ({href=>"/adm/coursegroups",
          text=>"Course Groups",
          faq=>9,bug=>'Instructor Interface',});
    }

    my %states = ();
    @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
    @{$states{'modify'}} = ();
                                                                                      
    my %trail = ();
    %{$trail{'create'}} = (
                            pick_name => 'Group Settings',
                            pick_members => 'Select Members',
                            pick_privs => 'Choose Privileges',
                            result => 'Creation Complete',
                          );
    %{$trail{'modify'}} = ();
                                                                                      
    if ((($action eq 'create') || ($action eq 'modify')) &&
              ($manage_permission)) {
        for (my $i=0; $i<@{$states{$action}}; $i++) {
            if ($state eq $states{$action}[$i]) {
                &Apache::lonhtmlcommon::add_breadcrumb(
                   {text=>"$trail{$action}{$state}"});
                $r->print(&Apache::lonhtmlcommon::breadcrumbs
                     (undef,'Course Groups Manager'));
                &display_control($r,$cdom,$cnum,$tabcol,$action,$state,
                         \%sectioncount,$groupname,$description,$functions,
                         \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,
                         \%users,\%userdata,$idx,\@members,\%usertools);
                last;
            } else {
                if ($state eq 'result' && $i > 0) {
                    &Apache::lonhtmlcommon::add_breadcrumb(
    {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
      text=>"$trail{$action}{$states{$action}[$i]}"});
                } else { 
                    &Apache::lonhtmlcommon::add_breadcrumb(
     {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
      text=>"$trail{$action}{$states{$action}[$i]}"});
                }
            }
        }
    } elsif (($action eq 'view') && ($view_permission)) {
                        &Apache::lonhtmlcommon::add_breadcrumb(
                   {text=>"View groups"});
        $r->print(&Apache::lonhtmlcommon::breadcrumbs
                     (undef,'Course Groups Manager'));
        &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
                                        $view_permission,$manage_permission);

    }
    $r->print(&footer());
    return;
}

sub display_control {
    my ($r,$cdom,$cnum,$tabcol,$action,$state,$sectioncount,$groupname,
        $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
                      $enddate,$users,$userdata,$idx,$members,$usertools) = @_;
    if ($action eq 'create') {
        if ($state eq 'pick_name') {
            &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions,
                                                                $sectioncount);
        } elsif ($state eq 'pick_members') {
            &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname,
                                  $description,$startdate,$enddate,$tools,
                                             $functions,$users,$userdata,$idx);
        } elsif ($state eq 'pick_privs') {
            &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate,
                           $enddate,$tools,$functions,$toolprivs,$fixedprivs,
                                           $userdata,$members,$usertools,$idx);
        } elsif ($state eq 'result') {
            &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname,
                            $description,$userdata,$startdate,$enddate,$tools,
                               $functions,$toolprivs,$members,$usertools,$idx);
        }
    }
}

sub header {
    my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_;
    my $html=&Apache::lonxml::xmlbegin();
    my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems);
    my $output = <<"END";
$html
<head>
<title>$title</title>
<script type="text/javascript">
$jscript
</script>
</head>
$bodytag
<form method="post" name="$state">

END
    if ($action eq 'create' || $action eq 'modify') {
        $output .= <<"END";
 <input type="hidden" name="action" value="$action" />
 <input type="hidden" name="state" value="" />
 <input type="hidden" name="origin" value="$state" />
END
    }
    return $output;
}

sub onload_action {
    my ($action,$state) = @_;
    my $loaditems;
    if ((defined($env{'form.origin'})) && ($action eq 'create') &&
                ($state eq 'pick_name' || $state eq 'pick_members' || 
                 $state eq 'pick_privs')) {
        unless ($env{'form.origin'} eq '') {
            $loaditems = 
             'onload="javascript:setFormElements(document.'.$state.')"';
        }
    }
    return $loaditems;
}

sub footer {
       return(<<ENDFOOT);
  </form>
 </body>
</html>
ENDFOOT
}

sub build_members_list {
    my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_;
    my %access = ();
    foreach my $role (@{$roles}) {
        %{$$users{$role}} = ();
    }
    foreach my $type (@{$types}) {
        $access{$type} = $type;
    }
    &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles,
                                          $sections,$users,$userdata);
    return;
}

sub group_files {
    return;
}

sub group_members {
    my ($cdom,$cnum,$group,$group_info) = @_;
    my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
    my $now = time;
    my ($tmp)=keys(%memberhash);
    if ($tmp=~/^error:/) {
        $$group_info{'totalmembers'} = 'Unknown - an error occurred';
        return $tmp;
    }
    my $now = time;
    my $totalmembers = 0;
    my $active = 0;
    my $previous = 0;
    my $future = 0;
    foreach my $member (keys %memberhash) {
        $totalmembers ++;
        my ($end,$start) = split(/:/,$memberhash{$member});
        if (($end!=0) && ($end<$now)) {
            $previous ++;
        } elsif (($start!=0) && ($start>$now)) {
            $future ++;
        } else {
            $active ++;
        }
    }
    if ($totalmembers == 0) {
        $$group_info{$group}{'totalmembers'} = 'None';
    } else {
        $$group_info{$group}{'totalmembers'} = $active.' - active<br />'.$previous.' -previous<br />'.$future.' -future';
    }
    return 'ok';
}


sub first_creation_form {
    my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_;
    my %lt = &Apache::lonlocal::texthash(
        'gmem' => 'Group membership options',
        'picr' => 'Pick the criteria to use to build a list of course users '.
                  'from which you will select members of the new group',   
        'gdat' => 'Group open and close dates',
        'sten' => 'Set a start date/time and end date/time for the group',
        'acty' => 'Access types',
        'coro' => 'Course roles',
        'cose' => 'Course sections',
        'gfun' => 'Group functionality',
    );

    my %status_types = (
                   active => &mt('Currently has access'),
                   previous => &mt('Previously had access'),
                   future => &mt('Will have future access'),
                   );

    my @roles = ('st','cc','in','ta','ep','cr');

    my $starttime = time;
    my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
    my ($start_table,$end_table) = &date_setting_table
                                    ($starttime,$endtime,$formname);

    my @sections = ();
    my $section_sel = '';
    my $numvisible = 4;

    @sections = sort {$a cmp $b} keys(%{$sectioncount});
    if (@sections > 0) {
        unshift(@sections,'_all'); # Put 'all' at the front of the list
        if (@sections < 4) {
            $numvisible = @sections;
        }
        foreach (@sections) {
            if ($_ eq '_all') {
                $section_sel .= '  <option value="'.$_.'" />all sections'."\n";
            } else {
                $section_sel .= '  <option value="'.$_.'" />'.$_."\n";
            }
        }
    }

    $r->print(<<"END");
 <br />
 <table width="100%" cellpadding="0" cellspacing="0" border="0">
   <tr bgcolor="$tabcol">
     <td>&nbsp;</td>
     <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step1.gif" 
         valign="bottom">&nbsp;&nbsp;</nobr>
     </td>
     <td align="left"><nobr>
       <font face="arial,helvetica,sans-serif"><b>Group name, description
         and available functionality</b></font></nobr> 
     </td>
     <td width="100%">&nbsp;</td>
   </tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td colspan="3">
     <table border="0" cellpadding="2" cellspacing="2">
      <tr>
       <td><b>Group Name:</b></td>
       <td colspan="5"><input type="text" name="groupname" size="25" />
       </td>
      <tr>
      <tr>
       <td><b>Description:</b></td>
       <td colspan="5"><input type="text" name="description" size="40" />
       </td>
      <tr>
      <tr>
       <td><b>Functionality:</b></td>
END
    my $numitems = keys(%{$functions});
    my $halfnum = int($numitems/2);
    my $remnum = $numitems%2;
    if ($remnum) {
        $halfnum ++;
    }
    my @allfunctions = sort (keys (%{$functions}));
    for (my $i=0; $i<$halfnum; $i++) {
        $r->print('<td><input type="checkbox" name="tool" value="'.
                  $allfunctions[$i].'" />&nbsp;'.
                   $$functions{$allfunctions[$i]}.'</td>
                   <td>&nbsp;</td><td>&nbsp;</td>');
    }
    $r->print('<td><input type="button" value="check all" '.
              'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.
              '</td></tr><tr><td>&nbsp;</td>');
    for (my $j=$halfnum; $j<@allfunctions; $j++) {
        $r->print('<td><input type="checkbox" name="tool" value="'.
                  $allfunctions[$j].'" />&nbsp;'.
                  $$functions{$allfunctions[$j]}.'</td>
                  <td>&nbsp;</td><td>&nbsp;</td>');
    }
    if ($remnum) {
        $r->print('<td>&nbsp;</td>');
    }
    $r->print(<<"END"); 
       <td>
        <input type="button" value="uncheck all" 
          onclick="javascript:uncheckAll(document.$formname.tool)" />
       </td>
      </tr>
      <tr>
       <td><b>Granularity:</b></td>
       <td colspan="9">Do you want to assign different functionality to different group members?&nbsp;<input type="radio" name="granularity" value="Yes" />Yes&nbsp;<input type="radio" name="granularity" value="No" checked="checked" />No</td>
      </tr> 
     </table>
    </td>
   </tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr bgcolor="$tabcol">
    <td>&nbsp;</td>
    <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step2.gif" 
        valign="bottom">&nbsp;&nbsp;</nobr>
    </td>
    <td align="left"><nobr>
      <font face="arial,helvetica,sans-serif"><b>Start and end dates for group
                                                  access</b></font></nobr>
    </td>
    <td width="100%">&nbsp;</td>
   </tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td colspan="3">$start_table</td>
   <tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td colspan="3">$end_table</td>
   <tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr bgcolor="$tabcol">
    <td>&nbsp;</td>
    <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step3.gif" 
        valign="bottom">&nbsp;&nbsp;</nobr>
    </td>
    <td align="left"><nobr>
     <font face="arial,helvetica,sans-serif"><b>Pick parameters to generate 
         membership list</b></nobr>
     </font>
    </td>
    <td width="100%">&nbsp;</td>
   </tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td colspan="3">
     <b>$lt{'gmem'}</b><br/> $lt{'picr'}
     <br /><br />
     <table border="0">
      <tr>
       <td><b>$lt{'acty'}</b></td>
       <td>&nbsp;</td>
       <td><b>$lt{'coro'}</b></td>
END
    if (@sections >0) {
         $r->print('
       <td>&nbsp;</td>
       <td><b>'.$lt{'cose'}.'</b></td>
       <td>&nbsp;</td>');
    }
    $r->print('</tr><tr>');
    $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
    $r->print('<td>&nbsp;</td>');
    $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
    if (@sections > 0) {
        $r->print('
       <td>&nbsp;</td>
       <td colspan="3" align="center" valign="top">
        <select name="sectionpick" multiple="true" size="'.$numvisible.'">
          '.$section_sel.'
        </select>
       </td>');
    }
    $r->print('
      </tr>
     </table>
    </td>
   </tr>
   <tr>
    <td colspan="4">&nbsp;</td>
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td colspan="3" align="left">
     <input type="button" value="Go to next step"  
     onclick="javascript:nextPage(document.'.$formname.','."'pick_members'".')>
    </td>
   </tr>
</table>
');
    return;
}

sub second_creation_form {
    my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$startdate,
                        $enddate,$tools,$functions,$users,$userdata,$idx) = @_;
    my @regexps = ('user_','userpriv_');
    $r->print(&Apache::lonhtmlcommon::echo_form_input(
                ['origin','action','state','member','specificity'],\@regexps));
    my %sectioncount = ();
    my $numsec = &Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);
    my %curr_groups;
    my $numgroups =  &Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
    my $earlyout;
    my $exitmsg = '<b>Invalid group name</b><br /><br />The group name entered "'.
                  $groupname.'" ';
    my $dupmsg = 'Group names and section names used in a course must be unique.'; 
    if ($groupname =~ /\W/) {
        $earlyout = $exitmsg.'is not a valid name.<br />Group names may only contain letters, numbers or underscores';
    }
    if ($numsec) {
        if (exists($sectioncount{$groupname})) {
            $earlyout = $exitmsg.'can not be used as it is the name of a '.
                                 'section in this course.<br />'.$dupmsg;
        }
    }
    if ($numgroups) {
        if (exists($curr_groups{$groupname})) {
            $earlyout = $exitmsg.'can not be used as it is the name of an 
                                 existing group in this course.<br />'.$dupmsg;
        }
    }
    if ($earlyout) {
        $r->print('<table border="0" cellpadding="2" cellspacing="2">
 <tr>
  <td>&nbsp;</td>
  <td>'.$earlyout.'</td>
 </tr>
 <tr>
  <td colspan="2">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td align="left">
   <input type="button" name="previous" value = "Go to previous page"
    onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
  </td>
 </tr>
</table>
        ');
        return;
    }
    my $rowColor1 = "#dddddd";
    my $rowColor2 = "#eeeeee";
    my $showstart = &Apache::lonlocal::locallocaltime($startdate);
    my $showend = &Apache::lonlocal::locallocaltime($enddate);
    $r->print('<table border="0" cellpadding="0" cellspacing="20">
<tr>
 <td><font face="arial,helvetica,sans-serif"><b>New group selections</b></font>
<br />When you create the new group, the following settings will apply:
 </td>
</tr>
<tr>
 <td>');
    $r->print(&Apache::lonhtmlcommon::start_pick_box());
    $r->print('
<table cellspacing="1" cellpadding="4">
 <tr bgcolor="'.$tabcol.'" align="center">
  <td><b>Group Name</b></td>
  <td><b>Description</b></td>
  <td><b>Group Functionality</b></td>
  <td><b>Default access dates</b></td>
 </tr>
 <tr bgcolor="'.$rowColor2.'">
  <td valign="top"><small>'.$groupname.'</small></td>
  <td valign="top"><small>'.$description.'</small></td>
  <td>
');
    my @available = ();
    my @unavailable = ();
    foreach my $item (sort(keys(%{$functions}))) {
        if (grep/^$item$/,@{$tools}) {
            push(@available,$item);
        } else {
            push(@unavailable,$item);
        }
    }
    if (@available > 0) {
        $r->print('<small><b>Available:</b></small>
                    <table cellpadding="" cellspacing="1"><tr>');
        my $rowcell = int(@available/2) + @available%2;
        for (my $i=0; $i<@available; $i++) {
            if (@available > 3) {
                if ($i==$rowcell) {
                    $r->print('</tr><tr>');
                }
            }
            $r->print('<td><small>'.$$functions{$available[$i]}.
                                          '</small></td><td>&nbsp;</td>');
        }
        if ((@available > 3) && (@available%2)) {
            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
        }
        $r->print('</tr></table><br />');
    }
    if (@unavailable > 0) {
        $r->print('<small><b>Unavailable:</b></small>
                    <table cellpadding="0" cellspacing="1"  border="0"><tr>');
        my $rowcell = int(@unavailable/2) + @unavailable%2;
        for (my $j=0; $j<@unavailable; $j++) {
            if (@unavailable > 3) {
                if ($j==$rowcell) {
                    $r->print('</tr><tr>');
                }
            }
            $r->print('<td><small>'.$$functions{$unavailable[$j]}.
                                              '</small></td><td>&nbsp;</td>');
        }
        if ((@unavailable > 3) && (@unavailable%2)) {
            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
        }
        $r->print('</tr></table>');
    }
    $r->print(<<"END");
  </td>
  <td valign="top"><small><b>Start date:</b> $showstart<br />
      <b>End date:</b> $showend</small>
  </td>
 </tr>
</table>
END
    $r->print(&Apache::lonhtmlcommon::end_pick_box());
    my %members = ();
    foreach my $role (keys(%{$users})) {
        foreach my $user (keys(%{$$users{$role}})) {
            unless (defined($members{$user})) {
                @{$members{$user}} = @{$$userdata{$user}};
            }
        }
    }
    $r->print('</td></tr></table><br />');
    if (keys(%members) > 0) {
        if ($env{'form.granularity'} eq 'Yes') {
            $r->print('
<script type="text/javascript">
function checkAllTools(formname) {
');
            foreach my $tool (@available) {
                $r->print('  checkAll(formname.user_'.$tool.');'."\n");
            }
            $r->print('
}
function uncheckAllTools(formname) {
');
            foreach my $tool (@available) {
                $r->print('  uncheckAll(formname.user_'.$tool.');'."\n");
            }
            $r->print('
}
</script>
            ');
       }
       $r->print(<<"END");
<table width="100%" cellpadding="0" cellspacing="0" border="0">
 <tr bgcolor="$tabcol">
  <td>&nbsp;</td>
  <td valign="top" align="left">
   <nobr><img src="/res/adm/pages/bl_step4.gif" valign="middle">&nbsp;</nobr>
  </td>
  <td alin="left">
   <nobr>
   <font face="arial,helvetica,sans-serif">
    <b>Select group members</b>
   </font></nobr>
  </td>
  <td width="100%">&nbsp;</td>
 </tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td colspan="2">
    <table>
     <tr>
      <td>
   <nobr>
    <fieldset><legend><b>Add members</b></legend>
     <input type="button" value="check all" 
       onclick="javascript:checkAll(document.$formname.member)" />
      &nbsp;&nbsp;
     <input type="button" value="uncheck all" 
      onclick="javascript:uncheckAll(document.$formname.member)" />
    </fieldset></nobr></td>
END
        if (@available > 0 && $env{'form.granularity'} eq 'Yes') {
            $r->print('<td><nobr><fieldset><legend><b> 
                                      Set functionality</b></legend>
     <input type="button" value="check all" 
       onclick="javascript:checkAllTools(document.'.$formname.')" />
       &nbsp;&nbsp;
     <input type="button" value="uncheck all" 
        onclick="javascript:uncheckAllTools(document.'.$formname.')" />
    </fieldset></nobr></td>');
        }
        $r->print('</tr></table>
  </td>
  <td width="100%">&nbsp;</td>
 </tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td colspan="3">
        ');
        $r->print(&Apache::lonhtmlcommon::start_pick_box());
        $r->print(<<"END");
   <table border="0" cellpadding="4" cellspacing="1">
    <tr bgcolor="$tabcol" align="center">
     <td><b>Add?</b></td>
     <td><b><a href="javascript:changeSort('fullname')">Name</a></b></td>
     <td><b><a href="javascript:changeSort('username')">Username</a></b>
     </td>
     <td><b><a href="javascript:changeSort('domain')">Domain</a></b></td>
     <td><b><a href="javascript:changeSort('id')">ID</a></b></td>
END
        if (@available > 0) {
            $r->print('<td><b>Functionality</b></td>');
        }
        $r->print('</tr>');
        my %Sortby = ();
        foreach my $user (sort(keys(%members))) {
            if ($env{'form.sortby'} eq 'fullname') {
                push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
            } elsif ($env{'form.sortby'} eq 'username') {
                push(@{$Sortby{$members{$user}[$$idx{uname}]}},$user);
            } elsif ($env{'form.sortby'} eq 'domain') {
                push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);
            } elsif ($env{'form.sortby'} eq 'id') {
                push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);
            } else {
                push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
            }
        }
        my $rowNum = 0;
        my $rowColor;
        foreach my $key (sort(keys(%Sortby))) {
            foreach my $user (@{$Sortby{$key}}) {
                if ($rowNum %2 == 1) {
                    $rowColor = $rowColor1;
                } else {
                    $rowColor = $rowColor2;
                }
                my $id = $members{$user}[$$idx{id}];
                my $fullname = $members{$user}[$$idx{fullname}];
                my $udom = $members{$user}[$$idx{udom}];
                my $uname = $members{$user}[$$idx{uname}];
                $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
   <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.
    $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
    $udom.'</small></td><td><small>'.$id.'</small></td>');
                if (@available > 0) {
                    $r->print('<td align="center"><small>'); 
                    foreach my $tool (@available) {
                        if ($env{'form.granularity'} eq 'Yes') {
                            $r->print('<input type="checkbox" name="user_'.
                          $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                        } else {
                            $r->print('<input type="hidden" name="user_'.
                          $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                        }
                    }
                    $r->print('</small></td>');
                }
                $r->print('</tr>'."\n");
                $rowNum ++;
            }
        }
        $r->print(&Apache::lonhtmlcommon::end_pick_box());
        $r->print('
  </td>
 </tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>');
        if (@available > 0) {
            $r->print('
 <tr bgcolor="'.$tabcol.'">
  <td>&nbsp;</td>
  <td valign="middle" align="left">
   <nobr><img src="/res/adm/pages/bl_step5.gif" valign="middle">&nbsp;</nobr>
  </td>
  <td align="left"><nobr>
   <font face="arial,helvetica,sans-serif">
    <b>User privileges</b>
   </font></nobr>
  </td>
  <td width="100%">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td colspan="3">
   <br />
   For each type of functionality you have chosen to include, there is a 
set of standard privileges which apply to all of those for whom the functionality is enabled.<br />There are also additional privileges which can be set for some, or all, members. Please choose one of the following:<br />
<br /><input type="radio" name="specificity" value="No" checked="checked" />&nbsp;All group members will receive the same privileges.<br/><input type="radio" name="specificity" value="Yes" />&nbsp;Some group members will receive different privileges from others.
  </td>
 </tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>
');
        }
        $r->print('    
 <tr>
  <td>&nbsp;</td>
  <td colspan="3">
   <input type="button" name="previous" value = "Go to previous page" 
    onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
   &nbsp;&nbsp;&nbsp;
   <input type="button" name="next" value="Go to next page" 
 onclick="javascript:nextPage(document.'.$formname.','."'pick_privs'".')" />
  </td>
 </tr>
        ');
    } else {
        $r->print('No members to add');
    }
    $r->print('
   </table>
  </td>
 </tr>
</table>');
    return;
}

sub third_creation_form {
    my ($r,$cdom,$cnum,$tabcol,$formname,$startdate,$enddate,$tools,$functions,
               $toolprivs,$fixedprivs,$userdata,$members,$usertools,$idx) = @_;
    my @regexps = ('userpriv_','allpriv_');
    $r->print(&Apache::lonhtmlcommon::echo_form_input(
                             ['origin','action','state'],\@regexps));
    my %possibles = ();
    my %showboxes = ();
    my $totalboxes = 0;
    my $rowColor1 = "#dddddd";
    my $rowColor2 = "#eeeeee";
    my $numtools = 1 + @{$tools};
    foreach my $tool (@{$tools}) {
        @{$showboxes{$tool}} = ();
        foreach my $user (@{$members}) {
            if (exists($$usertools{$user}{$tool})) {
                foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
                    unless (exists($$fixedprivs{$tool}{$priv})) {
                        push(@{$possibles{$user}},$priv);
                        unless(grep(/^$priv$/,@{$showboxes{$tool}})) {
                            push(@{$showboxes{$tool}},$priv);
                            $totalboxes ++;
                        }
                    }
                }
            }
        }
    }
    if ($totalboxes > 0) {
        $r->print('
<script type="text/javascript">
function checkAllTools(formname) {
');
        foreach my $tool (sort(keys(%showboxes))) {
            foreach my $priv (@{$showboxes{$tool}}) {
                $r->print('  checkAll(formname.userpriv_'.$priv.');'."\n");
            }
        }
        $r->print('
}
function uncheckAllTools(formname) {
');
        foreach my $tool (sort(keys(%showboxes))) {
            foreach my $priv (@{$showboxes{$tool}}) {
                $r->print('  uncheckAll(formname.userpriv_'.$priv.');'."\n");
            }
        }
        $r->print('
}
</script>
       ');
   }
   $r->print(<<"END");
<br />
<table width="100%" cellpadding="0" cellspacing="0" border="0">
 <tr bgcolor="$tabcol">
  <td>&nbsp;</td>
  <td valign="middle" align="left">
   <nobr><img src="/res/adm/pages/bl_step6.gif" valign="middle">&nbsp;</nobr>
  </td>
  <th align="left"><nobr>
    Group member privileges
   </nobr>
  </th>
  <td width="100%">&nbsp;</td>
 </tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td colspan="3">
END
    if ($env{'form.specificity'} eq 'Yes') {
        $r->print('
   <table border="0" cellspacing="2" cellpadding="2" border="0">
    <tr>
     <td valign="top">
');
        $r->print(&Apache::lonhtmlcommon::start_pick_box());
        $r->print(<<"END");
   <tr bgcolor="$tabcol">
    <th><b>Fullname</th>
    <th><b>Username</th>
    <th>Domain</th>
    <th colspan="$numtools">Additional Privileges</th>
  </tr>
END
    }
    if ($env{'form.specificity'} eq 'Yes') {
        &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,
                             $usertools,$toolprivs,$fixedprivs,$userdata,$idx);
    }
    if ($env{'form.specificity'} eq 'Yes') {
        $r->print('</td>');
        $r->print(&Apache::lonhtmlcommon::end_pick_box());
        $r->print('<td>&nbsp;</td>
               <td>&nbsp;</td><td valign="top">');
        my @toolboxes = sort(keys(%showboxes));
        foreach my $tool (@{$tools}) {
            if (@{$showboxes{$tool}} > 0) { 
                $r->print('<table class="thinborder"><tr bgcolor="'.$tabcol.
                      '"><th>'.$tool.'</th></tr>');
                foreach my $priv (@{$showboxes{$tool}}) {
                    $r->print(qq|
       <tr><td>
       <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
       <input type="button" value="check all"
         onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />
       &nbsp; 
       <input type="button" value="uncheck all"
        onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
      </nobr></fieldset></td></tr>|);
                }
                $r->print('</table><br /><br />');
            }
        }
        $r->print('</td></tr></table>');
    } else {
        $r->print(&Apache::lonhtmlcommon::start_pick_box());
        $r->print('<tr><td bgcolor="'.$tabcol.'" valign="top"><table cellspacing="0" cellpadding="1"><tr><td valign="top"><b>Function</b></td></tr><tr><td valign="top"><b>Fixed privileges</b>'.
                  '</td></tr><tr><td valign="top"><b>Optional privileges</b></td></tr></table></td>');
        foreach my $tool (@{$tools}) {
            $r->print('<td align="center" valign="top"><table cellspacing="0" cellpadding="1"><tr bgcolor="#cccccc">'.
                       '<td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
            my $privcount = 0;
            my $fixed = '';
            my $dynamic = '';
            foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
                if (exists($$fixedprivs{$tool}{$priv})) {
                    $fixed .= '<input type="hidden" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
                } else {
                    $privcount ++;
                    if ($privcount == 3) {
                        $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'">';
                    }
                    $dynamic .= '<td><input type="checkbox" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'</td>';
                }
            }
            if ($dynamic eq '') {
                $dynamic = '<td>None</td>'; 
            }
            if ($privcount < 3) {
                $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'"><td colspan="2">&nbsp;</td>';
            } elsif ($privcount%2) {
                $dynamic = '<td>&nbsp;</td>';
            }
            $r->print('<tr bgcolor="'.$rowColor2.'"><td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td></tr><tr bgcolor="'.$rowColor1.'">'.$dynamic.'</tr></table></td>');
        }
        $r->print('</tr>');
        $r->print(&Apache::lonhtmlcommon::end_pick_box());
    }
    $r->print('</td></tr>
 <tr>
  <td colspan="4">&nbsp;</td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td colspan="3">
   <input type="button" name="previous" value = "Go to previous page"
    onclick="javascript:backPage(document.'.$formname.','."'pick_members'".')"/>
   &nbsp;&nbsp;
   <input type="button" name="next" value="Create group"
 onclick="javascript:nextPage(document.'.$formname.','."'result'".')" />
  </td>
 </tr>
    ');
    $r->print('
</table>');

    return;
}

sub completed_creation {
    my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$userdata,
$startdate,$enddate,$tools,$functions,$toolprivs,$members,$usertools,$idx) = @_;

    $r->print(&Apache::lonhtmlcommon::echo_form_input(
                                        ['origin','action','state']));
    my @added= ();
    my @failed = ();
    my $now = time;
    my %group_privs = ();
    my %tooltype = ();
    foreach my $tool (@{$tools}) {
        foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
            $tooltype{$priv} = $tool;
            if ($env{'form.specificity'} eq 'Yes') {
                my @users =
                  &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv);
                foreach my $user (@users) {
                    $group_privs{$user} .= $priv.':';
                }
            } else {
                if (defined($env{'form.allpriv_'.$priv})) {
                    foreach my $user (@{$members}) {
                        if ($$usertools{$user}{$tool}) {
                            $group_privs{$user} .= $priv.':';
                        }
                    }
                }
            }
        }
    }
    foreach my $user (keys(%group_privs)) {
        $group_privs{$user} =~ s/:$//;
    }
    my $esc_description = &Apache::lonnet::escape($description);
    my @attributes = ('description','functions','startdate','enddate','creation','modified','creator');
        
    my %groupinfo = (
                      description => $esc_description,
                      startdate => $startdate,
                      enddate => $enddate,
                      creation => $now,
                      modified => $now,
                      creator => $env{'user.name'}.':'.$env{'user.domain'}, 
                    );
    foreach my $func (keys(%{$functions})) {
        my $status;
        if (grep(/^$func$/,@{$tools})) {
            $status = 'on';
        } else {
            $status = 'off';
        } 
        $groupinfo{'functions'} .=  qq|<name id="$func">$status</name>|;
    }

    my %curr_groups = ();
    my %groupsettings = ();
    my %usersettings = ();
    if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum,$groupname)) {
        if (exists($curr_groups{$groupname})) {
            $r->print('Non-unique name - please choose another');
            return; 
        }
    }
    my $groupentry;
    foreach my $item (@attributes) {
        $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}</$item>|;
    }
    my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum,
                                                          \%groupsettings);
    if ($result eq 'ok') {
        my $put_result = &create_homepage($cdom,$cnum,$groupname,\%groupinfo,$tools);
        foreach my $user (sort(@{$members})) {
            $usersettings{$groupname.':'.$user} = $enddate.':'.$startdate.':'.$group_privs{$user};
            if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                  $user,$enddate,$startdate,$group_privs{$user}) eq 'ok') {
                push(@added,$user);
            } else {
                push(@failed,$user);
            }
        }
        my $roster_result = &Apache::lonnet::modify_coursegroup_membership(
             $cdom,$cnum,\%usersettings);
        $r->print('
Group '.$groupname.' was created.<br />');
        if (@added > 0) {
            $r->print('Users were added with following privileges:<br />');
            foreach my $user (@added) {
                my @privs = split(/:/,$group_privs{$user});
                my $privlist= '';
                my $curr_tool = '';
                foreach my $priv (@privs) {
                    unless ($curr_tool eq $tooltype{$priv}) {
                        $curr_tool = $tooltype{$priv};
                        $privlist .= '<b>'.$curr_tool.'</b>: ';
                    }
                    $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
                }
                $privlist =~ s/, $//;
                $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.': '.$privlist.'<br />');
            }
        }
        if (@failed > 0) {
            $r->print('Addition of the following users was unsuccessful:<br />');
            foreach my $user (@failed) {
                $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
            }
        }
        if ($roster_result eq 'ok') {
            $r->print('<br />Group membership list updated.');
        } else {
            $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');
        } 
    } else {
        &Apache::lonnet::logthis('Failed to create group '.$groupname. 
                                 'in course: '.$cnum.' in domain: '.$cdom);

        $r->print('An error occurred when creating the new group. '.
                                                      'Please try again.');
    }
    return;
}

sub member_privs_entries {
    my ($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,$usertools,$toolprivs,
                                              $fixedprivs,$userdata,$idx) = @_;
    my $rowColor;
    my $rowNum = 0;
    foreach my $member (@{$members}) {
        my ($uname,$udom) = split(/:/,$member);
        if ($rowNum %2 == 1) {
            $rowColor = $rowColor1;
        } else {
            $rowColor = $rowColor2;
        }
        $r->print('<tr bgcolor="'.$rowColor.'">
                <td>'.$$userdata{$member}[$$idx{fullname}].'</td>
                <td>'.$uname.'</td>
                <td>'.$udom.'</td>
                <td valign="top"><table><tr><td><b>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');
        foreach my $tool (@{$tools}) {
            if (exists($$usertools{$member}{$tool})) {
                $r->print('<td valign="top"><table><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
                my $privcount = 0;
                my $fixed = '';
                my $dynamic = '';
                foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
                    if (exists($$fixedprivs{$tool}{$priv})) {
                        $fixed .= '<input type="hidden" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
                    } else {
                        $privcount ++;
                        if ($privcount == 3) {
                            $dynamic .= '</tr><tr>';
                        }
                        $dynamic .= '<td><input type="checkbox" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'</td>';
                    }
                }
                $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
            } else {
                $r->print('<td>&nbsp;</td>');
            }
        }
        $rowNum ++;
    }
}


sub get_dates_from_form {
    my $startdate;
    my $enddate;
    $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
    $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
    if ( exists ($env{'form.no_end_date'}) ) {
        $enddate = 0;
    }
    return ($startdate,$enddate);
}                                                                                     
sub date_setting_table {
    my ($starttime,$endtime,$formname) = @_;
    my $startform = &Apache::lonhtmlcommon::date_setter($formname,
                                                      'startdate',$starttime);
    my $endform = &Apache::lonhtmlcommon::date_setter($formname,
                                                      'enddate',$endtime);
    my $perpetual = '<nobr><input type="checkbox" name="no_end_date" />
                                                  no ending date</nobr>';
    my $start_table = '';
    $start_table .= "<table>\n";
    $start_table .= '<tr><td align="right">Default starting date for 
                                           member access</td>'.
        '<td>'.$startform.'</td>'.
        '<td>&nbsp;</td>'."</tr>\n";
    $start_table .= "</table>";
    my $end_table = '';
    $end_table .= "<table>\n";
    $end_table .= '<tr><td align="right">Default ending date for 
                                         member access</td>'.
        '<td>'.$endform.'</td>'.
        '<td>'.$perpetual.'</td>'."</tr>\n";
    $end_table .= "</table>\n";
    return ($start_table, $end_table);
}

sub create_homepage {
    my ($cdom,$cnum,$name,$groupinfo,$tools) = @_;
    my $functionality = join(',',@{$tools});
    my $content = &Apache::lonnet::unescape($$groupinfo{description});
    $content=~s/\s+$//s;
    $content=~s/^\s+//s;
    $content=~s/\<br\s*\/*\>$//s;
    $content=&Apache::lonfeedback::clear_out_html($content,1);

    my %pageinfo = (
                     'aaa_title' => 'Group: '.$name,
                     'abb_links' => $functionality,
                     'bbb_content' => $content,
                     'ccc_webreferences' => '',
                     'uploaded.lastmodified' => time,
                   );
   my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);
   return $putresult;
}


1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>