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

#  This file is part of Open Admin for Schools.

# This is a DUAL RUN script. It runs in /tcgi and also /cgi/repcard.

# Outline: This prints a full xtab report for a single grade/class. All
# objectives are perpendicular.

# Outline: 1) Find all the students in the group (class/section/grade).
#  2) Loop through all eval records for the selected term to find all
#  of the subjects.  
#  3) Load all subjects into a 2D array. Baseref->Arrayptr1->[0], etc. 
#   Order by subjsec, name of subject, then any objectives next (start 
#   at array index 2)

my %lex = ('Year End' => 'Year End',
	   'Report' => 'Report',
	   'Missing' => 'Missing',
	   'Group' => 'Group',
	   'Grade' => 'Grade',
	   'Homeroom' => 'Homeroom',
	   'View/Download' => 'View/Download',
	   'Download' => 'Download',
	   'File' => 'File',
	   'Teacher' => 'Teacher',
	   'Principal' => 'Principal',
	   'View Log File' => 'View Log File',
	   'Report Card' => 'Report Card',
	   'Main' => 'Main',
	   'Missing' => 'Missing',
	   'Short Subject Descriptions' => 'Short Subject Descriptions',
	   'Note' => 'Note',
	   'Page' => 'Page',
	   'Trm' => 'Trm',
	   'Term' => 'Term',
	   'No Student(s) Found' => 'No Student(s) Found',
	   'Y' => 'Y',
	   'Error' => 'Error',
	   'Continue' => 'Continue',
	   'Select by' => 'Select by',
	   'Paper Size' => 'Paper Size',
	   'Letter' => 'Letter',
	   'A4' => 'A4',
	   'Legal' => 'Legal',
	   'Student(s)' => 'Student(s)',
	   'Output' => 'Output',
	   'Combine failed' => 'Combine failed',
	   'End' => 'End',

	   );

my $self = 'rptfinalsumm.pl';

use DBI;
use CGI;
use Cwd;
use Number::Format qw(:all);


# Constants
# These two settings control the vertical height of the header.
my $objectivelength = 36; # number of characters to truncate objectives to.
my $offset = "25mm"; # Strut length in print_header fn.

my $maxstudents = 32; # Number of student rows per page; if you adjust above, 
# this may have to change also.

my $maxlegalcols = 16; # maximum number of columns per printed page.
my $maxlettercols = 16;



# Get current dir so know what path for config files.
my $configpath;
if (getcwd() =~ /tcgi/){ # we are in tcgi
    $configpath = '..'; # go back one to get to etc.
} else {
    $configpath = '../..'; # go back two to get to etc.
}

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

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

eval require "$configpath/lib/liblatex.pl";
if ( $@ ) {
    print $lex{Error}. ": $@<br>\n";
    die $lex{Error}. ": $@\n";
}

eval require "$configpath/lib/libattend.pl";
if ( $@ ) {
    print $lex{Error}. ": $@<br>\n";
    die $lex{Error}. ": $@\n";
}

# Get current dir so know what CSS to display;
if (getcwd() =~ /tcgi/){ # we are in tcgi
    $css = $tchcss;
}

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

if (length($mon) == 1){ $mon = '0'.$mon;}
if (length($mday) == 1){ $mday = '0'.$mday;}
my $currsdate = "$year-$mon-$mday";


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


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

my $term = $arr{term};

# Print the Page Header
my $title = "$lex{'Year End'} $lex{Report}";
print qq{$doctype\n<html><head><title>$title</title>
<link rel="stylesheet" href="$css" type="text/css">
$chartype\n</head><body>\n};

print qq{[ <a href="$homepage">$lex{Main}</a> \n};
if ( not (getcwd() =~ tcgi) ) { # not running in tcgi
    print qq{| <a href="$reppage">$lex{'Report Card'}</a>\n};
}
print qq{ ]<br>\n};

print qq{<h1>$title</h1>\n};



if ( not $arr{page} ) {
    showStartPage();

} else {
    delete $arr{page};
    
    if ( not $arr{term} ) {
	print qq{<h3>Missing End Term</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    if ( not $arr{group_value} ) {
	print qq{<h3>Missing Group Value</h3>\n};
	print qq{</body></html>\n};
	exit;
    }
    
    if ( $arr{output} eq 'pdf' ) {
	makePDF();

    } elsif ( $arr{output} eq 'csv') {
	makeCSV();
    }
}



#----------
sub makeCSV {
#----------

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

    use Text::CSV_XS;

    my $csv = Text::CSV_XS->new( {binary => 1} );

    # group and group_value
    my $group_value = $arr{group_value};
    my $group;
    if ( $arr{group} eq 'grade' ) {
	$group = 'grade';
    } else {
	$group = 'homeroom';
    }

    # $schoolstart and $schoolend defined in the admin.conf config file.
#    my $schoolDaysInYear = calcDaysOpen($schoolstart,$schoolend, $dbh);

    # Get Students First; by grade or homeroom.
    my $sth = $dbh->prepare("select studnum, lastname, firstname, grade from student
      where $group = ? order by lastname, firstname");
    $sth->execute( $group_value );
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }

    my (%names, %grades);  # names{studnum} = "last,first"; %grades{grade}[studnum];
    
    while ( my $ref = $sth->fetchrow_hashref ) {
	my %r = %$ref;
	$names{$r{studnum}} = qq{$r{lastname}, $r{firstname}};
	push @{ $grades{$r{grade}} }, $r{studnum};  # so we have sorted students.
	@test = @{ $grades{$r{grade}} };
    }

    if ( not %names ) {
	print qq{<h3>$lex{'No Student(s) Found'}</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    # Open output file
    # my $filename = "rptfinal$$.csv";
    my $filename = "rptfinal$$.csv";
    open (EX,">$filename") || die $lex{'Cannot open'}. " $fileName";

    
    # Get Courses
    my $sth1 = $dbh->prepare("select distinct subjcode from eval
			     where term = ? and studnum = ?");
    # Collect all the courses taken by this group of students.
    my %courses;
    foreach my $grade ( sort keys %grades ) {
	foreach my $studnum ( @{ $grades{$grade}} ) {
	    
	    $sth1->execute( $term, $studnum );
	    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }

	    while ( my $subjsec = $sth1->fetchrow ) {

		# Skip Unwanted Courses
		my ($subjcode, $section) = split('-', $subjsec);
		if ( $r_SupressSubject{$subjsec} or $r_SupressSubject{$subjcode} or 
		     $r_AdditionalComments{$subjsec} or $r_AdditionalComments{$subjcode} ) {
		    next; 
		}

		$courses{$subjsec} = 1;
	    }
	}
    }

    
    if ( not %courses ) {
	print qq{<h3>No Courses Found!</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    
    my %courseinfo; # $courseinfo{subjsec} = ref;
    my @courses; # set in loop below, giving correct ordering, just in case.
    foreach my $subjsec ( sort keys %courses ){

	# Get Course Information; pull in full record
	$sth = $dbh->prepare("select * from subject where subjsec = ?");
	$sth->execute( $subjsec );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $ref = $sth->fetchrow_hashref;
	$courseinfo{$subjsec} = $ref;
	my %r = %$ref;

	# If no short description, then long version truncated into short desc.
	if ( not $r{smdesc} ){
	    if ( length( $r{description} ) > $objectivelength ) { 
		$r{smdesc} = substr( $r{description},0,$objectivelength); # trunc full desc
	    } else { # length is ok.
		$r{smdesc} = $r{description};
	    }
	}

	push @courses, $subjsec;
	
    } # end of course loop


    use Text::CSV_XS;
    my $csv = Text::CSV_XS->new( {binary => 1} );


    # Header Line
    my @line;

    my $groupname;
    if ( $arr{group} eq 'grade' ) {
	$groupname ="$lex{Grade} $arr{group_value}";
    } else {
	$groupname = "$lex{Homeroom} $arr{group_value}";
    }
    push @line, $groupname;

    foreach my $subjsec ( @courses ) {
	my %r = %{ $courseinfo{$subjsec}};
	my $desc = $r{smdesc};
	if ( $arr{coursedesc} eq 'subjsec' ) {
	    $desc = $subjsec;
	} elsif ( $arr{coursedesc} eq 'both' ) {
	    $desc = $r{smdesc}. qq{ - $subjsec};
	}
	push @line, $desc;
    }

    push @line, "Attend";
    push @line, "Promotion";

    if ( $csv->combine( @line ) ) {
	my $record = $csv->string;
	print EX $record, "\r\n";

    } else {
	my $err = $csv->error_input;
	print qq{$lex{'Combine failed'}: $err\n\n};
    }
    # End of Header Line
    
    my $sth1 = $dbh->prepare("select grade from studentall where studnum = ?");    
    my $sth2 = $dbh->prepare("select count(*) from student where studnum = ?");    
    my $sth3 = $dbh->prepare("select endrptperiod from subject where subjsec = ?");
    my $sth4 = $dbh->prepare("select calcavg from subject where subjsec = ?");

#    foreach my $grade ( sort keys %grades ) {
#	my @student = @{ $grades{$grade} };
#	for my $studnum ( @student ) {
#	    print "SN:$studnum<br>\n";
#	}
#    }
    
    # Student Loop
    foreach my $grade ( sort keys %grades ) {
	my @students = @{ $grades{$grade}};
	foreach  my $studnum ( @students ) {

	    my @line;

	    # grade; needed for ppd.
	    $sth1->execute( $studnum );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	    my $gr = $sth1->fetchrow; # 

	    # Find $active value (ie. currently enrolled )
	    $sth2->execute( $studnum );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	    my $active = $sth2->fetchrow; # 

	
	    # calc attendance values for this student
	    # several values from admin.conf config file.
	    my $dayspresent = calcMyAttendance($studnum, $schoolstart, $schoolend,
					       $g_ppd{$gr},$active);
 	    $dayspresent = format_number($dayspresent, 2, 2);


	    push @line, "$names{$studnum} ($studnum)";


	    # Loop through each course for this student and print eval results.
	    foreach my $subjsec (@courses) {

		my $testavg;

		# Get the calcavg value (N or Y);
		$sth4->execute( $subjsec );
		if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
		my $calcavg = $sth4->fetchrow;
#		$calcavg = 'Y';
	    
		if ( $calcavg eq $lex{Y} ) { # average all terms to find values...
		    my $sth = $dbh->prepare("select $r_MarkField from eval where 
					    studnum = ? and subjcode = ?"); # equiv to $subjsec
		    $sth->execute( $studnum, $subjsec );
		    if ($DBI::errstr) {print $DBI::errstr; die $DBI::errstr; }
	    
		    my ($evalcount, $evaltotal);
		    while (my ($evalrec ) = $sth->fetchrow ) {
			if ($evalrec =~ m/\d/){ # if a digit...
			    $evaltotal += $evalrec;
			    $evalcount++;
			}
		    }
		
		    if ( $evalcount ){ # We have some tests.
			$testavg = $evaltotal / $evalcount;
			$testavg = format_number( $testavg, 0,0);
		    } else { 
			$testavg = ' ';
		    }

		} else { # We just find the endreporting period for this
		    # course and get that term's value from eval table;

		    # Get End Reporting period for final mark
		    $sth3->execute( $subjsec );
		    if ($DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		    my $endterm = $sth3->fetchrow;

		    my $sth = $dbh->prepare("select $r_MarkField from eval where 
					    studnum = ? and term = ? and subjcode = ?");
		    $sth->execute( $studnum, $endterm, $subjsec );
		    if ($DBI::errstr) {print $DBI::errstr; die $DBI::errstr; }
		    $testavg = $sth->fetchrow;
		    $testavg =~ s/\%//; # strip any percents.
		}

		# Note not really a 'test average' if a final mark only.
		push @line, $testavg;

	    } # end of courses loop

	    push @line, $dayspresent;
	    # print qq{Line:", @line, "<br>\n};

	    if ( $csv->combine( @line ) ) {
		my $record = $csv->string;
		print EX $record, "\r\n";

	    } else {
		my $err = $csv->error_input;
		print qq{$lex{'Combine failed'}: $err\n\n};
	    }

	    $studcount++;

	}  # End of Student Loop 

    } # end of grades loop
    
    # alter for tcgi (teacher) functioning
    if ( getcwd() =~ tcgi ) {
	$downloaddir = $tchdownloaddir;
	$webdownloaddir = $tchwebdownloaddir;
    }


    close EX;

    system("mv $filename $downloaddir");

    print qq{<h1><a href="$webdownloaddir/$filename">};
    print qq{$lex{Download} CSV $lex{File}</a></h1>\n};

    print qq{</body></html>\n};

    exit;

} # end of makeCSV




#----------
sub makePDF {
#----------

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

    # Set Local Term Value
    my $term = $arr{term};
    
    # Now passed: group and group_value
    my $group_value = $arr{group_value};
    my $group;
    if ( $arr{group} eq 'grade' ) {
	$group = 'grade';
    } else {
	$group = 'homeroom';
    }

    # Set paper size.
    my ( $papersize, $textheight, $textwidth, $maxcolumns );

    if ( $arr{papersize} eq 'legal' ) {
	$textwidth = $g_legalpaper_textwidth;
	$textheight = $g_legalpaper_textheight;
	$papersize = 'legalpaper';
	$maxcolumns = $maxlegalcols;

    } elsif ( $arr{papersize} eq 'a4' ) {
	$textwidth = $g_a4paper_textwidth;
	$textheight = $g_a4paper_textheight;
	$papersize = 'a4paper';
	$maxcolumns = $maxlettercols;

    } else { # Letter
	$textwidth = $g_letterpaper_textwidth;
	$textheight = $g_letterpaper_textheight;
	$papersize = 'letterpaper';
	$maxcolumns = $maxlettercols;
    }

    # $schoolstart and $schoolend defined in the admin.conf config file.
    my $schoolDaysInYear = calcDaysOpen($schoolstart,$schoolend, $dbh);

    # print qq{School Days: $schoolDaysInYear\n};


    # Must be passed a grade or homeroom.
    if ( not $group_value ) {  
	print qq{<h1>$lex{Missing} $lex{Group}</h1>\n};
	print qq{</body></html>\n};
	exit;
    }

    if ( $arr{studperpage} ) {
	$maxlines = $arr{studperpage};
    } else {
	$maxlines = $maxstudents;
    }


    # Get Students First; by grade or homeroom.
    my $sth = $dbh->prepare("select studnum, lastname, firstname, grade from student
      where $group = ? order by lastname, firstname");
    # Note: $grade here can actually be homeroom also...
    $sth->execute( $group_value );
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    $studary = $sth->fetchall_arrayref;

    # Test Print
    #    foreach my $ref ( @{$studary} ) {
    #     print "VAL:$ref  @{$ref}<br>\n";
    #    }
    

    my $studcount = $#$studary + 1;
    # print qq{Student Count: $studcount \n};

    if ( $studcount < 1 ) {
	print qq{<h1>$lex{'No Student(s) Found'}</h1>\n};
	print qq{</body></html>\n};
	exit;
    }


    # Setup TEX Code
    my $shortname = "summarkend$$";
    my $filename = "$shortname.tex";

    open(TEX,">$filename") || die "Can't open tex file";

    # removed landscape here...
    print TEX "\\documentclass[10pt,$papersize]{article}
\\usepackage{array,rotating,inputenc}
$a_latex_header
\\pagestyle{empty}
\\setlength{\\textwidth}{$textwidth}
\\setlength{\\textheight}{$textheight}
\\setlength{\\hoffset}{-13mm}
\\setlength{\\voffset}{-13mm}
\\setlength{\\topmargin}{0in}
\\setlength{\\headheight}{0mm}
\\setlength{\\headsep}{0mm}
\\setlength{\\parindent}{0mm}
\\setlength{\\evensidemargin}{0mm}
\\setlength{\\oddsidemargin}{0mm}
\\setlength{\\tabcolsep}{1pt}
\\setlength{\\extrarowheight}{4pt}\n";

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

    if ($divisionname){
	print TEX "{\\huge\\sf $divisionname}\n\n";
    } else {
	print TEX "{\\huge\\sf $schoolname}\n\n";
    }

    print TEX "{\\bf\\large $lex{'Year End'} $lex{Report}}\n\n";
    print TEX "{\\bf\\large ";
    if ( $group eq 'grade' ) {
	print TEX $lex{Grade};
    } else {
	print TEX $lex{Homeroom};
    }
    print TEX " $group_value -- $schoolyear}";
    print TEX "\\end{center}\n\n";

    # Collect all the courses taken by this group of students.
    foreach my $studref ( @$studary ) {
	# Note: $studref is a reference/pointer.
	# Select subject/section by grade and term
    
	my $subary;

	my $sth1 = $dbh->prepare("select distinct subjcode from eval
          where term = '$term' and studnum = '$$studref[0]'");

	$sth1->execute; 
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } 
	$subary = $sth1->fetchall_arrayref;

	foreach my $subjsec ( @{$subary} ) {
	    my ($subj,$section) = split('-',$$subjsec[0]);

	    # We have to put ONE version of subject in IF grade
	    if ($tempsubject{$subj}  and  $group eq $lex{Grade} ){
		# If already in tempsubject and grade is group, don't do
		#  Nothin'.
	    } else { # Act normal; put subject/section into array.
		$subjects{$$subjsec[0]} = 1;
		$tempsubject{$subj}= 1;
	    }
	}

    }

    my $objcount = 0; # Count Objectives...
    my $subjectbreakpoint = 0;

    # Add their subjects (and objectives) to a 2D array called fullsubjary
    # Each row in array has subjsec, and then objectives.
    foreach my $subjsec ( sort keys %subjects ){

#	print "Subjsec:$subjsec<br>\n";
	
	# Skip Unwanted Subjects
	my ($subjcode, $dud) = split('-', $subjsec);
	if (   $r_SupressSubject{$subjsec} or $r_SupressSubject{$subjcode} or 
	       $r_AdditionalComments{$subjsec} or $r_AdditionalComments{$subjcode} ) {
	    next; 
	}

	# Get Subject Information; pull in full subject record
	$sth = $dbh->prepare("select * from subject where subjsec = ?");
	$sth->execute( $subjsec );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my @subject = $sth->fetchrow;

	@subject = latex_filter( @subject );

	my $objref;
	push @$objref, $subjsec;

	# If no short description, then long versions used.
	if ( not $subject[37] ){
	    if ( length( $subject[2] ) > $objectivelength ) { 
		$subject[10] = substr( $subject[2],0,$objectivelength); # trunc full desc
	    } else {
		$subject[10] = $subject[2];
	    }
	    $subject[10] = "{\\bf $subject[10]} ";
	    $missingflag = 1; # used below on HTML output.
	} else {
	    $subject[10] = "{\\bf $subject[37]} "; #~~Short Description
	}

	for ( my $i=10;$i<11;$i++){ 
	    if ($subject[$i]){
		# Truncate the objective length.
		if ( length( $subject[$i] ) > $objectivelength){ 
		    $subject[$i] = substr($subject[$i],0,$objectivelength);
		}
		push @$objref,$subject[$i]; $objcount++;
	    } 
	}

	#print qq{OBJ:$objcount BP:$subjectbreakpoint <br>\n";
	if ($objcount > $maxcolumns){

	    # push subjbreakpoint into subject break array
	    push @subjbreakary,$subjectbreakpoint;
	    $objcount = 0; # reset objective count
	} 
	# This is incremented AFTER the test for too large.
	$subjectbreakpoint++;
	# objcount is reset, but subjectbreakpoint keeps going/growing.

	push @fullsubjary, $objref;  # Make 2D array

    }

    # Test print full subject array.
#    foreach my $subj ( @fullsubjary ) {
#        print qq{<br>Sub:$$subj[0]\n};
#    }
    
    # Now get break points for subjects and students.
    # print qq{Subject Break points: ", @subjbreakary, "<br>\n};

    for my $i ( 0..($studcount - 1) ) {
	if ($i % ($maxstudents - 1) == 0 and $i != 0){
	    # Minus 1 since we use array index (1 less)
	    push @studbreakary,$i;
	}
    }
    push @studbreakary, $studcount; # put in the end...

#    print qq{<br>Student Break Array: }, @studbreakary, qq{<br>\n};

    my $firstflag = 1;
    $pagecount = 1;
    $currstud = 0;
    foreach $studbreak ( @studbreakary ) {
	$prevstud = $currstud;
	$currstud = $studbreak;
	
	$currsubj = 0;
	foreach $subjbreak (@subjbreakary){
	    $prevsubj = $currsubj;
	    $currsubj = $subjbreak;

	    &print_page($prevstud,$currstud -1,$prevsubj,$currsubj - 1,$pagecount);

	    $pagecount++;
	    print TEX "\\newpage\n\n";
	}

	if (not $firstflag){ print TEX "\\newpage\n\n";} else { $firstflag = 0;}
	print_page($prevstud, $currstud - 1,$currsubj,$#fullsubjary,$pagecount); 
	$pagecount++;
    }

    print TEX "\n\\parbox{152mm}{\\vspace{13mm}\\underline{\\hspace{63mm}}";
    print TEX "\\hfill\\underline{\\hspace{63mm}}\n\n";
    print TEX "{\\small ". $lex{Teacher}. "}\\hfill{\\small ". $lex{Principal}. "}}\n";
    print TEX "\\end{document}\n";
    close TEX;

    
    # alter for tcgi functioning
    if ( getcwd() =~ tcgi ) {
	$downloaddir = $tchdownloaddir;
	$webdownloaddir = $tchwebdownloaddir;
    }

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

    print qq{<h1><a href="$webdownloaddir/$shortname.pdf">\n};
    print qq{$lex{'View/Download'} $title</a></h1>\n};
    print qq{[ <a href="$reppage">$lex{'Report Card'}</a> | \n};
    print qq{<a href="$webdownloaddir/pdflog$$.txt">$lex{'View Log File'}</a> ]\n};

    if ( $missingflag ) {
	print qq{<p><b>$lex{Note}:</b> };
	print qq{$lex{Missing} $lex{'Short Subject Descriptions'}<br>\n};
	print qq{ Full length subject descriptions are being used. This will<br>\n};
	print qq{look somewhat ugly, but does indicate the subject.</p>\n};
    }

    print qq{</body></html>\n};

    exit;

} # end of makePDF





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

    # Find all of the term end dates (not all patterns).
    my $sth = $dbh->prepare("select distinct endrptperiod from subject order by endrptperiod");
    $sth->execute;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }


    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};

    # Select Students
    print qq{<tr><td class="bra">$lex{'Select by'}</td>\n};
    print qq{<td><select name="group"><option value="grade">$lex{Grade}</option>\n};
    print qq{<option value="homeroom">$lex{Homeroom}</option>\n};
    print qq{</select>\n};
    print qq{<input type="text" name="group_value" size="10"></td></tr>\n};


    # Term Select
    print qq{<tr><td class="bra">$lex{End} $lex{Term}</td><td class="la">};
    print qq{<select name="term"><option></option>\n};
    while ( my $endterm = $sth->fetchrow ) {
	if ( not $endterm ) { next; }
	print qq{<option value="$endterm">$endterm</option>\n};
    }
    print qq{</select></td></tr>\n};


    # Output Type
    print qq{<tr><td class="bra">$lex{Output}</td>\n};
    print qq{<td><select name="output"><option value="pdf">PDF</option>\n};
    print qq{<option value="csv">CSV</option></select></td></tr>\n};


    # CSV Course Name Option
    print qq{<tr><td class="bra">CSV - Course Desc Type</td>\n};
    print qq{<td><select name="coursedesc">};
    print qq{<option value="smdesc">Small Description</option>\n};
    print qq{<option value="subjsec">Subject-Section</option>\n};
    print qq{<option value="both">Both</option>\n};
    print qq{</select></td></tr>\n\n};

    # Students / Page
    print qq{<tr><td class="bra">PDF - $lex{'Student(s)'}/$lex{Page}</td>\n};
    print qq{<td><input type="text" name="studperpage" size="4" value="$maxstudents">};
    print qq{</td></tr>\n};


    # Paper Size
    print qq{<tr><td class="bra">PDF $lex{'Paper Size'}</td>\n};
    print qq{<td><select name="papersize">};
    print qq{<option value="letter">$lex{Letter}</option>\n};
    print qq{<option value="a4">$lex{A4}</option>\n};
    print qq{<option value="legal">$lex{Legal}</option>\n};
    print qq{</select></td></tr>\n\n};

    
    # Continue
    print qq{<tr><td></td><td align="left">\n};
    print qq{<input type="submit" value="$lex{Continue}"></td></tr>\n};

    print qq{</table></form>\n};
    print qq{</body></html>\n};

    exit;

}


#---------------
sub print_header {
#---------------

    # passed starting and ending values(indexes) for subject, pagenum
    my ($startsubj, $endsubj, $pagenum) = @_;
  
    print TEX "\\begin{tabular}{p{49mm}";
    for (my $i = $startsubj; $i <= $endsubj; $i++){
	$subjref = $fullsubjary[$i];
	for (1..$#$subjref) { print TEX "p{6.15mm}";}
    }
    # Print section for attendance and promotion text.
    print TEX "p{7mm}l"; # Note Left Alignment here.


    print TEX "}\n\\parbox[b]{47mm}{\\raggedright{\\bf\\large $schoolname}\\\\
     $currdate\\hfill\\\\ $lex{Page}:~$pagenum  $lex{Term}:~$term\\\\ ";

    if ( $group eq 'grade' ){
	print TEX $lex{Grade}. ": $group_value } &\n";
    } else {
	print TEX $lex{Homeroom}. ": $group_value } &\n";
    }

    $count = 0;
    for ($i = $startsubj; $i <= $endsubj; $i++){
	$subjref = $fullsubjary[$i];

	if ($i != $startsubj){print TEX "&";}
	print TEX "\\begin{rotate}{90}{\\small $$subjref[1]}\\end{rotate}"; 
	for (2..$#$subjref) {
	    print TEX "&\\begin{rotate}{90}{\\small $$subjref[$_]}\\end{rotate}"; 
	}
    }
    print TEX "&\\rule{0mm}{2mm}\\begin{sideways}{\\small\\bf Attend }\\end{sideways}"; 
    print TEX "&\\parbox[b]{50mm}
    {\\raggedright\\small P=Complete~Promotion, R=Repeating~Years~Work,
    SP=Social~Promotion, MA=Modified/Alternate~Program}";

    print TEX "\\\\\n\\end{tabular}\n\n";

    # Now print header section WITH dividers
    print TEX "\\begin{tabular}{p{45mm}|";

    # foreach $subjref (@fullsubjary){

    for ( my $i = $startsubj; $i <= $endsubj; $i++ ) {
	$subjref = $fullsubjary[$i];
	for ( 1 .. $#$subjref ) { print TEX "p{6mm}|";}
    }
    # Print section for attendance and promotion text.
    print TEX "p{12mm}|p{25mm}|";
    print TEX "}\\hline\n";

}


#--------------
sub print_page {
#--------------

    # print a single page when passed start, end values for students
    # as well as subjects. (ie. defining a block)

    my ($startstud, $endstud, $startsubj, $endsubj,$pagenum) = @_;

#    print qq{Page $pagenum Stud: $startstud - $endstud \n};
#    print qq{Sub: $startsubj - $endsubj<br>\n};

    print_header( $startsubj, $endsubj, $pagenum );

    
    my $sth3 = $dbh->prepare("select endrptperiod from subject where subjsec = ?");

    my $studcount = 1;
    # foreach $studref (@$studary){
    for ( my $j = $startstud; $j <= $endstud; $j++ ) {
	$studref = @$studary[$j];
	my $lastname = $$studref[1];
	my $firstname = $$studref[2];
	my $studnum = $$studref[0];
	my $gr = $$studref[3];  # grade; needed if homeroom group for ppd.


	# Find $active value (ie. currently enrolled )
	my $sth = $dbh->prepare("select studid from student where studnum = ?");
	$sth->execute( $studnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	my $active = $sth->fetchrow;

	# calc attendance values for this student
#	print "Start:$schoolstart End:$schoolend GR:$gr Active:$active<br>\n";
	my $dayspresent = calcMyAttendance($studnum, $schoolstart, $schoolend, $g_ppd{$gr}, $active); 
	$dayspresent = format_number($dayspresent, 2, 2);

	
	print TEX "$lastname, $firstname ";

	# Setup for reading subject table calcavg value.
	my $sth2 = $dbh->prepare("select calcavg from subject where subjsec = ?");

	# Loop through each subject for this student and print eval results.

	for ( my $i = $startsubj; $i <= $endsubj; $i++ ) {
	    $subjref = $fullsubjary[$i];

	    # Get his/her evaluation for this subject in this term
	    my $subjsec = $$subjref[0];
	    my $testavg;

	    # Get the calcavg value (N or Y);
	    $sth2->execute( $subjsec );
	    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
	    my $calcavg = $sth2->fetchrow;
	    
	    if ( $calcavg eq $lex{Y} ) { # average all terms to find values...

		my $locobjcount = $#$subjref; # Number of objectives.
		#print qq{ SUB: $subjsec OBJ: $locobjcount \n};

		my $sth1 = $dbh->prepare("select $r_MarkField from eval where 
                 studnum = ? and subjcode = ?"); #~~instead of $subjsec
		$sth1->execute( $studnum, $subjsec );
		if ($DBI::errstr) {print $DBI::errstr; die $DBI::errstr; }
	    
		my ($evalcount, $evaltotal);
		while (my ($evalrec ) = $sth1->fetchrow ) {
		    if ($evalrec =~ m/\d/){ # if a digit...
			$evaltotal += $evalrec;
			$evalcount++;
		    }
		}
		
		if ( $evalcount ){ # We have some tests.
		    $testavg = $evaltotal / $evalcount;
		    $testavg = format_number( $testavg, 0,0);
		} else { 
		    $testavg = ' ';
		}

	    } else { # We just find the endreporting period for this
		# subject and get that term's value from eval table;

		# Get End Reporting period for final mark
		$sth3->execute( $subjsec );
		if ($DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		my $endrptperiod = $sth3->fetchrow;
		
		my $sth1 = $dbh->prepare("select $r_MarkField from eval where 
                 studnum = ? and term = ? and subjcode = ?");
		$sth1->execute( $studnum, $endrptperiod, $subjsec );
		if ($DBI::errstr) {print $DBI::errstr; die $DBI::errstr; }
		$testavg = $sth1->fetchrow;
		$testavg =~ s/\%//; # strip any percents.

	    }

	    # Note not really a 'test average' if a final mark only.
	    print TEX "&\\hfil{\\small $testavg}\\hfil";

    

	}

	print TEX "&\\hfil $dayspresent \\hfil& "; # End of line (with space)
	print TEX "\\\\\\hline\n";
	if (not ($studcount % 3)){ print TEX "\\hline\n";} # put in spacers.
	$studcount++;

    }  # End of Student For 

    print TEX "\\end{tabular}\n\n";

} # End of print_page function



#-----------------
sub calcMyAttendance {
#-----------------

    my ($studnum, $startdate, $enddate, $periodsperday,$active) = @_;

    my @enrolblocks = findEnrollmentBlocks($studnum, $schoolstart, $currsdate, $dbh);

    my $absent = 0; my $daysEnrolled = 0; my $late = 0; 

    foreach my $block (@enrolblocks){
	my $start = $block->{start};
	my $end = $block->{end};
	# print qq{ST: $start END: $end };
	my $blocklength = calcDaysOpen($start,$end, $dbh);
	# print qq{BlockLen: $blocklength<br>\n};
	$daysEnrolled += $blocklength;
	#print qq{STUD: $studnum ST: $start END: $end\n};

	my $sth = $dbh->prepare("select * from attend 
          where studentid='$studnum' and 
          to_days(absdate) >= to_days('$start') and 
          to_days(absdate) <= to_days('$end') 
          order by absdate,period");
	$sth->execute;
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr;}

	while (@absence = $sth->fetchrow){
	    if ($absence[3] =~ /$absentString/) { $absent++; }
	    #if ($absence[3] =~ /$lateString/) { $late++; }
	}
	#print qq{ABS: $absent<br>\n};
    }


    if ( not $periodsperday ) { 
	print qq{PPD: $periodsperday not defined for $studnum<br>\n}; 
    }

    my $present;
    if ( $periodsperday ) {
	$absent = $absent/$periodsperday; #convert periods into days
	$present = $daysEnrolled - $absent;
    } else {
	$present = 0;
    }

    return $present;
}
