#!/usr/bin/perl
#  Copyright 2001-2022 Leslie Richardson

#  This file is part of Open Admin for Schools.

#  scoreadd.pl
#  Passed id for the gbtest record that we want to add/edit scores for.

#  Flag - does update  Comment - comment entry mode.

my $self = 'scoreadd.pl';
my %lex = ('Add/Edit Test Scores' => 'Add/Edit Test Scores',
	   'Name' => 'Name',
	   'Score' => 'Score',
	   'Scores' => 'Scores',
	   'Comment' => 'Comment',
	   'Comments' => 'Comments',
	   'GB&nbsp;Main' => 'GB&nbsp;Main',
	   'Fill Blanks' => 'Fill Blanks',
	   'Score Entry' => 'Score Entry',
	   'Max Score' => 'Max Score',
	   'Test' => 'Test',
	   'Contact' => 'Contact',
	   'Comment Entry' => 'Comment Entry',
	   'Maximum' => 'Maximum',
	   'Error' => 'Error',
	   'Save' => 'Save',

	   );

use DBI;
use CGI;

# Set the current date
my @tim = localtime(time);
my $year = $tim[5] + 1900;
my $month = $tim[4] + 1;
my $day = $tim[3];
my $currdate = "$year-$month-$day"; 

eval require "../../etc/admin.conf";
if ( $@ ) {
    print $lex{Error}. " $@<br>\n";
    die $lex{Error}. " $@<br>\n";
}

my $q = new CGI;
print $q->header( -charset, $charset ); 
my %arr = $q->Vars;

# Test passed as id; just id field for test record.
my $comment = $arr{comment};
delete $arr{comment};

my $dsn = "DBI:$dbtype:dbname=$dbase";
my $dbh = DBI->connect($dsn,$user,$password);
$dbh->{mysql_enable_utf8} = 1;

# Lookup Test record
my $sth = $dbh->prepare("select * from gbtest where id = ?");
$sth->execute ( $arr{id} );
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;; }
my @test = $sth->fetchrow;
my $subjsec = $test[1];


# Now HTML header
my $title = $lex{'Add/Edit Test Scores'};
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$tchcss" type="text/css">\n};

# Set Focus on first entry with javascript.
my $elementnumber;
if ( $comment ) { $elementnumber = 3; } else { $elementnumber = 4;}
print qq{<script type="text/javascript">};

print qq{function setfocus() { 
  document.forms[1].elements[$elementnumber].focus();
}\n\n};

print "function movefocus(currid, e) { 
 var currval = currid * 1; // make it a number
 var startid = 100;
 var endid = 100;
 var nodes = document.getElementsByTagName('input');
 for (var i=0;i<nodes.length;i++) {
   tempid = nodes[i].getAttribute('id');
   if (tempid > endid) { endid = tempid; }
 }

 var unicode=e.charCode? e.charCode : e.keyCode;

 if (unicode == 40) { // arrow down
   if (currval == endid) {
     targetid = startid;
   } else {
     targetid = currid + 1;
   }
   oElement = document.getElementById(targetid);
   oElement.focus();
   return;
 } 

 if (unicode == 38) { // arrow up
   if (currval == startid) {
     targetid = endid;
   } else {
     targetid = currid - 1;
   }
   oElement = document.getElementById(targetid);
   oElement.focus();
   return;
 } 

} \n";

print qq{</script>\n};

print qq{$chartype\n</head><body onload="setfocus()" style="padding:1em;">\n};
print qq{[ <a href="gbmain.pl">$lex{'GB&nbsp;Main'}</a> | };
print qq{<a href="testadd.pl">Add Item</a> ]\n};

print qq{<form action="$self" method="post" style="display:inline;">\n};
if ($comment){
   print qq{<input type="hidden" name="comment" value="1">\n};
}
print qq{<input type="hidden" name="id" value="$arr{id}">\n};
print qq{<input type="submit" value="$lex{'Fill Blanks'}">\n};
print qq{<input type="text" name="filler" size="16" maxlength="255"></form>\n};


if ( not $comment ) { # show entry hands
    print qq{<img src="/images/hands.gif" width="300" };
    print qq{style="border:2px solid black;position:absolute;top:1em;right:1em;">\n};
}


# Update records for changed scores.
if ( $arr{flag} ){ # we are updating records
    delete $arr{flag};
    updateRecs();
}


# Creates array controlling student sort order.
my @studnum = mkStudNum( $subjsec );

if ($comment){
    doComment();
} else {
    doScore();
}


#------------
sub mkStudNum {
#------------

    my $subjsec = shift;
    my (@eval, @studnum, %remove);

    # Create the studnum array that controls the order that students are
    # displayed in. Load the eval records first into an array, sorted by
    # lastname and firstname. (@eval) Load the sort order records in order
    # into an array and also into a hash (%remove)
    # Any remaining array elements in eval are added to the end of
    # the studnum array once done. If there _are_ no sortorder recs, then
    # the final array becomes the eval records only. This has the desired
    # behavior.

    # Find the enrollments for this class and read them into @eval array
    my $sth = $dbh->prepare("select distinct e.studnum from eval e
			    left outer join studentall s on s.studnum = e.studnum 
			    where e.subjcode = ?  order by s.lastname, s.firstname");
    $sth->execute( $subjsec );
    if ($DBI::errstr) { print qq{$DBI::errstr}; die $DBI::errstr;}
    while ( my $studnum = $sth->fetchrow ){
	push @eval,$studnum;
    }
    
    # Load 'SortOrder' test if it exists...
    my $sth = $dbh->prepare("select id from gbtest where subjsec = ? and name = 'sortorder'");
    $sth->execute( $subjsec );
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr;}
    my $sortid = $sth->fetchrow;

    if ($sortid){ # We have a sortorder
	my $sth = $dbh->prepare("select studnum from gbscore where testid = ? order by score");
	$sth->execute( $sortid );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr;}
	while ( my $sn = $sth->fetchrow){
	    push @studnum, $sn;
	    $remove{$sn} = 1;
	}
	
	# Now add on @eval elements who are not in @studnum (enrolled but not in sortorder yet)
	foreach my $en (@eval){
	    if ( not $remove{$en} ){ push @studnum, $en;}
	}
	return @studnum;

    } else { # no sortorder
	return @eval;
    }
}


#-------------
sub updateRecs { # Update scores records
#-------------

    #foreach my $key (keys %arr) { print qq{K: $key VAL: $arr{$key}<br>\n}; } 

    foreach my $key ( keys %arr ) { # Read all passed values...
	if ($key eq 'id' or $key eq 'comment'){ next;}

	my ( $studnum,$flag,$type ) = split ':',$key; #Type:(S)core/(C)omment
	#print qq{S:$studnum F:$flag V:$arr{$key}<br>\n};
	if ( not defined $flag or not $studnum or not $type ) {
	    print qq{$lex{Error} $arr{$key} $lex{Test}: $arr{id}<br>\n};
	    print qq{</body></html>\n};
	    exit;
	}

	# Look for an existing student score record...
	my $sth = $dbh->prepare("select count(id) from gbscore where studnum = ? and testid = ?");
	$sth->execute( $studnum, $arr{id} );
        my $count = $sth->fetchrow;
	if ( $count > 1) { # We have more than 1 record for score for this student/test.
	    print qq{<b>Duplicate Records found for the testid: $arr{id}<br>\n};
	    print qq{for student number: $studnum</b><br>\n};
	    exit;
	}

	if ($count == 1){  #if non zero, we have an existing record to update
	    if ( $type eq 'S' ) {
		if ( not $arr{$key} and $arr{$key} ne '0' ) {
		    $sth = $dbh->prepare("delete from gbscore 
                      where studnum = ? and testid = ?");
		    $sth->execute( $studnum, $arr{id} );
                     # print qq{DELETE!<br>\n};
		} else {
		    $sth = $dbh->prepare("update gbscore set score = ? 
                     where studnum = ? and testid = ?");
		    $sth->execute( $arr{$key}, $studnum, $arr{id} );
		}
	    } elsif ($type eq 'C') { # type eq C, set comment.
		$sth = $dbh->prepare("update gbscore set comment = ? 
                  where studnum = ? and testid = ?");
		$sth->execute( $arr{$key}, $studnum, $arr{id} );
	    } else { 
		print qq{Error in Type for $arr{$key} for testid: $arr{id}<br>\n};
		exit;
	    }
	} elsif ($count == 0) { # count is zero; we must add a new record.
	    if ( not $arr{$key} and $arr{$key} ne '0') { next; } # skip if empty
	    if ( $type eq 'S' ) {
		$sth = $dbh->prepare("insert into gbscore values (
                 $sql{default},?,?,?,$sql{default})");
		$sth->execute( $studnum, $arr{id}, $arr{$key} );
	    } elsif ($type eq 'C') { # Add Comment Field.
		$sth = $dbh->prepare("insert into gbscore values (
                 $sql{default},?,?,$sql{default},?)");
		$sth->execute( $studnum, $arr{id}, $arr{$key} );
	    } else {
		print qq{Error in Type for $arr{$key} for testid: $arr{id}<br>\n};
		exit;
	    }
	} else { # $count not zero or 1... error.
	    print qq{Error in Count: $count<br>\n};
	    exit;
	}

	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    } # End of foreach

} # End of updateRecs



#----------
sub doScore {
#----------

    # Heading
    print qq{<h1>$lex{'Score Entry'} - $test[2]</h1>$test[3]<br><b>};
    print qq{$lex{'Max Score'}: $test[5]</b>\n};

    # Form
    print qq{<form action="scoreadd.pl" method="post" name="scoreadd">\n};
    print qq{<input type="hidden" name="id" value="$arr{id}">\n};
    print qq{<input type="hidden" name="flag" value="1">\n};
    print qq{<input type="submit" value="$lex{Save} $lex{Scores}">\n};
    print qq{<input type="hidden" name="comment" value="1">\n};

    # Table and Heading
    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
    print qq{<tr><th>$lex{Name}</th><th>$lex{Score}</th>};
    print qq{<th>$lex{Comment}</th></tr>\n};

    my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");
    my $idcount = 100;
    
    # Print the students and their scores;
    foreach my $studnum ( @studnum ) {
    
	# Get student name
	$sth->execute($studnum);
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth->fetchrow;

	# Now get the score for this student for this testid.
	my $sth1 = $dbh->prepare("select score, comment from gbscore
         where studnum = ? and testid = ?");
	$sth1->execute( $studnum, $arr{id} );
	if ($DBI::errstr) { print qq{GetScore Error: $DBI::errstr}; die $DBI::errstr; }
	my $trow = $sth1->rows; 
	# Trow is passed to the next script for deciding how to update record
	#  0 means no record and thus add new one; 1 means update record.
    
	my ($score,$comment) = $sth1->fetchrow;
	if ( not defined $score ){ $score = $arr{filler}; }
    
	print qq{<tr><td>$lastname, $firstname ($studnum)</td>\n};
	print qq{<td><input type="text" name="$studnum:$trow:S" size="6" };
	print qq{value="$score" id="$idcount" onkeyup="movefocus($idcount, event)"></td>\n};
	print qq{<td>$comment</td></tr>\n};
	$idcount++;
    
    }

    print qq{</table><input id="$idcount" onkeyup="movefocus($idcount, event)" };
    print qq{type="submit" value="$lex{Save} $lex{Scores}">};
    print qq{</form></body></html>\n};
							
    exit;
							
} # End of doScore



#------------
sub doComment {
#------------
    
    print qq{<h1>$lex{'Comment Entry'} - $test[2]</h1>$test[3]\n};
    
    print qq{<form action="scoreadd.pl" method="post">\n};
    print qq{<input type="hidden" name="id" value="$arr{id}">\n};
    print qq{<input type="hidden" name="flag" value="1">\n};
    print qq{<input type="submit" value="$lex{Save} $lex{Comments}">\n};
    
    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
    print qq{<tr><th>$lex{Name}</th><th>$lex{Score}</th><th>$lex{Comment} };
    print qq{($lex{Maximum}:255 chars)</th></tr>\n};


    # Print the students and their marks;
    my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");

    foreach my $studnum ( @studnum ) {
	$sth->execute($studnum);
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr;}
	my ($lastname, $firstname) = $sth->fetchrow;

	# Now get the score for this student for this testid.
	my $sth1 = $dbh->prepare("select score,comment from gbscore
				 where studnum = ? and testid = ?");
	$sth1->execute( $studnum, $arr{id} );
	if ($DBI::errstr) { print qq{GetScore Error: $DBI::errstr}; die $DBI::errstr; }
	my $trow = $sth1->rows; 
	# Trow is passed to the next script for deciding how to update record
	#  0 means no record and thus add new one; 1 means update record.
	my ($score,$comment) = $sth1->fetchrow;
	if (not $comment){ $comment = $arr{filler};}

	print qq{<tr><td>$lastname, $firstname ($studnum)</td>};
	print qq{<td>$score</td><td><input type="text" name="$studnum:$trow:C" };
	print qq{size="70" value="$comment" maxlength="255"></td></tr>\n};
    }

    print qq{</table><input type="submit" value="$lex{Save} $lex{Comments}">};
    print qq{</form></body></html>\n};

    exit;

} # End of doComment
