#! /usr/bin/perl
#  Copyright 2001-2019 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.

# 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)
#   4) Get a count of all objectives (all subjects) and all students. 
#   Then decide on a paper size and orientation. Since the priority is
#   for a per student list (one student per line), the priority is:
#   letter landscape, legal landscape

my %lex = ('Crosstab' => 'Crosstab',
	   'Mark Report' => 'Mark Report',
	   'Report Card System disabled. Please contact secretary.' => 
	     'Report Card System disabled. Please contact secretary.',
	   'Grade' => 'Grade',
	   'Page' => 'Page',
	   'Trm' => 'Trm',
	   'View/Download' => 'View/Download',
	   'Report Card' => 'Report Card',
	   'Main' => 'Main',
	   'Error' => 'Error',
	   'Papersize' => 'Papersize',
	   'Continue' => 'Continue',
	   'Legal' => 'Legal',
	   'Letter' => 'Letter',
	   'A4' => 'A4',
	   'Term' => 'Term',
	   'Subject' => 'Subject',
	   'or' => 'or',
	   'Blank=Current' => 'Blank=Current',
	   'No Student(s) Found' => 'No Student(s) Found',
	   'Select' => 'Select',
	   'Homeroom' => 'Homeroom',
	   'View Log File' => 'View Log File',
	   'Subject' => 'Subject',

	   );

my $self = 'rptsummxtab.pl';

use DBI;
use CGI;

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

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

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


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

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


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] $mday, $year";

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

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


# Get the values from configuration system
my $sth = $dbh->prepare("select datavalue from conf_system where dataname = ?");
foreach my $val ( qw( r_MarkField r_SupressSubject r_AdditionalComments )) {
    $sth->execute( $val  );
    my $datavalue = $sth->fetchrow;
    eval $datavalue;
    if ( $@ ) {
	print $lex{Error}. " $@<br>\n";
	die $lex{Error}. " $@\n";
    }
}


# Print the Page Header
my $title = "$lex{Crosstab} $lex{'Mark Report'}";
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\n};
print qq{$chartype\n</head><body>\n};
print qq{[ <a href="$homepage">$lex{Main}</a> |\n};
print qq{<a href="$reppage">$lex{'Report Card'}</a> ]\n};

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


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


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

# Check for entry errors
my $inputcount;
foreach my $val ( qw( grade homeroom subjsec )) {
    if ( $arr{$val} ) { $inputcount++; }
}
if ( $inputcount != 1 ) {
    print qq{<h1>$lex{Select} $lex{Error}</h1>\n};
    print qq{</body></html>\n};
    exit;    
}


# passed values
my $grade = $arr{grade};
delete $arr{grade};

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

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

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


my ( $papersize, $textwidth, $textheight,$maxcolumns );

if ( $arr{papersize} eq 'letter' or not $arr{papersize} ) {
    $papersize = 'letterpaper';
    $textwidth = $g_letterpaper_textwidth;
    $textheight = $g_letterpaper_textheight;
    $maxcolumns = $maxlettercols;

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

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

} 
delete $arr{papersize}; # no longer needed.



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


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

} elsif ( $homeroom ) {
    my $sth = $dbh->prepare("select studnum, lastname, firstname from student
        where homeroom = ? order by lastname, firstname");
    $sth->execute( $homeroom );
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    $studary = $sth->fetchall_arrayref;

} else { # subject-section based
    my $sth = $dbh->prepare("select distinct s.studnum, s.lastname, s.firstname 
     from studentall as s, eval as e where s.studnum = e.studnum and
     e.subjcode = ? order by lastname, firstname");
    $sth->execute( $subjsec );
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    $studary = $sth->fetchall_arrayref;
}

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


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

my %subjects = ();  # hash of $subjects{subjsec} = 1 format

if ( $grade or $homeroom ) {
    # Collect all the subjects taken by this grade of students.
    foreach my $studnum ( @$studary ) {
	# Note: $studnum is a reference/pointer.
	# Select subject-section by grade and term
    
	$subary = ();

	$sth1 = $dbh->prepare("select distinct subjcode from eval
          where term = ? and studnum = ?");
	$sth1->execute( $term, $$studnum[0]); 
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; } 
	$subary = $sth1->fetchall_arrayref;

	foreach my $subjsec ( @{$subary} ) {
	    $subjects{$$subjsec[0]} = 1;
	}

    } # End of Subject Selection loop.

} else { # we have selected a subject only;
    $subjects{$subjsec} = 1;
}

# Print out %subjects hash to see what we have...
#foreach my $subjsec ( sort keys %subjects ){ print qq{$subjsec<br>\n}; }


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) {

    # 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; }
    @subject = $sth->fetchrow;
    if ( not $subject[1] ){ next; }


    @subject = latex_filter( @subject );

    #print qq{Sub: ($subjsec) $subject[2]<br>\n};
    $objref = ();
    push @$objref, $subjsec;

    if ( $subject[37] ) {
	$subject[10] = "{\\bf $subject[37]} ".$subject[10]; #Add SDesc-1stobj
    } else { # no short description for this subject (smdesc), use subjsec
	$subject[10] = "{\\bf $subject[9]} ".$subject[10];
    }

    for ( my $i=10; $i<30; $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 ( 0..( $studcount - 1 ) ) {
    if ($_ % ($maxstudents - 1) == 0 and $_ != 0){
	# Minus 1 since we use array index (1 less)
	push @studbreakary, $_;
    }
}
push @studbreakary, $studcount; # put in the end...

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


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

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

print TEX "\\documentclass[11pt,$papersize,landscape]{article}
\\usepackage{array,rotating,inputenc}
$a_latex_header
\\pagestyle{empty}
\\setlength{\\textwidth}{$textwidth}
\\setlength{\\textheight}{$textheight}
\\setlength{\\hoffset}{-20mm}
\\setlength{\\voffset}{-50mm}
\\setlength{\\evensidemargin}{0mm}
\\setlength{\\oddsidemargin}{0mm}
\\setlength{\\tabcolsep}{1pt}
\\setlength{\\extrarowheight}{4pt}\n";


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


$pagecount = 1;
$currstud = 0;
foreach my $studbreak ( @studbreakary ) {
    $prevstud = $currstud;
    $currstud = $studbreak;

    $currsubj = 0;
    foreach my $subjbreak (@subjbreakary){
	$prevsubj = $currsubj;
	$currsubj = $subjbreak;

	&print_page($prevstud,$currstud -1,$prevsubj,$currsubj - 1,$pagecount);
	$pagecount++;
    }
    &print_page($prevstud, $currstud - 1,$currsubj,$#fullsubjary,$pagecount); 
    $pagecount++;

}

$logfile = "pdflog$$.txt";

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

print qq{<h1><a href="$webdownloaddir/$shortname.pdf">};
print qq{$lex{'View/Download'} $title</a></h1>\n};

print qq{[ <a href="$reppage">$lex{'Report Card'}</a> |\n};
print qq{<a href="$webdownloaddir/$logfile">$lex{'View Log File'}</a> ]\n};

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

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



#---------------
sub print_header {
#---------------
    # passed starting and ending values(indexes) for subject, pagenum
    my ($startsubj, $endsubj, $pagenum) = @_;
  
    print TEX "\\begin{tabular}{>{\\raggedright}b{49mm}";
    for (my $i = $startsubj; $i <= $endsubj; $i++){
	$subjref = $fullsubjary[$i];
	for (1..$#$subjref) { print TEX "p{6.15mm}";}
    }

    # Print the first cell.
    print TEX "}\n\\rule{0pt}{$offset}{\\bf\\large $schoolname}\\\\
     $currdate\\\\ ". $lex{Page}. ":~$pagenum  ". $lex{Trm}. ":~$term\\\\ ";
    if ( $grade ){
	print TEX $lex{Grade}. ": $grade\\\\";
    } elsif ( $homeroom ) {
	print TEX $lex{Homeroom}. ": $homeroom\\\\";
    } else {
	print TEX $lex{'Subject'}. ": $subjsec\\\\";
    }

    # Print the next cells.
    $count = 0;
    for (my $i = $startsubj; $i <= $endsubj; $i++){
	$subjref = $fullsubjary[$i];

	#if ($count != 0){print TEX "&";}
	#print TEX "\\begin{rotate}{45}{\\small $$subjref[1]}\\end{rotate}"; 

	for (1..$#$subjref) {
	    print TEX "&\n\\begin{rotate}{45}{\\small $$subjref[$_]}";
	    print TEX "\\end{rotate}"; 
	    $count++;
	}
    }

    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}|";} # C type is defined in TeX hdr
    }
    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 $studcount = 1;
    # foreach $studref (@$studary){
    for ($j = $startstud; $j <= $endstud; $j++){
	$studref = @$studary[$j];
	my $lastname = $$studref[1];
	my $firstname = $$studref[2];
	my $studnum = $$studref[0];

	print TEX "$lastname, $firstname ";

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


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

	    # Get his/her evaluation for this subject in this term

	    my $subjsec = $$subjref[0];
	    my $locobjcount = $#$subjref; # Number of objectives.
	    #print qq{ SUB: $subjsec OBJ: $locobjcount \n};
	    $sth1 = $dbh->prepare("select * from eval where 
              studnum = ? and term = ? and subjcode = ?");
	    $sth1->execute( $studnum, $term, $subjsec );
	    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	    my @evalrec = $sth1->fetchrow;

	    my $count = $locobjcount + 6;  # 7 is the first result in eval rec.
	    for (7..$count){
		$evalrec[$_] =~ s/\%//g; # strip percent signs
		print TEX "&\\hfil {\\footnotesize $evalrec[$_]}\\hfil ";
	    }
	}
	print TEX "\\\\\\hline\n";
	if (not ($studcount % 3)){ print TEX "\\hline\n";} # put in spacers.
	$studcount++;

    }  # End of Student For 

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

} # End of print_page function


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

    # Find all the grades
    my @grades;
    my $sth = $dbh->prepare("select distinct grade from student");
    $sth->execute;
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    while ( my $grade = $sth->fetchrow ) {
	push @grades, $grade;
    }

    # Find all the homerooms
    my @homerooms = ();
    $sth = $dbh->prepare("select distinct homeroom from student");
    $sth->execute;
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    while ( my $homeroom = $sth->fetchrow ) {
	push @homerooms, $homeroom;
    }

    # Find the subjects
    $sth = $dbh->prepare("select subjsec, description from subject");
    $sth->execute;
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    while ( my ( $subjsec, $desc ) = $sth->fetchrow ) {

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

	$subjects{"$desc ($subjsec)"} = $subjsec;
    }

    # Find the terms
    my @terms;
    $sth = $dbh->prepare("select distinct term from eval 
      where term is not NULL and term != '' order by term");
    $sth->execute;
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }
    while ( my  $trm = $sth->fetchrow ) {
	push @terms, $trm;
    }


    print qq{<form action="$self" method="post">\n};
    print qq{<input type="hidden" name="page" value="1">\n};
    print qq{<table cellspacing="0" cellpadding="3" border="0" style="border:1px solid gray;padding:0.4em;">\n};

    print qq{<tr><td colspan="2" class="bla">Select Students by</td></tr>\n};
    
    # Grade
    print qq{<tr><td class="bla">$lex{Grade}</td>};
    print qq{<td><select name="grade"><option></option>\n};
    foreach my $grade ( sort { $a <=> $b} @grades ) {
	print qq{<option>$grade</option>};
    }
    print qq{</select></td></tr>\n};

    # OR
    print qq{<tr><td colspan="2" class="bla">$lex{or}</td></tr>\n};

    # Homeroom
    print qq{<tr><td class="bla">$lex{Homeroom}</td><td><select name="homeroom"><option></option>\n};
    foreach my $homeroom ( sort { $a <=> $b} @homerooms ) {
	print qq{<option>$homeroom</option>};
    }
    print qq{</select></td></tr>\n};

    # OR
    print qq{<tr><td colspan="2" class="bla">$lex{or}</td></tr>\n};
    
    # Subject
    print qq{<tr><td class="bla">$lex{'Subject'}</td><td><select name="subjsec"><option></option>\n};
    foreach my $desc ( sort keys %subjects ) {
	print qq{<option value="$subjects{$desc}">$desc</option>};
    }
    print qq{</select></td></tr>\n};

    # Divider
    print qq{<tr><td colspan="2" class="bla"><hr></td></tr>\n};
    
    # Get Paper Size
    print qq{<tr><td class="bra"><i>$lex{Papersize}</i></td><td class="la">\n};
    print qq{<select name="papersize"><option value="letter">$lex{Letter}</option>};
    print qq{<option value="legal">$lex{Legal}</option>};
    print qq{<option value="a4">$lex{A4}</option></select></td></tr>\n};


    # Get the Term
    print qq{<tr><td class="bra"><i>$lex{Term}</i></td>\n};
    print qq{<td class="la"><select name="term">};

    foreach my $trm ( @terms ) {
	print qq{<option value="$trm">$trm</option>\n};
    }
    print qq{</select></td></tr>\n};


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

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

    exit;
}
