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

my %lex = ('Main' => 'Main',
	   'No Student(s) Found' => 'No Student(s) Found',
	   'View/Download' => 'View/Download',
	   'Custom Classlist' => 'Custom Classlist',
	   'Main' => 'Main',
	   'View Log File' => 'View Log File',
	   'Continue' => 'Continue',
	   'Homeroom' => 'Homeroom',
	   'Grade' => 'Grade',
	   'Blank=All' => 'Blank=All',
	   'Cell Width' => 'Cell Width',
	   'Maximum' => 'Maximum',
	   'Page' => 'Page',
	   'Students' => 'Students',
	   'Select by' => 'Select by',
	   'Repeat Entry Elements' => 'Repeat Entry Elements',
	   'Classlist' => 'Classlist',
	   'Rm' => 'Rm',
	   'Students' => 'Students',
	   'Paper Size' => 'Paper Size',
	   'Letter' => 'Letter',
	   'Legal' => 'Legal',
	   'A4' => 'A4',
	   'Font Size' => 'Font Size',
	   'Gray Shade' => 'Gray Shade',
	   'Smaller=Darker' => 'Smaller=Darker',
	   'Include' => 'Include',
	   'Student Number' => 'Student Number',
	   'Additional Field' => 'Additional Field',
	   'Error' => 'Error',
	   'Y' => 'Y',
	   'Width' => 'Width',
	   'Sort by' => 'Sort by',
	   'Name' => 'Name',
	   'Single Value Only' => 'Single Value Only',
	   'Not Found' => 'Not Found',

	   );

my $self = 'rptcustomclasslist.pl';

use DBI;
use CGI;
use Cwd;

# Configurable settings
my $maxstudents = 30; # maximum students per page.
my $width = 8;  # default width of columns, 8 mm;
my $defaultgrayshade = '0.90';  # shading for alternate rows

my $entrylimit = 18; # Max entries allowed for rotated text.
my $maxentrysize = 14; # Maximum number of characters for the entry

my $namewidth = 50; # Width of the first 'Name' column in mm.
my $studnumwidth = 15; # Width of local student number.
my $extrafieldsize = 20; # default extra field in mm; overridden on start page (possible)

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 $q = new CGI;
print $q->header( -charset, $charset );
my %arr = $q->Vars;


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

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


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

my $title = "$lex{'Custom Classlist'}";
print "$doctype\n<html><head><title>$title</title>\n";
print "<link rel=\"stylesheet\" href=\"$css\" type=\"text/css\">\n";
print "$chartype\n</head><body style=\"padding:1em 5em;\">\n";
print "<div>[ <a href=\"$homepage\">$lex{Main}</a> ]</div>\n";

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


# Get values for Customization, then exit;
# Values passed are width, maxstudents, repeat, entry1 to entry8
if ( not $arr{page} ) {
    showStartPage();
}

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

if ( $arr{fieldwidth} ) {
    my $extrafieldsize = $arr{fieldwidth};
}
delete $arr{fieldwidth};

# Setup Extra fields
my ( $studnumfield, $extrafield, $extrafieldName );
if ( $arr{studnumfield} ) {
    $studnumfield = 1;
    delete $arr{studnumfield};
}
if ( $arr{extrafield} ) {
    ( my $dud, $extrafield ) = split(/\(/, $arr{extrafield});
    chop $extrafield; # remove trailing parenthesis
    my $sth = $dbh->prepare("select fieldname from meta where tableid = 'student' and fieldid = ?");
    $sth->execute( $extrafield );
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    $extrafieldName = $sth->fetchrow;
    ( $extrafieldName ) = latex_filter( $extrafieldName );
    delete $arr{extrafield};
}


# Set Sizes
# Letter paper size is 279mm x 216mm
# 200mm wide - 50mm name, 20mm extra fld, leaves 130mm for columns.
# a4 paper is 297mm x 210mm; legal is 356mm x 216mm

# The tabcolsep of 1mm leaves 128 mm where each col is $width + 1mm wide.
my $fontsize = $arr{fontsize}. 'pt';

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

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

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

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

} 


# Restrict Gray Shading values
if ( $arr{grayshade} > 1 ) { $arr{grayshade} = 1; }
if ( $arr{grayshade} < 0.5 ) { $arr{grayshade} = 0.5; }

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

my $availablesize = $textwidth - $namewidth;

# Set column count after shrinking available size
if ( $studnumfield ) { $availablesize -= $studnumwidth; }
if ( $extrafield ) { $availablesize -= $extrafieldsize; }

my $colcount = $availablesize / ($arr{width} + 1);
$colcount = int $colcount; # truncate


# Filter for Passed values that might crash LaTeX 
foreach my $key ( keys %arr ) {
    ( $arr{$key} ) = latex_filter( $arr{$key} );
}

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


# push entry text into array.
for (1..$entrylimit){
    my $entryname = 'entry'.$_;
    if ($arr{$entryname}){ # if it exists...push into array
	push @entry,$arr{$entryname};
    }
}
my $entrysize = $#entry + 1;
#print "Entry size: $entrysize\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;}
#print "Repeat Count: $repeatcount\n";


my $shortname = "cclasslist$$";
my $filename = "$shortname.tex";

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

print TEX "\\documentclass[$fontsize,$papersize ]{article}
\\usepackage{array,newcent,rotating,colortbl,inputenc}
$a_latex_header
\\pagestyle{empty}
\\setlength{\\textwidth}{$textwidth}
\\setlength{\\textheight}{$textheight}

\\setlength{\\hoffset}{-36mm}
\\setlength{\\voffset}{-36mm}
\\addtolength{\\evensidemargin}{0mm}
\\addtolength{\\oddsidemargin}{0mm}
\\setlength{\\tabcolsep}{1mm}
\\setlength{\\extrarowheight}{2mm}
\\newcolumntype{G}{>{\\columncolor[gray]{1.00}}p{$namewidth mm}}\n";
# Note above... a columncolor of 1.00 means white, smaller number is darker.

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

my $select; 
my $group;
# NOTE: 2 values passed: group (either grade or homeroom) and groupvalue
if ( $arr{group} eq 'homeroom' and $arr{groupvalue} )  {
    my $grpvalue = $dbh->quote( $arr{groupvalue} );
    $select = "where homeroom = $grpvalue";
    $group = 'homeroom';

} elsif ( $arr{group} eq 'grade' and $arr{groupvalue} )  {
    my $grpvalue = $dbh->quote( $arr{groupvalue} );
    $select = "where grade = $grpvalue";
    $group = 'grade';

} else {
    $group = $arr{group};
}



# Set sorting order
my $sortorder = 'order by lastname, firstname';
if ( $arr{sortorder} eq 'homeroom' ) {
    $sortorder = 'order by homeroom, lastname, firstname';

} elsif ( $arr{sortorder} eq 'grade' ) {
    $sortorder = 'order by grade, lastname, firstname';
}



my $sth = $dbh->prepare("select lastname, firstname, grade, 
  homeroom, studnum from student $select $sortorder");
$sth->execute;
if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }

$rows = $sth->rows;
if ( $rows < 1 ) { # No students found...
    print "<h1>$lex{'No Student(s) Found'}!</h1>\n";
    print "[ <a href=\"$homepage\">$lex{Main}</a> ]\n"; 
    print "</body></html>\n";
    system("rm -f $shortname.*"); #cleanup
    exit;
}


my $curroom = -1;
my $teachername;



for my $i ( 1..$rows ) {

    my ( $lastname, $firstname, $grade, $homeroom, $studnum ) = $sth->fetchrow;   

    $oldroom = $curroom;
    if ( $group eq 'grade' ) {
	$curroom = $grade;
    } else {
	$curroom = $homeroom;
    }

    if ( $oldroom eq $curroom or $arr{sortorder} eq 'name' ) { # We have another record for same page

	$linecount++;
	$studcount++;
	if ( $linecount > $maxlines or $i == 1 ) { # We'll print a new page header here
	    # New Page Header
	    $linecount = 0;
	    if ( $i != 1 ) { print TEX "\\end{tabular}\\\\ \\newpage\n"; }
	    prHeader($teachername, $curroom );
	}
	# Print Normal Record.
	prRecord($lastname, $firstname, $studnum);

    } else {  # We are starting a new page

	# Get Teacher(s) Name for the room.
	if ($curroom and $curroom != -1) {
	    $sth1 = $dbh->prepare("select sal, lastname from staff as s, staff_multi as sm
              where s.userid = sm.userid and field_name = 'homeroom' and field_value = ?");
	    $sth1->execute( $curroom );
	    if ($DBI::errstr) { print "Teacher Error: $DBI::errstr"; die $DBI::errstr; }
	    $teachrows = $sth1->rows;
	    $teachername = '';
	    for ( 1..$teachrows ){ 
		my ($sal, $lastname) = $sth1->fetchrow;
		$teachername .= " $sal~$lastname";
	    }

	} # End of teacher name

	if ( $i != 1 ) {
	    $studcount++;
	    prStudCount();
	    print TEX "\n\\end{tabular} \n\n \\newpage \n";
	}

	$linecount = 0;
	$studcount = 0;
	prHeader($teachername, $curroom );
	prRecord($lastname, $firstname, $studnum);
    } # End of Starting a New Page.

}  # End of Loop for all students


$studcount++;
prStudCount();
print TEX "\\end{tabular}\\\\ \n\\end{document}";
close TEX;

# Solve download location issues with cgi vs tcgi..
# Get current dir so know what CSS to display;
if (getcwd() =~ /tcgi/){ # we are in 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 "<h1><a href=\"$webdownloaddir/$shortname.pdf\">";
print "$lex{'View/Download'} $lex{'Custom Classlist'}</a></h1>\n";
print "<p>[ <a href=\"$homepage\">$lex{Main}</a> |\n <a href=\"$webdownloaddir/pdflog$$.txt\">";
print "$lex{'View Log File'}</a>\n ]</p>";

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



#----------------
sub showStartPage { # Entry Values for Custom Script
#----------------

    # Read student fields, and defaults into a @fields and %fieldname hash.
    my $sth = $dbh->prepare("select fieldid, fieldname
    from meta where tableid = 'student' order by fieldname");
    $sth->execute;
    my @fields = (); 
    my %fieldnames = ();
    while ( ( my $fieldid, $fieldname ) = $sth->fetchrow ) {
	$fieldname =~ s/\(//g;
	$fieldname =~ s/\)//g; # strip parenthese. (sp?)
	push @fields, $fieldid;
	$fieldname{ $fieldid } = $fieldname;
    }


    print "<form action=\"$self\" method=\"post\">\n";
    print "<input type=\"hidden\" name=\"page\" value=\"1\">\n";

    print "<table cellpadding=\"3\" cellspacing=\"0\" border=\"0\">\n";

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

    # Student Group
    print "<tr><td class=\"ra\">$lex{'Select by'}</td>";
    print "<td><select name=\"group\"><option value=\"grade\">$lex{Grade}</option>";
    print "<option value=\"homeroom\">$lex{Homeroom}</option></select>\n";
    print " <input type=\"text\" name=\"groupvalue\" size=\"4\" value=\"$arr{homeroom}\">\n";
    print " $lex{'Blank=All'}, $lex{'Single Value Only'}</td></tr>\n";

    # Sort Order
    print "<tr><td class=\"ra\">$lex{'Sort by'}</td>";
    print "<td><select name=\"sortorder\">";
    print "<option value=\"grade\">$lex{Grade}</option>";
    print "<option value=\"homeroom\">$lex{Homeroom}</option>";
    print "<option value=\"name\">$lex{Name}</option>";
    print "</select></td>";
    print "<td></td></tr>\n";


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

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

    # Gray Shade
    print "<tr><td class=\"ra\">$lex{'Gray Shade'}</td><td>\n";
    print "<input type=\"text\"  name=\"grayshade\" value=\"$defaultgrayshade\" size=\"5\">";
    print " (0-1) $lex{'Smaller=Darker'}</td></tr>\n";

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

    # Include Student Number
    print "<tr><td class=\"ra\">$lex{Include} $lex{'Student Number'}</td>";
    print "<td><input type=\"checkbox\" name=\"studnumfield\"  value=\"1\"></td></tr>\n";

    # Additional Field
    print "<tr><td class=\"ra\">$lex{'Additional Field'}</td>\n";
    print "<td><select name=\"extrafield\"><option></option>\n";
    foreach my $fld ( @fields ) {
	print "<option>$fieldname{$fld} ($fld)</option>\n";
    }
    print "</select></td></tr>\n";

    # Additional Field Width
    print "<tr><td class=\"ra\">$lex{'Additional Field'} $lex{Width}</td>\n";
    print "<td><input type=\"text\" size=\"4\" name=\"fieldwidth\" value=\"$extrafieldsize\"> mm</td></tr>\n";
    # $extrafieldsize is set at top of script as a default value.

    # Max Student
    print "<tr><td class=\"ra\">$lex{Maximum} $lex{Students}/$lex{Page}</td>\n<td>";
    print "<input type=\"text\" name=\"maxstudents\" size=\"4\" value=\"$maxstudents\">";
    print "</td></tr>\n";

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

    for ( 1..$entrylimit ) {
	my $entrytxt = "entry$_";
	print "<tr><td class=\"ra\">Entry $_</td>\n";
	print "<td><input type=\"text\" name=\"$entrytxt\" "; 
	print "size=\"$maxentrysize\" maxlength=\"$maxentrysize\"></td></tr>";
	print "\n";
    }

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

    exit;

}


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

    my ($teachername,$group) = @_;


    # Done at the start of a new page.
    print TEX "\\begin{tabular}{G|";
    if ( $studnumfield ) { print TEX "p{ $studnumwidth mm}|"; }
    if ( $extrafield ) { print TEX "p{ $extrafieldsize mm}|"; }
    for (1..$colcount){	print TEX "p{$wi mm}|"; }
    print TEX "}\n";

    print TEX "\\raggedright\\bf $schoolname ". $lex{Classlist};
    if ( $studnumfield ) { print TEX "& "; }
    if ( $extrafield ) { print TEX "& "; }
    for ( 1..$colcount ){ print TEX "& ";}
    print TEX "\\\\ \n";

    print TEX "\\small\\raggedright $currdate\n\\bigskip ";
    if ( $studnumfield ) { print TEX "& "; }
    if ( $extrafield ) { print TEX "& "; }
    for ( 1..$colcount ){ print TEX "& ";}
    print TEX "\\\\ \n";

    # Print Grade or Homeroom, if not sorting by name
    if ( not $group ) { $group = $lex{'Not Found'}; }

    if ( $arr{sortorder} ne 'name' ) { # print grade/homeroom if sorting that way
	if ( $arr{group} eq 'grade' ){
	    print TEX "\\Large\\raggedright $lex{Grade} $group ";
	} else { # homeroom
	    print TEX "\\bf\\raggedright $teachername ";
	    print TEX $lex{Rm}. " $group ";
	}
    }

    if ( $studnumfield ) { print TEX "& "; }
    if ( $extrafield ) { 
	print TEX "&\\hfil\\rule{6pt}{0pt}\\begin{rotate}{90}$extrafieldName";
	print TEX "\\end{rotate}\\hfil";
	#print TEX "& "; 
    }

    my $remainder = $colcount - ($repeatcount * $entrysize);

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

} # End of prHeader



#-----------
sub prRecord { # print normal record (ie. line)
#-----------
    my ( $lastname, $firstname, $studnum ) = @_;

    my ($youngest, $sex, $efield);
    if ( $studnumfield or $extrafield ) { # we have to load some values
	my $fields = 'youngest, sex ';
	if ( $extrafield ) {
	    $fields .= ", $extrafield"; 
	}
	my $sth1 = $dbh->prepare("select $fields from student where studnum = ?");
	$sth1->execute( $studnum );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	( $youngest, $sex, $efield ) = $sth1->fetchrow;
	( $efield ) = latex_filter( $efield );
	if ( $youngest ) { $youngest = $lex{Y}; } 
    }

    if ( $alternatingcolor == 0 ) {
	print TEX "\\rowcolor[gray]{". $arr{grayshade}. "}";
	$alternatingcolor = 1;
    } else { $alternatingcolor = 0;}



    print TEX "\\raggedright $lastname, $firstname";
    if ( $studnumfield ) { 
	my $snfld = $studnum. $youngest. $sex;
	print TEX "&\\footnotesize{$snfld}"; 
    }
    if ( $extrafield ) { 
	print TEX "&\\footnotesize{$efield}"; 
    }

    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\\\hline\n";
}


#--------------
sub prStudCount {
#--------------
    #if ($alternatingcolor == 0){ # continue color from above...
    my $grayval = $arr{grayshade} - 0.08; # make it darker, slightly
    print TEX "\\rowcolor[gray]{$grayval}";
    #}
    print TEX $lex{Students}. ": $studcount";
    if ( $studnumfield ) { print TEX "& "; }
    for (1..$colcount){ print TEX "& ";}
    print TEX "\\\\\\hline\n";
}

