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

#  This file is part of Open Admin for Schools.

# Derived from the central report of same name (without Local)
# Selector based on 'Season' entry. Skips those outside of Season. Skip IEP.

my %lex = ('Error' => 'Error',
	   'Main' => 'Main',
	   'Start Date' => 'Start Date',
	   'End Date' => 'End Date',
	   'Date' => 'Date',
	   'Continue' => 'Continue',
	   'Schools' => 'Schools',
	   'Database' => 'Database',
	   'Reading' => 'Reading',
	   'Report' => 'Report',
	   'Global' => 'Global',
	   'Select' => 'Select',
	   'Split' => 'Split',
	   'Grade' => 'Grade',
	   'Current' => 'Current',
	   'Output' => 'Output',
	   'Combine failed on input' => 'Combine failed on input',
	   'Download CSV File' => 'Download CSV File',
	   'Test' => 'Test',
	   'Group' => 'Group',
	   'Division' => 'Division',
	   'Paper Size' => 'Paper Size',
	   'Letter' => 'Letter',
	   'Legal' => 'Legal',
	   'A4' => 'A4',
	   'Check All' => 'Check All',

	   );


my $self = 'rdRptCurrentLocal.pl';

# Maps Grades to Grade Divisions I, II, III, IV.
my %divmap = ( 'K' => 1, 1 => 1, 2 => 1, 3 => 1, 
	       4 => 2, 5 => 2, 6 => 2, 
	       7 => 3, 8 => 3, 9 => 3,
	       10 => 4, 11 => 4, 12 => 4 );


# use GD::Graph::bars;
# use GD::Graph::colour qw(:colours);
use DBI;
use CGI;
use Number::Format qw(:all);
use Time::JulianDay;
use Text::CSV_XS;
use Statistics::Basic qw(:all);
use Cwd;


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


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

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

my @time = localtime(time);
my $year = $time[5] + 1900;
my $month = $time[4] + 1;
my $currdate = "$year-$month-$time[3]";
my $schyear = $year;
if ( $month < 7 ){ $schyear = $schyear - 1; }
my $prevyear = $schyear - 1;

my $currstartdate = "$schyear-08-01"; # Aug 1 of this school year
my $prevstartdate = "$prevyear-08-01"; # August 1 of prev year.


# Teachermode
if ( $teachermode ) { # running on teacher site
    $css = $tchcss;
    $homepage = $tchpage;
    $downloaddir = $tchdownloaddir;
    $webdownloaddir = $tchwebdownloaddir;
}


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


# Script Heading Descriptor
my $title = "$lex{Current} $lex{Reading} $lex{Report} - $schoolname";

# Print Page Heading
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\n};

if ( not $arr{page} ) { # calendar popup.
    print qq{<link rel="stylesheet" type="text/css" media="all" };
    print qq{href="/js/calendar-blue.css" title="blue">\n};
    print qq{<script type="text/javascript" src="/js/calendar.js"></script>\n};
    print qq{<script type="text/javascript" src="/js/lang/calendar-en.js"></script>\n};
    print qq{<script type="text/javascript" src="/js/calendar-setup.js"></script>\n};
}

print qq{$chartype\n</head><body style="padding:0.4em 2em;">\n};
print qq{[ <a class="alt" href="$homepage">$lex{Main}</a> ]\n};
print qq{<h1>$title</h1>\n};

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

} elsif ( $arr{page} == 1 ) {
    delete $arr{page};

    # output now locked to html
    if ( $arr{output} eq 'html' or $arr{output} eq 'pdf' ) {
	delete $arr{output};
	selectReading();

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


#-----------
sub printPDF { # print one table (one school or summary )
#-----------

    my ($mode, $dataref ) = @_;
    # mode is either grade or division (I,II,etc)
    my %data = %$dataref;


}



#-----------
sub startPDF {  # print the setup for PDF
#-----------

    my ($filename,$papersize) = shift;

    # Preamble and Head of Document
    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;
    }

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

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


    print TEX <<"EOS1";  
\\documentclass[ 12pt, $papersize, oneside]{article}
\\usepackage{array,graphicx,multicol,colortbl,inputenc,fancyhdr}
\\inputencoding{latin1}
\\renewcommand{\\familydefault}{\\sfdefault}

\\setlength{\\hoffset}{-20mm}
\\setlength{\\voffset}{-20mm}

\\setlength{\\headsep}{10pt}
\\setlength{\\headheight}{14pt}
\\setlength{\\topmargin}{0mm}

\\setlength{\\textwidth}{ $textwidth }
\\setlength{\\textheight}{ $textheight }

\\setlength{\\parindent}{0pt}
\\setlength{\\evensidemargin}{0mm}
\\setlength{\\oddsidemargin}{0mm}

\\begin{document}
EOS1


    # Print Data Structure


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

    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">};
    print qq{$lex{'View/Download'} $lex{'Progress Report'}</a></h1>\n};
    print qq{<p>[ <a href="$homepage">$lex{Main}</a> |\n <a href="$webdownloaddir/pdflog$$.txt">};
    print qq{$lex{'View Log File'}</a>\n ]</p>\n};
    print qq{</body></html>\n};



} # end of printPDF



#-----------
sub writeCSV {
#-----------

    my $ref = shift;

    # print "Val:", @val, " Ref:$ref<br>\n";
    
    if ( $csv->combine( @$ref ) ) {
	my $record = $csv->string;
	print EX $record, "\r\n";

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

    return;

} # end writeCSV




#------------
sub exportCSV {
#------------

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

    # Remove the extra:
    delete $arr{grouping};
    delete $arr{papersize};


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

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


    my $sdate = $arr{startdate};
    delete $arr{startdate};
    my $edate = $arr{enddate};
    delete $arr{enddate};

    # Write date range.
    my @data = ();
    #for my $i (1..20){ $data[$i] = ' ';}
    $data[0] = "$lex{'Start Date'} $sdate";
    $data[2] = "$lex{'End Date'} $edate";
    writeCSV(\@data);


    my $startjd = julian_day( split(/-/, $sdate ));
    my $endjd = julian_day( split(/-/, $edate ));

    my %overall;

    foreach my $db ( sort keys %arr ) {
	
	my $database = $db;
	my $dsn = "DBI:$dbtype:dbname=$database";
	my $dbh = DBI->connect($dsn,$guser,$gpassword);
	my $schoolname = $alldbase{"$db"};

	# Write the school name
	my @data = ();
	#for my $i (1..20){ $data[$i] = ' ';}
	$data[0] = $schoolname;
	writeCSV(\@data);

	
	# Get all students in the school who have tests into a @students array
	my @students;
	my $sth = $dbh->prepare("select distinct studnum from read_test");
	$sth->execute;
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	while ( my $studnum = $sth->fetchrow ) {
	    push @students, $studnum;
	}

	if ( not @students ) {

	    my @data = ();
	    for my $i (1..20){ $data[$i] = ' ';}
	    $data[0] = "No Student Tests Found";
	    writeCSV(\@data);

	    # Write blank line.
	    my @data = ();
	    $data[0] = ' ';
	    writeCSV(\@data);
	    
	    next;
	}


	# Now loop through all students printing results; setup queries first
	my $sth1 = $dbh->prepare("select id, tdate, readlevel, tgrade, dratype from read_test 
         where studnum = ? order by tdate desc");

	my $sth2 = $dbh->prepare("select sum(score) from read_test_score where testid = ?");
	
	my %schooldata = ();

	foreach my $studnum ( @students ) {

	    # Get Tests
	    $sth1->execute( $studnum );
	    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

	    # Only use latest value for the student.
	    my $trows = $sth1->rows;
	    # if $onlylatest, limit to 1 test
	    #if ( $onlylatest and $trows > 1 ) { $trows = 1; } 
	    $trows = 1;
	    for ( 1 .. $trows ) {

		my ( $testid, $tdate, $readlevel, $tgrade, $dratype ) = $sth1->fetchrow;

#	    print qq{JD:$testjd  Start:$startjd  \n};
#	    if ( $testjd > $startjd ) { print qq{<br>GREATER<br>\n}; }
#	    if ( $testjd < $endjd ) { print qq{<br>GREATER<br>\n}; }

		# skip out of date range.
		my $testjd = julian_day( split('-', $tdate));
		if ( $testjd < $startjd or $testjd > $endjd ) { next; } 

		# Get the score total;
		$sth2->execute( $testid );
		if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		my $total = $sth2->fetchrow;

		# Equivalent Grade print
		my $equivgrade = scoreToGrade($total, $readlevel, $dratype );

#	    print qq{<div>$testid - $total - $equivgrade</div>\n};

		my $grdelta;
		if ( not $tgrade ) {
		    print qq{Grade Missing: $studnum - $readlevel - $tdate<br>\n};
		    next;
		} else { # Find grade delta
		    $grdelta = $equivgrade - $tgrade;
		}

		if ( $grdelta >= 0 ) { $grdelta = int $grdelta; } # truncate.
		else { $grdelta = int $grdelta - 1; }

		$schooldata{$tgrade}{$grdelta}++;
		$overall{$tgrade}{$grdelta}++;

	    } # end of trows loop

	} # end of student loop


	my ($max, $min, $studcount );
	my %dcount = ();
	my @stats = ();
	foreach my $grade ( sort keys %schooldata ) {
	    foreach my $delta ( sort keys %{ $schooldata{$grade} } ) {
		# Set Min/Max values
		if  ( $delta > $max ) { $max = $delta; }
		if  ( $delta < $min ) { $min = $delta; }

		# Get Count and Delta Counts.
		$studcount += $schooldata{$grade}{$delta};
		$dcount{$delta} += $schooldata{$grade}{$delta};
		for (1..$dcount{$delta} ) { push @stats, $delta; } # put delta values into @stats
		# print qq{G:$grade D:$delta Count:$schooldata{$grade}{$delta}<br>\n};
	    }
	}



	# Table Heading
	@data = ();
	$data[0] = "$lex{Grade}";
	foreach my $delta ( $min .. $max ) {
	    push @data, $delta;
	}
	push @data, "SDev";
	push @data, "Var";

	writeCSV(\@data);


	# Write each grade row.
	foreach my $grade ( sort {$a <=> $b} keys %schooldata ) {
	    my @data = ();
	    my @grstats = ();
	    $data[0] = $grade;
	    foreach my $delta ( $min .. $max ) {
		push @data, $schooldata{$grade}{$delta};
		for (1..$schooldata{$grade}{$delta}) { push @grstats, $delta; }
	    }

	    push @data, stddev(\@grstats);
	    push @data, variance(\@grstats);

	    writeCSV(\@data);
	}


	# Write average Row
	my @data = ();
	my @data1 = ();
	$data[0] = 'Average';
	$data1[0] = 'Count';
	foreach my $delta ( $min .. $max ) {
	    my $avg;
	    if ( $studcount ) {
		$avg = round( $dcount{$delta} / $studcount * 100, 2);
	    }
	    push @data, $avg;
	    push @data1, $dcount{$delta}
	    # print qq{<td>$dcount{$delta}/$studcount<br>$avg%</td>};
	}

	push @data, stddev(\@stats);
	push @data, variance(\@stats);

	writeCSV(\@data); # average
	writeCSV(\@data1); # count


	# Duplicate of the studcount row...
	# Write Column Sum
#	my @data = ();
#	$data[0] = 'Column Sum';
#	foreach my $delta ( $min .. $max ) {
#	    push @data,	$dcount{$delta}
#	}
#	writeCSV(\@data);


	# Write studcount Row
	my @data = ();
	$data[0] = 'S Count';
	foreach my $delta ( $min .. $max ) {
	    push @data, $studcount;
	}
	writeCSV(\@data);

	# Write blank line.
	my @data = ();
	$data[0] = ' ';
	writeCSV(\@data);


    } # database loop



    # All Schools Combined.
    my @data = ();
    $data[0] = 'Combined Schools Result';
    writeCSV(\@data);


    # Next Line
    $max = 0, 
    $min = 0, 
    $studcount = 0;
    %dcount = ();
    @stats = ();

    foreach my $grade ( sort keys %overall ) {
	foreach my $delta ( sort keys %{ $overall{$grade} } ) {
	    if  ( $delta > $max ) { $max = $delta; }
	    if  ( $delta < $min ) { $min = $delta; }
	    $studcount += $overall{$grade}{$delta};
	    $dcount{$delta} += $overall{$grade}{$delta};
	    for (1..$overall{$grade}{$delta}) { push @stats, $delta; }
	    # print qq{G:$grade D:$delta Count:$overall{$grade}{$delta}<br>\n};
	}
    }

    # Write Heading Line
    my @data = ();
    $data[0] = $lex{Grade};
    foreach my $delta ( $min .. $max ) {
	push @data, $delta;
    }
    push @data, "SDev";
    push @data, "Var";

    writeCSV(\@data);


    # Write all grade rows.
    foreach my $grade ( sort {$a <=> $b} keys %overall ) {
	my @data = ();
	my @grstats = ();
	$data[0] = $grade;
	foreach my $delta ( $min .. $max ) {
	    push @data, $overall{$grade}{$delta};
	    for (1..$overall{$grade}{$delta}) { push @grstats, $delta; }
	}

	push @data, stddev(\@grstats);
	push @data, variance(\@grstats);

	writeCSV(\@data);
    }


    # Write average Row
    my @data = ();
    $data[0] = 'Average';
    foreach my $delta ( $min .. $max ) {
	my $avg;
	if ( $studcount ) {
	    $avg = round( $dcount{$delta} / $studcount * 100, 2);
	}
	push @data, $avg;
	# print qq{<td>$dcount{$delta}/$studcount<br>$avg%</td>};
    }

    push @data, stddev(\@stats);
    push @data, variance(\@stats);

    writeCSV(\@data);


    # Write Column Sum Row
    my @data = ();
    $data[0] = 'Count';
    foreach my $delta ( $min .. $max ) {
	push @data,	$dcount{$delta}
    }
    writeCSV(\@data);


    # Write studcount Row
    my @data = ();
    $data[0] = 'Total';
    foreach my $delta ( $min .. $max ) {
	push @data, $studcount;
    }
    writeCSV(\@data);


    close EX;
    system("mv $filename $downloaddir");
    
    print qq{<p><a href="$webdownloaddir/$filename">\n};
    print qq{<span style="font-size:1.5em;">$lex{'Download CSV File'}</span></a></p>\n};
    print qq{</body></html>\n};

    exit;

} # end of exportCSV




#----------------
sub selectReading {  # normal html report.
#----------------

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

    # Load the reading library containing the scoreToGrade function.
    eval require "../../lib/libreading.pl";
    if ( $@ ) {
	print $lex{Error}. " $self: $@<br>\n";
	die $lex{Error}. "$self: $@\n";
    }

    
    my $sdate = fmtDate( $arr{startdate} );
    my $startdate = $arr{startdate};
    delete $arr{startdate}; 

    my $edate = fmtDate( $arr{enddate} );
    my $enddate = $arr{enddate};
    delete $arr{enddate};

    my $season =  $arr{season};
    delete $arr{season};
    
    my $grouping = $arr{grouping};
    delete $arr{grouping};

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

    my $mindelta = $arr{mindelta};
    delete $arr{mindelta}; # the starting point below which we display grade, names;

    if ( $arr{includewithdrawn} ) {
	print qq{<div>Including Withdrawn Students with reading data };
	print qq{in this season/date range</div>\n};
    }
    # All %arr variable removed by here.
    
    # sdate and edate are formatted dates.
    if ( not $season ) {
	print qq{<h3>$lex{'Start Date'} $sdate | $lex{'End Date'} $edate</h3>\n};
    } else {
	print qq{<h3>Season $season</h3>\n};
    }

    my ($sy,$ey) = split('-', $schoolyear);
    $sy =~ s/^20//;  # remove leading 20 in 2022, etc.
    $ey =~ s/^20//;
    
    my $iepdbase = qq{iep$sy$ey};
    my $dsniep = "DBI:$dbtype:dbname=$iepdbase";
    my $dbhiep = DBI->connect($dsniep,$guser,$gpassword);
    
#    print "IEP Dbase:$iepdbase<br>";
    
    my $dsn = "DBI:$dbtype:dbname=$dbase";
    my $dbh = DBI->connect($dsn,$user,$password);

    print qq{<h2>$schoolname</h2>\n};


    # Find IEP students, to remove from evaluation, match by studnum and/or name
    # (since may not be unique)
    my (%iepstudents, %iepnames);
    my $sth = $dbhiep->prepare("select lastname, firstname, studnum from special 
			       where school = '$dbase'");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    while ( my ($lastname, $firstname, $studnum ) = $sth->fetchrow ) {
#	print "IEP SN:$studnum</br>\n";
	$iepstudents{$studnum} = "$lastname,$firstname";
	$iepnames{"$lastname$firstname"} = $studnum;
    }
    
    # Get all students who have tests 
    my $sth2 = $dbh->prepare("select lastname, firstname, grade from studentall where studnum = ?");
    
    my (%studentname,%sort, %studentgrade);
    my $sth = $dbh->prepare("select distinct studnum from read_test");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $studnum = $sth->fetchrow ) {

	# Get Name, Grade
	$sth2->execute( $studnum);
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my ($lastname,$firstname,$grade) = $sth2->fetchrow;
	if ( not $lastname) {
#	    print "No Name: $studnum<br>\n";
	    $lastname = 'Unknown', $firstname = 'Name';
	    next;
	}
	
	if ( $iepstudents{$studnum} or  $iepnames{"$lastname$firstname"} ) {
	    if ( $showiep ) {
		print qq{Skip IEP Student: $firstname <b>$lastname</b> ($studnum) };
		print qq{<b>Grade $grade</b><br>\n};
	    }
	    next;
	}

	$sort{"$lastname$firstname$studnum"} = $studnum; 
	$studentname{$studnum} = "<b>$lastname</b>, $firstname";  # store in case needed later.
	$studentgrade{$studnum} = $grade;
	
    }

    if ( not %sort ) {
	print qq{<h3>No Student Tests Found</h3>\n};
	next;
    }


    # Now loop through all students printing results; setup queries first
    my $sth1;
    if ( $season ) {
	$sth1 = $dbh->prepare("select id, tdate, readlevel, tgrade, dratype from read_test 
               where studnum = ? and season = '$season' order by tdate desc");

    } else {
	$sth1 = $dbh->prepare("select id, tdate, readlevel, tgrade from read_test 
               where studnum = ? and to_days(tdate) >= to_days('$startdate') and 
               to_days(tdate) <= to_days('$enddate') order by tdate desc");
    }
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

    # Get Score total
    my $sth2 = $dbh->prepare("select sum(score) from read_test_score where testid = ?");

    # Are they withdrawn?
    my $sth4 = $dbh->prepare("select count(*) from studentwd where studnum = ?");
    

    
    foreach my $key ( keys %schooldata ) { $schooldata{$key} = NULL; }
    my %schooldata;
    my %lowdelta; # lowdelta{tgrade}{delta} = @studnums; store students with very neg delta values.

	
    foreach my $key ( sort keys %sort ) {
	my $studnum = $sort{$key};

	my $name = $studentname{$studnum};
	my $grade = $studentgrade{$grade};

	# Withdrawn?
	$sth4->execute( $studnum );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my $wdcount = $sth4->fetchrow;
	if ( $wdcount and not $arr{includewithdrawn} ) {
	    next;
	}

	
	# Get Tests
	$sth1->execute( $studnum );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

	# Only use latest value for the student.
	my $trows = $sth1->rows;
	if ( $trows < 1 ) { next; }

	# if ( $onlylatest and $trows > 1 ) { $trows = 1; } 
	$trows = 1;  # only the latest version.


	for ( 1 .. $trows ) {

	    my ( $testid, $tdate, $readlevel, $tgrade, $dratype ) = $sth1->fetchrow;

#	    print "ID:$testid<br>\n";
	    # Get the score total;
	    $sth2->execute( $testid );
	    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	    my $total = $sth2->fetchrow;

	    # Equivalent Grade print
	    my $equivgrade = scoreToGrade($total, $readlevel, $dratype );
	    #if ( $tgrade == 6 ) {
	    # print "ID:$testid EGR:$equivgrade TGrade:$tgrade<br>\n";
	    #}
	
	    my $grdelta;
	    if ( not $tgrade ) {
		$sth3->execute( $studnum );
		my ( $lastname, $firstname ) = $sth3->fetchrow;		    
		print qq{Test Grade Missing: $lastname, $firstname ($studnum) - $tdate<br>\n};
		next;
		
	    } else { # Find grade delta
		$grdelta = $equivgrade - $tgrade;
	    }
		
	    if ( $grdelta >= 0 ) { $grdelta = int $grdelta; } # truncate.
	    else { $grdelta = int $grdelta - 1; }

	    # Store kids below threshold.
	    if ( $mindelta and $grdelta <= $mindelta ) { # add this student to the list.
		push @{ $lowdelta{$tgrade}{$grdelta} }, $studnum;
	    }

	    $schooldata{$tgrade}{$grdelta}++;
	    $overall{$tgrade}{$grdelta}++;


	} # end of trows loop

    } # end of student loop

	
    # Skip if no tests in this date range
    if ( not %schooldata ) { 
	print qq{<h3>No tests in this Date Range</h3>\n};
	next; 
    }

    # Get MIN, MAX values of Delta Grade (How far above/below grade level.
    my ($max, $min, $studcount );
    my %dcount = ();
    foreach my $grade ( sort keys %schooldata ) {
	foreach my $delta ( sort keys %{ $schooldata{$grade} } ) {
	    if  ( $delta > $max ) { $max = $delta; }
	    if  ( $delta < $min ) { $min = $delta; }
	    $studcount += $schooldata{$grade}{$delta};
	    $dcount{$delta} += $schooldata{$grade}{$delta};
	    # print qq{G:$grade D:$delta Count:$schooldata{$grade}{$delta}<br>\n};
	}
    }


    my %divdata = ();  # Grade Divisions Data

    if ( $grouping eq 'division' ) { # populate this structure
	foreach my $grade ( sort {$a <=> $b} keys %schooldata ) {
	    my $div = $divmap{$grade};
	    if ( not $div ) { 
		print qq{$lex{Error}: No Div for $lex{Grade}:$grade<br>\n};
		next;
	    }

	    foreach my $delta ( $min .. $max ) {
		$divdata{$div}{$delta} += $schooldata{$grade}{$delta};
#		print qq{D:$delta DIV:$div GRD:$grade -- $divdata{$div}{$delta} -- };
#		print qq{$schooldata{$grade}{$delta}<br>\n};
	    }
	}
    }

    # Division Level Output
    if ( $grouping eq 'division' ) { 
	print qq{<table cellspacing="0" cellpadding="3" border="1">\n};
	# Table Heading
	print qq{<tr><th>$lex{Division}</th>};
	foreach my $delta ( $min .. $max ) {
	    print qq{<th>$delta</th>};
	}
	print qq{<th>$lex{Test}#</th><th>Wt. Avg</th></tr>\n};


	foreach my $div ( sort {$a <=> $b} keys %divdata ) {
	    print qq{<tr><td>$div</td>};
	    my ($total,$partavg);
	    foreach my $delta ( $min .. $max ) {
		my $count = $divdata{$div}{$delta};
		print qq{<td>$divdata{$div}{$delta}</td>};
		$total += $count;
		$partavg += ( $count * $delta );
	    }

	    my $avg;
	    if ( $total ) {
		$avg = $partavg / $total;
	    } else { $avg = 0; }
		
	    $avg = round($avg, 2);
	    print qq{<td>$total</td><td>$avg</td>};
	    print qq{</tr>\n};
	}
	# print qq{</table><p></p>\n};
	# End - Division Level Output

    } else {
	# Grade Level Output    
	
	# Now Printing Grade Level Output
	print qq{<table cellspacing="0" cellpadding="3" border="1">\n};


	# Table Heading
	print qq{<tr><th>$lex{Grade}</th>};
	foreach my $delta ( $min .. $max ) {
	    print qq{<th>$delta</th>};
	}
	print qq{<th>$lex{Test}#</th><th>Wt. Avg</th>};
	print qq{</tr>\n};


	foreach my $grade ( sort {$a <=> $b} keys %schooldata ) {
	    print qq{<tr><td>$grade</td>};
	    my ($total,$partavg);
	    foreach my $delta ( $min .. $max ) {
		my $count = $schooldata{$grade}{$delta};
		print qq{<td>$schooldata{$grade}{$delta}</td>};
		$total += $count;
		$partavg += ( $count * $delta );
	    }

	    my $avg;
	    if ( $total ) {
		$avg = $partavg / $total;
	    } else { $avg = 0; }
		
	    $avg = round($avg, 2);
	    print qq{<td>$total</td><td>$avg</td>};
	    print qq{</tr>\n};
	} # end of grade loop

    }

    # Summary Row
    print qq{<tr><th>Average</th>};
    my $partavg;
    foreach my $delta ( $min .. $max ) {
	$partavg += ($delta * $dcount{$delta} );
	my $avg;
	if ( $studcount ) {
	    $avg = round( $dcount{$delta} / $studcount * 100, 2);
	}
	    
	print qq{<td>$dcount{$delta}/$studcount<br>$avg%</td>};
    }

    my $avg = $partavg / $studcount;
    $avg = round($avg,2);
    print qq{<th>$studcount</th><th>$avg</th></tr>\n};

    print qq{</table><p></p>\n};

    
    if ( $mindelta ) {  # display students below minimum delta value.
	print qq{<table cellpadding="3" cellspacing="0" border="0" };
	print qq{style="padding:0.5em;border:1px solid gray;">\n};
	print qq{<tr><th>Grade</th><th>Student</th><th>Grades<br>Below</th></tr>\n};

	my $bgcolor;
	foreach my $tg ( sort keys %lowdelta ) { # grade sort.
	    foreach my $delta ( sort keys %{ $lowdelta{$tg} } ) {
		if ( $bgcolor eq 'white' ) { $bgcolor = '#DDD' } else { $bgcolor = 'white'; }
		foreach my $sn ( @{ $lowdelta{$tg}{$delta} } ) {
		    print qq{<tr style="background-color:$bgcolor;"><td class="cn">$tg</td>};
		    print qq{<td class="la">$studentname{$sn} ($sn)</td>};
		    print qq{<td>$delta</td></tr>\n};
		}
	    }
	}
	print qq{</table>\n};
    }


    exit;
}



#----------
sub fmtDate {
#----------

    my ( $year, $mon, $day ) = split /-/, shift;
    return "$year-$s_month[$mon]-$day";
}


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

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

    my $sth = $dbh->prepare("select count(*) from read_test where season = ?");
    
    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" };
    print qq{style="padding:0.5em;border:1px solid gray;">\n};


    # Season (override dates)
    my ($sy,$ey) = split('-', $schoolyear);
    my $currjd = julian_day( split('-',$currdate));

    # Start Date for current school year seasons.
    my $falljd = julian_day($sy,'09','01'); # Sept 1
    my $springjd = julian_day($ey,'01','03'); # Jan 1
    my $summerjd = julian_day($ey,'05','15'); # May 15

    print qq{<tr><td class="bra">Season</td><td class="la">};
    print qq{<select name="season"><option></option>\n};
    
    if ( $currjd >= $summerjd ) {
	print qq{<option value="$ey-Summer">$ey Summer (May 15 - June 30)</option>\n};
    }
    if ( $currjd >= $springjd ) {
	print qq{<option value="$ey-Spring">$ey Spring (Jan 1 - March 31)</option>\n};
    }

    for( my $yr = $sy; $yr >= 2011; $yr-- ) {

	my %seasonrec;
	foreach my $sn ( 'Fall','Summer','Spring') {
	    $sth->execute("$yr-$sn");
	    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	    my $val = $sth->fetchrow;
	    $seasonrec{$sn} = $val;
	}
	
	print qq{<option value="$yr-Fall">$yr Fall (Sept 1 - Oct 31) };
	print qq{$seasonrec{'Fall'} Records</option>\n};
	print qq{<option value="$yr-Summer">$yr Summer (May 15 - June 30) };
	print qq{$seasonrec{'Summer'} Records</option>\n};
	print qq{<option value="$yr-Spring">$yr Spring (Jan 1 - March 31) };
	print qq{$seasonrec{'Spring'} Records</option>\n};
    }
    print qq{</select> (Override Dates)</td></tr>\n\n};

    
    # Start Date
    print qq{<tr><td class="bra">$lex{'Start Date'}</td><td class="la"><input type="text" };
    print qq{name="startdate" id="sdate" size="10" value="$currstartdate">\n};
    print qq{<button type="reset" id="start_trigger">...</button>\n};
    print qq{</td></tr>\n\n};


    # End Date
    print qq{<tr><td class="bra">$lex{'End Date'}</td><td class="la"><input type="text" };
    print qq{name="enddate" id="edate" size="10" value="$currdate">\n};
    print qq{<button type="reset" id="end_trigger">...</button></td></tr>\n\n};

    # Grouping 
    print qq{<tr><td class="bra">$lex{Group}</td><td class="la">};
    print qq{<select name="grouping">\n};
    print qq{<option value="grade">$lex{Grade}</option>};
    print qq{<option value="division">$lex{Division}</option>\n};
    print qq{</select></td></tr>\n};

    # Show Students At/Below Delta Grade
    print qq{<tr><td class="bra">Show Students at/below Delta</td><td class="la">};
    print qq{<input type="text" name="mindelta" style="width:3ch;" value=""> };
    print qq{Blank = Don't Show</td></tr>\n};
    print qq{<tr><td colspan="2" class="la">};
    print qq{<b>Delta</b> is difference between reading grade level and current grade placement };
    print qq{(-1,-2,etc)</td></tr>\n\n};


    # Show IEP Skips
    print qq{<tr><td class="bra">Show IEP Skips</td><td class="la">};
    print qq{<input type="checkbox" name="showiep" value="1">};
    print qq{ IEP Student Reading Tests are skipped</td></tr>\n};

    # Include Withdrawn Student Data
    print qq{<tr><td class="bra">Include Withdrawn Student Data</td><td class="la">};
    print qq{<input type="checkbox" name="includewithdrawn" value="1"></td></tr>\n};

    
    # Output Type
    print qq{<tr><td><input type="hidden" name="output" value="html"></td></tr>\n};

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

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

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

    print qq{<script type="text/javascript">
     Calendar.setup({
        inputField     :    "sdate", 
        ifFormat       :    "%Y-%m-%d",
        button         :    "start_trigger",
        singleClick    :    false,
        step           :    1
    });

    Calendar.setup({
        inputField     :    "edate",
        ifFormat       :    "%Y-%m-%d",
        button         :    "end_trigger",
        singleClick    :    false,
        step           :    1
    });
    </script>\n};

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

    exit;

} # end of showStartPage


