#!/usr/bin/perl


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

## This script is profEditClasslistDB.pl ##

###############################################################################
############          PRELIMINARY SETUP                 #######################
###############################################################################

use lib '/ww/webwork/development/'; # mainWeBWorKDirectory;

use Global;
use CGI qw(:standard);
use Auth;
use TimeLocal; # the module Time::Local.pm has a bug which interacts
			   # with DProf.  (They call a subroutine assuming @_ doesn't change.

use strict;

my $logTimingData = 0;
my $beginTime;

# begin Timing code
if ($logTimingData == 1) {
	use Benchmark;
	$beginTime = new Benchmark;
}
# end Timing code

my $cgi = new CGI;

&CGI::ReadParse(*main::inputs);
my %inputs=%main::inputs;

# get primary data from CGI form
my $User       = $inputs{'user'};
my $Course     = $inputs{'course'};
my $Key        = $inputs{'key'};


# set course environment
&Global::getCourseEnvironment($Course);

my	$scriptDirectory   = getWebworkScriptDirectory($Course);
my	$databaseDirectory = getCourseDatabaseDirectory($Course);
my 	$cgiURL   		   = getWebworkCgiURL($Course);
my	$htmlURL       	   = getCourseHtmlURL($Course);
my  $logsDirectory     = getCourseLogsDirectory($Course);

require "${scriptDirectory}$Global::DBglue_pl";
require "${scriptDirectory}$Global::classlist_DBglue_pl";
require "${scriptDirectory}$Global::FILE_pl";
require "${scriptDirectory}HTMLglue.pl";

my $keyFile 			= getCourseKeyFile($Course);
&verify_key($inputs{'user'}, $inputs{'key'}, "$keyFile", $inputs{'course'});

my $passwordFile = &Global::getCoursePasswordFile($inputs{'course'});
my $permissionsFile = &Global::getCoursePermissionsFile($inputs{'course'});
my $permissions = &get_permissions($inputs{'user'}, $permissionsFile);

if ($permissions != $Global::instructor_permissions ) {
	print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n";
	print &html_NO_PERMISSION;
	}


# get additional data from calling CGI form
my ($Mode, $studentLogin,$action);

$Mode        = "HTML";   #default viewing mode
$Mode = $inputs{'Mode'} if defined($inputs{'Mode'});
$studentLogin	= $inputs{'studentLogin'};
$action = $inputs{'action'};

wwerror("No Student Selected", "Go back and select the student whose record you want to view or edit")
  unless defined $studentLogin;

# the following are used to send warning messages if a unique section
# or recitation name is saved. They are set in updateDatabase()
my $section_status = 'non_unique';
my $recitation_status = 'non_unique';
my $section_status_ref = \$section_status;
my $recitation_status_ref = \$recitation_status;

if (defined( $inputs{'save'} ) and ($inputs{'save'} eq "ON" ) and ($action =~ /SAVE/) )  {
	# in this case we obtain the data from the CGI from and store it in the database

	my $status = get_CL_database_status();
	if ($status eq 'locked') {
		wwerror("The Classlist Database is LOCKED", "This means the database can not be updated from the internet.
Go back and unlock the Classlist Database before proceeding.");
	}
	# update the database from the CGI script:

	$studentLogin =	&updateDatabase($studentLogin);
						# loads the information into %CLRecord,
						# modifies the data and saves it back to the database

	#log the changes:  -- the format for loggin the changes needs improvement
	&logChanges( getClassListRecord()  );
	&print_modification_form;

}	

elsif (defined( $inputs{'save'} ) and ($inputs{'save'} eq "ON" ) and ($action =~ /REMOVE/) )  {

	my $status = get_CL_database_status();
	if ($status eq 'locked') {
		wwerror("The Classlist Database is LOCKED", "This means the database can not be updated from the internet.
Go back and unlock the Classlist Database before proceeding.");
	}
	&removeRecord($studentLogin);
	&record_successfully_deleted_message($studentLogin);
}

elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){
	# No new information in the calling CGI form
	# and the information has already been loaded into %probSetRecord using &fetchProbSetRecord($psvn);
	# Nothing needs to be done in this case except print the form
	&print_modification_form;

}	else {

#   The calling CGI script must define the 'save' variable or the 'deleteMode' variable
	wwerror( $0,  "No value for 'save' mode in the calling CGI form");
}

# begin Timing code
if ($logTimingData == 1) {
	my $endTime = new Benchmark;
	&Global::logTimingInfo($beginTime,$endTime,'profEditClasslistDB.pl',$Course,$User);
}
# end Timing code
exit;

#### END of main program

###############################################################################
############################  SUBROUTINES          ############################
###############################################################################


###############################################################################
##########################       PRINT FORM      ##############################
###############################################################################
sub print_modification_form {
	print &htmlTOP('Classlist database edit form');
	print <<END_OF_HTML;

	<A HREF="${cgiURL}profClasslist.pl?user=$inputs{'user'}&key=$inputs{'key'}&course=$inputs{'course'}&format=section">
	<IMG SRC="${Global::upImgUrl}" align="right" BORDER=1 ALT="[Up]"></A><p>
	<H3 ALIGN ="CENTER">Course Name: <FONT COLOR="#AA4400"> $inputs{'course'}</FONT>
	Data for Student Login: <FONT COLOR="#AA4400">$studentLogin</FONT></H3>
	<HR SIZE =2>
	<FORM ACTION="${cgiURL}profEditClasslistDB.pl" METHOD=POST>

	Changes can be saved only if the Read/Write Mode button is selected: <BR>

	<INPUT TYPE="radio" CHECKED NAME="save" VALUE="OFF" > Read Only Mode <BR>
	<INPUT TYPE="radio" NAME="save" VALUE="ON"> Read/Write Mode  <BR>
	<INPUT TYPE='HIDDEN' NAME='firsttime' VALUE= 0>

END_OF_HTML


	######################################################
	# return messages
	#print message about saving to the database and current mode of CGI form
	if (defined( $inputs{'firsttime'} ) && $inputs{'firsttime'} == 0 ) {
		if (defined( $inputs{'save'} ) && $inputs{'save'} eq "ON" ) {
			print "<P><FONT COLOR='#ff00aa'><B>CLASSLIST DATABASE MODIFIED</B></font> <P>";
		}	elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){

			print "<P><FONT COLOR='#ff00aa'><B>READ ONLY MODE:  CLASSLIST DATABASE UNCHANGED</B></font> <P>";

		} else {
	#   When initially entering this CGI the 'save' mode is undefined.
			wwerror( $0,  "No value for 'save' mode.</B><P>");
		}
	}

	# Get set data

	attachCLRecord($studentLogin);
											   ## student
	my $StudentLastName		= CL_getStudentLastName($studentLogin);
	my $StudentFirstName	= CL_getStudentFirstName($studentLogin);
	my $StudentStatus		= CL_getStudentStatus($studentLogin);
	my $StudentComment		= CL_getComment($studentLogin);
	my $ClassSection		= CL_getClassSection($studentLogin);
	my $ClassRecitation		= CL_getClassRecitation($studentLogin);
	my $StudentEmail		= CL_getStudentEmailAddress($studentLogin);
	my $StudentID			= CL_getStudentID($studentLogin);


	if ($section_status eq 'unique') {
		print "<P><FONT COLOR='#ff00aa'><B>$StudentFirstName $StudentLastName is the only
		person in the section $ClassSection</B></font> <P>";
	}

	if ($recitation_status eq 'unique') {
		print "<P><FONT COLOR='#ff00aa'><B>$StudentFirstName $StudentLastName is the only
		person in the recitation $ClassRecitation</B></font> <P>";
	}


	# submit button

	print qq!<INPUT TYPE='SUBMIT' NAME = 'action' VALUE='SAVE CHANGES'><INPUT TYPE = "RESET" VALUE= "RESET FORM"><INPUT TYPE='SUBMIT' NAME = 'action' VALUE='REMOVE THIS RECORD'> <BR>!;

	# Get set data


	# continue printing form ######################################################
	print &sessionKeyInputs(\%inputs);
	print qq!<INPUT TYPE='HIDDEN' NAME='studentLogin' VALUE="$studentLogin">!;
	print qq! <TABLE BORDER="1" CELLPADDING="1" CELLSPACING="2" > <FONT SIZE=-2>!;

	print "<TR>\n";
		print &formatHeaderCell("Last Name");
		print &formatHeaderCell("First Name");
		print &formatHeaderCell("Student ID" );
	print "</TR>\n";
	print "<TR>\n";
		print &formatDataCell("StudentLastName",$StudentLastName, "20");
		print &formatDataCell("StudentFirstName", $StudentFirstName, "20");
		print &formatDataCell("StudentID", $StudentID, "30");
	print "</TR>\n";

	print "<TR>\n";
		print &formatHeaderCell("Student login name");
		print &formatHeaderCell("Enrollment Status");
		print &formatHeaderCell('Comment' );
	print "</TR>\n";
	print "<TR>\n";
		print &formatDataCell('StudentLogin',$studentLogin, "20");
		print &formatDataCell('StudentStatus',$StudentStatus, "20");
		print &formatDataCell('Comment', $StudentComment, "30");
	print "</TR>\n";

	print "<TR>\n";
		print &formatHeaderCell('Section');
		print &formatHeaderCell('Recitation');
		print &formatHeaderCell('Email Address');
	print "</TR>\n";

	print "<TR>\n";
		print &formatDataCell('ClassSection', $ClassSection, "20");
		print &formatDataCell('ClassRecitation', $ClassRecitation, "20");
		print &formatDataCell('StudentEmail', $StudentEmail, "30");
	print "</TR>\n";



	print ' </FONT></TABLE>';
	
	print '<BR>The drop down lists below are for information only. Selecting items from them 
	does nothing.<BR> Enter the section, recitation, and enrollment status, if any, above. <BR>';
	# Current Sections list

	print $cgi -> popup_menu( -name => 'currentSections',
		-values => ['List of current sections', keys (%{getAllSections()})]
				);

	# Current Recitations list
	print $cgi -> popup_menu( -name => 'currentRecitations',
		-values => ['List of current recitations', keys (%{getAllRecitations()})]
				);
	# Current Drop List

	my @drop_status_labels = getStatusDrop();

	print $cgi -> popup_menu( -name => 'dropStatus',
		-values => ['Valid Drop Status',@drop_status_labels]
				);
	print 'Any other status (e.g. "C") indicates a current student.';

	print q!</FORM>!;

	print &htmlBOTTOM('profEditClasslistDB.pl', \%inputs);

}  # end of print_modification_form


sub updateDatabase {

	my $studentLogin = shift @_;
	attachCLRecord($studentLogin);

	my $orgStudentLastName	= CL_getStudentLastName($studentLogin);
	my $orgStudentFirstName	= CL_getStudentFirstName($studentLogin);
	my $orgStudentID		= CL_getStudentID($studentLogin);
	my $orgStudentStatus	= CL_getStudentStatus($studentLogin);
	my $orgStudentLogin 	= $studentLogin;

	my $newStudentLastName 		= stripWhiteSpace($inputs{'StudentLastName'});
	my $newStudentFirstName 	= stripWhiteSpace($inputs{'StudentFirstName'});
	my $newStudentStatus 		= stripWhiteSpace($inputs{'StudentStatus'});
	my $newComment 				= stripWhiteSpace($inputs{'Comment'});
	my $newClassSection 		= stripWhiteSpace($inputs{'ClassSection'});
	my $newClassRecitation 		= stripWhiteSpace($inputs{'ClassRecitation'});
	my $newStudentEmail		 	= stripWhiteSpace($inputs{'StudentEmail'});
	my $newStudentID 			= stripWhiteSpace($inputs{'StudentID'});
	my $newStudentLogin 		= stripWhiteSpace($inputs{'StudentLogin'});
	
	## test entries for bad characters. 
	my @entries = ($newStudentLastName, $newStudentFirstName, $newStudentStatus, $newComment, $newClassSection, 	    
	  $newClassRecitation, $newStudentEmail);		
	my $item ='';
	foreach $item (@entries) {
		my $msg = test_entry($item);	
		unless ($msg eq 'OK') {
			&wwerror('Bad Entry',$msg);
		}              
     }    
               
	## test student login and ID for validity. 
	my $studentLoginChanged = 0;
	if ($newStudentLogin ne $orgStudentLogin) {
		$studentLoginChanged = 1;
		my $msg = testNewStudentLogin($newStudentLogin,$newStudentID);
		unless ($msg eq 'OK') {
        	&wwerror('Bad Login Name',$msg);}
	}
	my $studentIDChanged = 0;
	if ($newStudentID ne $orgStudentID) {
		$studentIDChanged = 1;
		my $msg = testNewStudentID($newStudentID,$newStudentLogin);
		unless ($msg eq 'OK') {
        	&wwerror('Bad Student ID',"$msg");}
	}

	if ($studentLoginChanged and $studentIDChanged) {
			warningMsgPage(\%inputs,$orgStudentFirstName,$orgStudentLastName,$newStudentFirstName,$newStudentLastName);
			exit(0);
	}

	# these will be set to zero if the new section or recitation is unique
	my $uniqueSection = 0;
	my %section_hash = %{getAllSections()};
	$uniqueSection = $section_hash{$newClassSection} if defined $section_hash{$newClassSection};

	my $uniqueRecitation = 0;
	my %recitation_hash = %{getAllRecitations()};
	$uniqueRecitation = $recitation_hash{$newClassRecitation} if defined $recitation_hash{$newClassRecitation};

	$$section_status_ref = 'unique' unless $uniqueSection;
	$$recitation_status_ref = 'unique' unless $uniqueRecitation;

	# update the webwork database if it exists

	if ( -e "${databaseDirectory}$Global::database" ){
		my %setNumberHash=&getAllSetNumbersForStudentLoginHash($studentLogin);
		my @PSVNs = values %setNumberHash;
		my $psvn;
		foreach $psvn (@PSVNs) {
			attachProbSetRecord($psvn);
			putStudentLastName(		$newStudentLastName	,$psvn);
			putStudentFirstName(	$newStudentFirstName,$psvn);
			putStudentStatus(	 	$newStudentStatus	,$psvn);
			putClassSection(		$newClassSection	,$psvn);
			putClassRecitation(		$newClassRecitation	,$psvn);
			putStudentEmailAddress(	$newStudentEmail	,$psvn);
			putStudentID(			$newStudentID		,$psvn);
			putStudentLogin(		$newStudentLogin	,$psvn);
			detachProbSetRecord($psvn);
		}
	}
	# update the password and permissions databases

	if ($studentLoginChanged) {
		change_user_in_password_file($newStudentLogin, $orgStudentLogin,$passwordFile);
		change_user_in_permissions_file($newStudentLogin, $orgStudentLogin,$permissionsFile);
	}

	if (&dropStatus($newStudentStatus) !=  &dropStatus($orgStudentStatus)) {
		if (&dropStatus($newStudentStatus)) {
			delete_password($newStudentLogin,$passwordFile);
			delete_permissions($newStudentLogin,$permissionsFile);
		}
		else {
			new_password($newStudentLogin,$newStudentID,$passwordFile);
			put_permissions(0,$newStudentLogin,$permissionsFile);
		}
	}
	# update the classlist database

	if ($studentLoginChanged) {
		deleteClassListRecord($orgStudentLogin);
		$studentLogin = $newStudentLogin;
	}

	&CL_putStudentLastName(		$newStudentLastName	,$studentLogin);
	&CL_putStudentFirstName(	$newStudentFirstName,$studentLogin);
	&CL_putStudentStatus(	 	$newStudentStatus	,$studentLogin);
	&CL_putComment(				$newComment			,$studentLogin);
	&CL_putClassSection(		$newClassSection	,$studentLogin);
	&CL_putClassRecitation(		$newClassRecitation	,$studentLogin);
	&CL_putStudentEmailAddress(	$newStudentEmail	,$studentLogin);
	&CL_putStudentID(			$newStudentID		,$studentLogin);

	# save the updated information to the database
	saveCLRecord($studentLogin);
	$studentLogin;               ## return the possibly new studentLogin

}

sub removeRecord {	
	my ($studentLogin) = shift @_;
	attachCLRecord($studentLogin);	
	deleteClassListRecord($studentLogin);			
	delete_password($studentLogin,$passwordFile);
	delete_permissions($studentLogin,$permissionsFile);
}	

# logs the incremental changes to a log file
sub	logChanges {
		my @dataArray = @_;
		my $fullLogFileName ="${logsDirectory}classlist_DB.log";
		open(LOGFILE,">>$fullLogFileName")  ||  &Global::error( "Can't open $fullLogFileName");

		my $timeNow = formatDateAndTime(time);
		print LOGFILE "\n$Course, student is $studentLogin, user is $User, time is $timeNow, data is: ";
		my $dataString = join( ' ',@dataArray);
		print  LOGFILE "@dataArray\n" ;
		close(LOGFILE);
		}


sub formatDataCell {
	my ($name,$value,$size) = @_;
		# if the data hasn't been entered it appears as a blank:
	$value = '' unless defined($value);

	my $out = qq!
	<TD ALIGN=CENTER VALIGN=MIDDLE >
	<INPUT TYPE="TEXT" NAME="$name" VALUE="$value", SIZE="$size">
	</TD>
	!;
	$out;
	}
sub formatFixedDataCell {
	my ($name,$value,$size) = @_;
		# if the data hasn't been entered it appears as a blank:
	$value = '' unless defined($value);

	my $out = qq!
	<TD ALIGN=CENTER VALIGN=MIDDLE >
	<INPUT TYPE='HIDDEN' NAME="$name" VALUE="$value">
	$value
	</TD>
	!;
	$out;
	}
sub formatHeaderCell {
	my ($item,$options) = @_;
	$options = '' unless defined($options);
	my $out = qq!
	<TH ALIGN=CENTER VALIGN=MIDDLE $options>
	$item
	</TH>
	!;
	$out;
	}



sub record_successfully_deleted_message {
	my $studentLogin =shift;
	print &htmlTOP("The student record with login $studentLogin has been deleted from the $Course classlist database.");
	print <<END_OF_HTML;
	<A HREF="${cgiURL}profLogin.pl?user=$inputs{'user'}&key=$inputs{'key'}&course=$inputs{'course'}">
	<IMG SRC="${Global::upImgUrl}" align="right" BORDER=1 ALT="[Up]"></A>
END_OF_HTML
	print qq!<P><B> The student record with login $studentLogin has been deleted from the classlist database.</B><P>!;
	print &htmlBOTTOM('profEditClasslistDB.pl', \%inputs);

}



sub warningMsgPage {

my ($inputref,$ofn,$oln,$nfn,$nln)  = @_;
my %inputs = %$inputref;
# print HTML text
print &htmlTOP("Data for the classlist record for $studentLogin");

# print navigation buttons
print qq!
<A HREF="${Global::cgiWebworkURL}profLogin.pl?user=$inputs{'user'}&key=$inputs{'key'}&course=$inputs{'course'}">
<IMG SRC="${Global::upImgUrl}" align="right" BORDER=1 ALT="[Up]"></A><p>
!;

print <<EOF;
<HR><BR>
<h3 align="left">WeBWorK WARNING message for Student Login $studentLogin</h3>
EOF
print qq!You have attempted to change (edit) both the Student Login and Student ID for <BR><BR>
Original Name: $ofn $oln <BR>
Edited Name: $nfn $nln <BR><BR>

<P><FONT COLOR='#ff00aa'><B>NO CHANGES HAVE BEEN MADE</B></font> <P>
It is possible you are making a mistake by trying to use this form to enter a new user. If you want to
enter a new user, goto the Professor's page and click on "Enter Add Student(s) Page". <BR><BR>

If you really want to make these extensive changes to $ofn ${oln}'s classlist record, you must do it
in two steps.  You can not change both the Student Login and Student ID at the same time. Use your
browser's "Back Button" to go back and change just one of these. Then edit the record again changing the other one.
<BR><BR>
To Quit and return to the Professor's page, select the "Up" button or the button below.!;



print &htmlBOTTOM('profEditClasslistDB.pl', \%inputs);
exit;
} #end of warning Page