#!/usr/local/bin/webwork-perl



## This file is profBuildProblemSetPage.pl
## It provides access to utilities for building problem sets
##

####################################################################
# Copyright @ 1995-1998 University of Rochester
# All Rights Reserved
####################################################################

use lib '.'; use webworkInit; # WeBWorKInitLine
use CGI qw(:standard);
use Global;
use Auth;
use strict;

# begin Timing code
use Benchmark;
my $beginTime = new Benchmark;
# end Timing code

my $cgi = new CGI;
my %inputs = $cgi->Vars();

# get information from CGI inputs  (see also below for additional information)

my $Course 		= $inputs{'course'};
my $User 		= $inputs{'user'};
my $Session_key 	= $inputs{'key'};

# verify that information has been received
unless($Course && $User && $Session_key) {
	&wwerror("$0","The script did not receive the proper input data.","","");
}

# establish environment for this script

&Global::getCourseEnvironment($inputs{'course'});


my $cgiURL   			= getWebworkCgiURL;
my $courseScriptsDirectory 	= getCourseScriptsDirectory;
my $databaseDirectory 		= getCourseDatabaseDirectory;
my $htmlURL       		= getCourseHtmlURL;
my $scriptDirectory   		= getWebworkScriptDirectory;
my $templateDirectory 		= getCourseTemplateDirectory;
my $dat				= getDat;
my $dd				= getDirDelim;

require "${scriptDirectory}$Global::DBglue_pl";
require "${scriptDirectory}$Global::FILE_pl";
require "${scriptDirectory}$Global::HTMLglue_pl";

# log access
&Global::log_info('', query_string);


my $permissionsFile = &Global::getCoursePermissionsFile($inputs{'course'});
my $permissions = &get_permissions($inputs{'user'}, $permissionsFile);
my $keyFile = &Global::getCourseKeyFile($inputs{'course'});
# my $defaultClasslistFile = getCourseClasslistFile($Course);

#verify session key
	&verify_key($inputs{'user'}, $inputs{'key'}, $keyFile, $inputs{'course'});

# verify permissions are correct
	if ($permissions != $Global::instructor_permissions ) {
		print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n";
		print &html_NO_PERMISSION;
		exit(0);
		}
# get the rest of the information from the submitted form
	# nothing further to get in this case

# print HTML text
print &htmlTOP("Build Problem Set Utilities");

# print navigation button
print $cgi->a( { -href=>"${cgiURL}login.pl?user=$User&key=$Session_key&course=$Course" },

                        $cgi->img({ #  -name=>'upImg',  # name is not an attribute of img
                                          -src=>"${Global::upImgUrl}",
                                          -align=>'right',
                                          -border=>'1',
                                          -alt=>'[Up]'
                                        })
                        ),
        $cgi->p;

print "\n",
        $cgi->hr, $cgi->br,
        "\n\n", $cgi->h3({ -align=>'left' }, "WeBWorK Housekeeping Utilities for $Course"), "\n",
        $cgi->p,
	"From this page, you can build a problem set, edit a set definition or header file, or 
	destroy and rebuild sets in one operation";

# build problem sets
print heading('Build', "1. Build Problem Sets for $Course"),
	$cgi->p, 	"Select the Set Definition file(s) to be used to build the set(s).  Note that
			by selecting multiple Set Definition files, you can build multiple sets at one time.  If you want to
			see lists of actions for individual students, select the appropriate button.  Note that some of these
			selections may return a lot of data.",
	$cgi->p,	"Building a set which already exists will not change any data for students already  in the set.  It
			will however add all new students to the set.\n",
	$cgi->startform(-action=>"${cgiURL}profBuildProblemSet.pl");
	
 ## find the available set definition files

	opendir SETDEFDIR, $templateDirectory or wweror($0,"Can't open directory $templateDirectory","","");
		my @allFiles = grep !/^\./, readdir SETDEFDIR;
	closedir  SETDEFDIR;

	## sort the files

	my @setDefFiles = grep /\.def$/, @allFiles;
	my @sortedNames = sort @setDefFiles;

	## print list of files
	my  $fileName;

	my ($ind,$label,$date,@stat);
	my %labels;
	for $ind (@sortedNames) {
		$fileName = "${templateDirectory}$ind";
			if (-e $fileName) {
				@stat = stat($fileName);
				$date = $stat[9];
				$date = formatDateAndTime($date);
				$date =~ s|\s*at.*||;
				$label = "  Last Changed $date";
			}
		$labels{$ind} = "$ind $label";
	}

print $cgi->popup_menu(-name=>'setDefinition', -size=>4, -multiple=>undef, -values=>\@sortedNames, -labels=>\%labels), "\n";

my %formatLabels = ();
%formatLabels = ('no_students'=>'Don\'t list actions for individual students', 'new_students'=>'List actions only for new students', 'all_students'=>'List actions for all students');

print $cgi->br, $cgi->radio_group(-name=>'outputFormat', -values=>['no_students','new_students','all_students'], -default=>'no_students', -linebreak=>'true', -labels=>\%formatLabels),
	$cgi->submit(-value=>'Build Problem Set(s)'), "\n",
	hiddens('user', 'key', 'course'),
	$cgi->hidden(-name=>'page', -value=>'build'), "\n",
	$cgi->hidden(-name=>'download', -value=>0), "\n",
	$cgi->hidden(-name=>'fileName', -value=>'blah'), "\n",
	$cgi->endform(), "\n",
	$cgi->p;

#edit set definition files
print heading('editSetDef', "2. Simple editing of $Course Set Definition files"),
	$cgi->startform(-action=>"${cgiURL}profEditCourseFiles.pl"),
	$cgi->submit(-value=>'Edit Set Definition File'), "\n", #join (",<BR>", @sortedNames), %labels,
	$cgi->popup_menu(-name=>'filename', -values=>\@sortedNames, -labels=>\%labels, -default=>$sortedNames[0]), "\n",
	hiddens('user', 'key', 'course'),
	$cgi->hidden(-name=>'ext', -value=>'def'), "\n",
	$cgi->endform(), "\n",
	$cgi->p, "This lets you edit set definition files which are used to build problem sets (by detailing due dates, problem filenames, etc).";

#edit set header files

## find the available set header files
## reuses most of the variable from the above set definition file search
	#opendir SETHEADDIR, $templateDirectory or wweror($0,"Can't open directory $templateDirectory","","");
	#	@allFiles = grep !/^\./, readdir SETHEADDIR;
	#closedir  SETHEADDIR;
	#my @setHeadFiles = grep /header.*\.pg$/i, @allFiles; #get all files containing 'header' that end in .pg
	
	# i should fix this so that it doesn't use find!
	my @setHeadFiles = `find $templateDirectory -name '*Header*.pg'`;
	for (my $i = 0; $i < @setHeadFiles; $i++) {
		$setHeadFiles[$i] =~ s/$templateDirectory//;
		chomp $setHeadFiles[$i];
	}
	@sortedNames = sort @setHeadFiles;

	## print list of files
	$fileName = '';

	($ind,$label,$date,@stat) = ('', '', '', ());
	%labels = ();
	for $ind (@sortedNames) {
		$fileName = "${templateDirectory}$ind";
			if (-e $fileName) {
				@stat = stat($fileName);
				$date = $stat[9];
				$date = formatDateAndTime($date);
				$date =~ s|\s*at.*||;
				$label = "  Last Changed $date";
			}
		$labels{$ind} = "$ind $label";
	}

print heading('editSetHead', "3. Simple editing of $Course Set Header files"),
	$cgi->startform(-action=>"${cgiURL}profEditCourseFiles.pl"),
	$cgi->submit(-value=>'Edit Set Header File'), "\n",
	$cgi->popup_menu(-name=>'filename', -values=>\@sortedNames, -labels=>\%labels, -default=>$sortedNames[0]), " (Must contain the word Header in the name)\n",
	hiddens('user', 'key', 'course'),
	$cgi->hidden(-name=>'ext', -value=>'pg'), "\n",
	$cgi->endform(), "\n",
	$cgi->p, "This lets you edit set header files which tend to come in two forms: screen set headers which are used for the opening page before viewing problems and paper set headers which are printed right before the problems in a paper copy of a problem set.";


if ( -e "${databaseDirectory}$Global::database" ) {
	print heading('DestroyRebuild', "4. Destroy and Rebuild Problem Sets for $Course."),
		$cgi->p, 	"Select the set(s) to destroy and rebuild.  Note that
				by selecting multiple sets, you can destroy and rebuild multiple sets at one time.  Note that
				destroying sets removes all associated data (and .sco files) from the database.
				The reconstructed sets will have problem with different psvn's and seeds and all scoring
				information will be removed from the webwork-database and .sco files.<b> Be very careful.</b>
				if you want to save the current scoring information for a set to be
				destroyed and rebuilt, score the set before deleting it (go to the scoring page) and/or move
				the .sco files out of the DATA directory. <b> Be very careful and think before you click.</b>",
		$cgi->p, $cgi->p, "Select the set(s) to destroy and rebuild:",
		$cgi->startform(-action=>"${cgiURL}profBuildProblemSet.pl");

		my %availableSets = &getAllProbSetNumbersHash;
		my @sortedSetNames = &sortSetNamesByDueDate(\%availableSets);

		# enter the available set names
		for $ind (@sortedSetNames) {
			$labels{$ind} = "Set $ind";
		}

print $cgi->popup_menu(-name=>'setNo', -size=>4, -multiple=>undef, -values=>\@sortedSetNames, -labels=>\%labels), "\n",
	$cgi->br, $cgi->radio_group(-name=>'outputFormat', -values=>['no_students','all_students'], -default=>'no_students', -linebreak=>'true', -labels=>\%formatLabels),
	$cgi->p, $cgi->submit(-value=>'Destroy and Rebuild'), "\n",
	$cgi->radio_group(-name=>'confirm', -values=>['0', '1'], -default=>'0', -labels=>{'0'=>'Off', '1'=>'Destroy and Rebuild enabled'}), "\n",
	hiddens('user', 'key', 'course'),
	$cgi->hidden(-name=>'page', -value=>'destroy'), "\n",
	$cgi->hidden(-name=>'download', -value=>0), "\n", 
	$cgi->hidden(-name=>'fileName', -value=>''), "\n",
	$cgi->endform(), "\n", 
	$cgi->p;

}  ## end of long if which began on line 202.  Clean up this code next time.

# print &sessionKeyInputs(\%inputs);  Don't use this.  It's duplicating the course, user and key which have already been   put in.

print &htmlBOTTOM("profBuildProblemSetPage.pl", \%inputs, 'profBuildProblemSetPageHelp.html');

# begin Timing code
my $endTime = new Benchmark;
&Global::logTimingInfo($beginTime,$endTime,"profBuildProblemSetPage.pl",$inputs{'course'},$inputs{'user'});
# end Timing code
exit;

################################################################################
#
# HELPFUL METHODS
#
################################################################################

#returns the horizontal line, blue square, and heading for each option
#in the list, eliminating the need to repeat this code each time it is needed
#this does NOT PRINT the info, so that it can be incorporated into other text
sub heading {
        my $link = shift; #name for internal link (used for shortcuts on some pages)
        my $text = shift; #text used as the main heading

        return "\n",
                 $cgi->p, "\n",
                 $cgi->a({-name=>$link},''), "\n",
                 $cgi->hr({ -noshade=>undef }), "\n",
                 $cgi->h4({ -align=>'LEFT' },
                                "\n" . $cgi->img({-src=>"$Global::bluesquareImgUrl", -border=>1, -alt=>'' }) . "\n" .
                                $text ), "\n";
}

#prints hidden form fields for each of given cgi parameters
#if a given parameter does not exist, a note is placed in the html to that affect
#this does NOT PRINT the info, so that it can be incorporated into other text
sub hiddens {
	my @params = @_;
	my $out;
	
	foreach my $param (@params) {
		if (exists $inputs{$param}) {
			$out .= $cgi->hidden(-name=>"$param", -value=>"$inputs{$param}") . "\n";
		} else {
			$out .= $cgi->p . "\nExpected cgi parameter $param does not exist or is empty";
		}
	}
	$out;
}
