#! /usr/bin/perl
#  Copyright 2001-2011 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";
}

# Now loaded directly from table
# Load $additionalcomments value; skip this subject
#eval require "../../etc/repcard.conf";
#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 "$doctype\n<html><head><title>$title</title>
<link rel=\"stylesheet\" href=\"$css\" type=\"text/css\">
$chartype\n</head><body>[ <a href=\"$homepage\">$lex{Main}</a> |\n";
print "<a href=\"$reppage\">$lex{'Report Card'}</a> ]\n";

print "<center><h1>$title</h1></center>\n";


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

#foreach my $key ( sort keys %arr ) { print "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 "<h1>$lex{Select} $lex{Error}</h1>\n";
    print "</body></html>\n";
    exit;    
}


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

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

my ($dud, $subjsec) = split /\(/, $arr{subjsec};
chop $subjsec; # remove trailing parens
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;
}

# If not set, get the current term.
if ( not $term ) {
    open(TERM, "../../etc/term") || die "Can't find the term number!";
    $term = <TERM>;
    close TERM;
}

if ($term == 0){
    print "<h1>$lex{'Report Card System disabled. Please contact secretary.'}</h1>\n";
    print "</body></html>\n";
    exit;
}


# 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 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 "<h1>$lex{'No Student(s) Found'}</h1>\n";
    print "</body></html>\n";
    exit;
}


$studcount = $#$studary + 1;
#print "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 "$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 "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 "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 "<br>Sub: $$subj[0] \n"; }


# Now get break points for subjects and students.
# print "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 "<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 "<center><h1><a href=\"$webdownloaddir/$shortname.pdf\">";
print "$lex{'View/Download'} $title</a></h1>\n";

print "[ <a href=\"$reppage\">$lex{'Report Card'}</a> |\n";
print "<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 "</center></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 "Page $pagenum Stud: $startstud - $endstud \n";
    # print "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 " 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 "<center><form action=\"$self\" method=\"post\">\n";
    print "<input type=\"hidden\" name=\"page\" value=\"1\">\n";
    print "<table cellspacing=\"0\" cellpadding=\"3\" border=\"0\">\n";

    print "<tr><td class=\"ra\"><i>$lex{Grade}</i></td>";
    print "<td><select name=\"grade\"><option></option>\n";
    foreach my $grade ( sort { $a <=> $b} @grades ) {
	print "<option>$grade</option>";
    }
    print "</select>\n&nbsp;<b>". $lex{or}. "</b>&nbsp;<i>";

    print $lex{Homeroom}. "</i> <select name=\"homeroom\"><option></option>\n";
    foreach my $homeroom ( sort { $a <=> $b} @homerooms ) {
	print "<option>$homeroom</option>";
    }
    print "</select>\n&nbsp;<b>". $lex{or}. "</b>&nbsp;<i>\n";

    # Get the Subjects
    print "$lex{'Subject'}</i> <select name=\"subjsec\"><option></option>\n";
    foreach my $desc ( sort keys %subjects ) {
	print "<option value=\"$subjects{$desc}\">$desc</option>";
    }
    print "</select></td></tr>\n";


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


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

    # Just in case of older configurations.
#    if ( not %g_TermDisplay ) {
#	%g_TermDisplay = %r_TermDisplay;
#    }

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


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

    print "</body></html>\n";

    exit;
}
