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

#  This file is part of Open Admin for Schools.

#  Open Admin for Schools 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.

# rptmarksheet.pl - A customizable column width report
#  - passed a teacher userid, shows his/her subjects for selection.
# Once selected, print sheets for his/her courses

my $self = 'rptMarkSheet.pl';

my %lex = ('Mark Sheets' => 'Mark Sheets',
	   'Main' => 'Main',
	   'GB Main' => 'GB Main',
	   'View/Download' => 'View/Download',
	   'View Log File' => 'View Log File',
	   'Students' => 'Student',
	   'Cell Width' => 'Cell Width',
	   'Select Print Characteristics' => 'Select Print Characteristics',
	   'Max Students/Page' => 'Max Students/Page',
	   'Repeat Entry Elements?' => 'Repeat Entry Elements?',
	   'Text Elements (Column Titles)' => 'Text Elements (Column Titles)',
	   'Entry' => 'Entry',
	   'Continue' => 'Continue',
	   'Mark Sheet' => 'Mark Sheet',
	   'Error' => 'Error',
	   'Font Size' => 'Font Size',
	   'Course' => 'Course',

	   );

use DBI;
use CGI;

# Configurable settings
my $maxstudents = 28; # default maximum students per page.
my $width = 6;  # default width of columns, 6mm;

my $entrylimit = 8; # Max entries allowed for text.
my $maxentrysize = 14; # Maximum number of characters for the entry
my $namewidth = 50; # Width of the first 'Name' column in mm.
my $grayshade = '0.96'; # 1.00 is white, 0.00 is black.
my $columnareawidth = 145;  # width of the column area for letter paper (only, so far)


my $q = new CGI;
my %arr = $q->Vars;

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

# Load LaTeX library for filtering
eval require "../../lib/liblatex.pl";
if ( $@ ) {
    print $lex{Error}. " :$@<br>\n";
    die $lex{Error}. " :$@\n";
}

# Current Date
my ($sec, $min, $hour, $mday, $mon, $year, $wday, 
    $yday, $iddst) = localtime(time);
$year = $year + 1900;
$mon++;
$wday++;
my $currdate = "$dow[$wday], $month[$mon] $mday, $year";


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



my $userid = $ENV{'REMOTE_USER'};
print $q->header( -charset, $charset );

# Get Teacher Name
my $sth = $dbh->prepare("select lastname, firstname from staff where userid = ?");
$sth->execute($userid);
my ($ln,$fn) = $sth->fetchrow;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
my $teachername = "$fn $ln";


my $title = qq{$lex{Course} $lex{'Mark Sheets'}};
print qq{$doctype\n<html><head><title>$title</title>
<link rel="stylesheet" href="$tchcss" type="text/css">
$chartype\n</head><body style="margin:1em;">\n};

print qq{[ <a href="$tchpage">$lex{Main}</a> |\n}; 
print qq{<a href="gbmain.pl">$lex{'GB Main'}</a> | <a href="rptMenu.pl">Report Menu</a> ]\n};


# Values passed are width, maxstudents, repeat, entry1 to entry8
if ( not $arr{page} ) {
    showStartPage();
} else {
    delete $arr{page};
    # and continue
}

my $maxlines;
if ( $arr{maxstudents} ) {
    $maxlines = $arr{maxstudents};
    delete $arr{maxstudents};
} else {
    $maxlines = $maxstudents;
}
my $wi = $arr{width} - 1; # width of each col desired (in mm)
# take away 1 for 1mm tabcolsep.


my $colcount = $columnareawidth / ($arr{width} + 1);
delete $arr{width};
$colcount = int $colcount; # truncate
#print qq{Column Count: $colcount<br>\n};

my $fontsize = $arr{fontsize};
delete $arr{fontsize};


# push entry text into array.
for ( 1..$entrylimit ) {
    my $entryname = 'entry'.$_;
    if ( $arr{$entryname} ){ # if it exists...push into array
	push @entry,$arr{$entryname};
    }
    delete $arr{$entryname};
}
my $entrysize = $#entry + 1;
#print qq{Entry size: $entrysize<br>\n};

if ($arr{repeat} and $entrysize){
    $repeatcount = $colcount / $entrysize;
    $repeatcount = int $repeatcount;
} elsif ($entrysize){
    $repeatcount = 1; # only do it once if not repeat.
} else { $repeatcount = 0;}

delete $arr{repeat};

my $shortname = "cmarksheet$$";
my $fileName = "$shortname.tex";

open(TEX,">$fileName") || die "Can't open tex file";
# Letter paper size is 279mm x 213mm
# 200mm wide - 50mm name, 20mm extra fld, leaves 130mm for columns.
# The tabcolsep of 1mm leaves 128 mm where each col is $width + 1mm wide.

if ( $defaultpapersize ) {
    $papersize = $defaultpapersize;
} else {
    $papersize = 'letterpaper';
}

print TEX "\\documentclass[$fontsize, $papersize]{article}
\\usepackage{array,newcent,rotating,colortbl,inputenc}
$a_latex_header
\\pagestyle{empty}
\\setlength{\\textwidth}{200mm}
\\setlength{\\textheight}{270mm}
\\setlength{\\hoffset}{-1.6in}
\\setlength{\\voffset}{-1.4in}
\\addtolength{\\evensidemargin}{0in}
\\addtolength{\\oddsidemargin}{0in}
\\setlength{\\tabcolsep}{1mm}
\\setlength{\\extrarowheight}{2mm}\n";
#\\newcolumntype{G}{>{\\columncolor[gray]{$grayshade}}p{$namewidth mm}}\n";

print TEX "\\begin{document}\n";

#Prep for loop through each subject.
my $sth = $dbh->prepare("select distinct eval.studnum, studentall.lastname, 
  studentall.firstname from eval
  left outer join studentall on eval.studnum = studentall.studnum
  where eval.subjcode = ?
  order by studentall.lastname, studentall.firstname");

# Prep for Course Name
my $sth1 = $dbh->prepare("select description from subject where subjsec = ?");

# Main Course Loop
foreach my $subjsec ( keys  %arr ) { # Loop through each selected subject
    #print qq{K: $subjsec V:$arr{$subjsec}<br>\n};

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

    # Get Course Name
    $sth1->execute($subjsec);
    my $desc = $sth1->fetchrow;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	
    # print New Page Header; reset counters.
    $linecount = 0; $studcount = 0;
    prHeader($subjsec,$desc);

    # Loop through and print all students
    foreach my $studnum (@studnum){
	$sth2 = $dbh->prepare("select lastname, firstname from studentall
          where studnum = ?");
	$sth2->execute( $studnum );
	if ($DBI::errstr) { print qq{$DBI::errstr}; die;}
	my ($lastname, $firstname) = $sth2->fetchrow;
	

	#print qq{LN: $lastname<br>\n};
	$linecount++;
	$studcount++;
	if ($linecount > $maxlines) { # print a new page header
	    # New Page Header
	    $linecount = 0;
	    print TEX "\\end{tabular}\\\\ \\newpage\n";
	    prHeader($subjsec,$desc);
	}
	# Print Normal Record.
	prRecord($lastname,$firstname,$studnum);
    }
    prStudCount();
    print TEX "\\end{tabular}\\\\ \\newpage\n";

}  # End of Loop for all subjects.

print TEX "\n\\end{document}\n";
close TEX;

system("$pdflatex $fileName >pdflog$$.txt");
system("mv $shortname.pdf $tchdownloaddir");
system("mv pdflog$$.txt $tchdownloaddir");
system("rm -f $shortname.*");

print qq{<h1><a href="$tchwebdownloaddir/$shortname.pdf">};
print qq{$lex{'View/Download'} $lex{Course} $lex{'Mark Sheets'}</a></h1>\n};
print qq{<p>[ <a href="$tchwebdownloaddir/pdflog$$.txt">$lex{'View Log File'}</a> ]</p>\n};
print qq{</center></body></html>\n};


#======== Functions Start Here ==============

#----------------
sub showStartPage {
#----------------

    # Get Teacher Name
    $sth = $dbh->prepare("select lastname,firstname from staff where userid = ?");
    $sth->execute( $userid );
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    my ($lastname, $firstname) = $sth->fetchrow;

    # Get Courses
    $sth = $dbh->prepare("select description, subjsec from subject
      where teacher = ? order by description");
    $sth->execute( $userid );
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my ( $desc, $subjsec ) = $sth->fetchrow ) {
	push @subject, "$desc:$subjsec";
    }

    print qq{<h1>$firstname $lastname - $lex{'Mark Sheets'}</h1>\n};
    print qq{<form action="$self" method="post">\n};
    print qq{<input type="hidden" name="page" value="1">\n};
    print qq{<table cellpadding="3" cellspacing="0" border="0">\n};
    print qq{<tr><td colspan="2"><b>Select Courses</b></td></tr>\n};

    foreach my $subj (@subject){
	my ($desc,$subjsec) = split ':',$subj;
	print qq{<tr><td class="la" colspan="2"><input type="checkbox" name="$subjsec" value="1">\n};
	print qq{ $desc ($subjsec)</td></tr>\n};

    }

    
    print qq{<tr><td colspan="2"><b>$lex{'Select Print Characteristics'}</b></td></tr>\n};

    # Cell Width
    print qq{<tr><td class="la">$lex{'Cell Width'}\n};
    print qq{<input type="text" name="width" style="width:3ch;" value="$width"> mm</td></tr>\n};

    # Students/Page
    print qq{<tr><td class="la">$lex{'Max Students/Page'} };
    print qq{ <input type="text" name="maxstudents" style="width:4ch;" value="$maxstudents"> };
    print qq{</td></tr>\n};

    # Font size.
    print qq{<tr><td class="la">$lex{'Font Size'} };
    print qq{ <select name="fontsize"><option>11pt</option><option>10pt</option>\n};
    print qq{<option>12pt</option></select></td></tr>\n};

    # Repeat
    print qq{<tr><td class="la">$lex{'Repeat Entry Elements?'} \n};
    print qq{<input type="checkbox" name="repeat" value="2"></td></tr>\n};

    
    print qq{<tr><td colspan="2"><b>$lex{'Text Elements (Column Titles)'}</b></td></tr>\n};
    for (1..$entrylimit){
	my $entrytxt = "entry$_";
	print qq{<tr><td class="la" colspan="2">$lex{Entry} $_\n};
	print qq{<input type="text" name="$entrytxt" }; 
	print qq{style="width:$maxentrysize}. 'ch'. qq{" maxlength="$maxentrysize"></td></tr>\n};
    }

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

    exit;

} # End of prEntryPage



#-----------
sub prHeader {
#-----------

    my ($subjsec,$description) = @_;

    ($description) = latex_filter( $description );

    print TEX "\\begin{tabular}{p{$namewidth mm}|";
    for (1..$colcount){	print TEX "p{$wi mm}|"; }
    print TEX "}\n";

    print TEX "{\\small Raw Score $lex{'Mark Sheet'}} ";
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\ \n";

    print TEX "\\raggedright\\bf $teachername ";
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\ \n";
    
    #    print TEX "{\\small $currdate} ";
    print TEX "{\\raggedright\\bf $description} ";
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\ \n";

    print TEX "{\\raggedright $subjsec}";
    my $remainder = $colcount  - ($repeatcount * $entrysize);
    #print qq{Remainder is: $remainder<br>\n};

    if ($repeatcount){
	for (1..$repeatcount){ # times to loop to print rotated text.
	    foreach my $txt (@entry){
		print TEX "&\\hfil\\rule{5pt}{0pt}\\begin{rotate}{90}";
		print TEX "$txt\\end{rotate}\\hfil\n";
	    }
	}
    }
    for (1..$remainder){ print TEX "& ";}
    print TEX "\\\\ \\hline\\hline\n";

} # End of prHeader


#-----------
sub prRecord { # print normal record (ie. line)
#-----------
    if ($alternatingcolor == 1){
	print TEX "\\rowcolor[gray]{$grayshade}";
	$alternatingcolor = 0;
    } else { $alternatingcolor = 1;}

    my ($lastname, $firstname, $studnum) = @_;
    print TEX "$lastname, $firstname";
    #print TEX " &{\\small $studnum}";
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\\\hline\n";

}

#--------------
sub prStudCount {
#--------------
    print TEX "\\hline\n$lex{Students}: $studcount";
    #print TEX "& ";
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\\\hline\n";
}

#------------
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
    $sth = $dbh->prepare("select distinct eval.studnum from eval
     left outer join studentall on studentall.studnum = eval.studnum 
     where eval.subjcode = ? 
     order by studentall.lastname, studentall.firstname");

    $sth->execute( $subjsec );
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr;}
    while (my $studnum = $sth->fetchrow){
	push @eval,$studnum;
    }
    
    # Load 'SortOrder' test if it exists...
    $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
	$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
	foreach my $en (@eval){
	    if (not $remove{$en}){ push @studnum, $en;}
	}
	return @studnum;

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