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

#  This file is part of Open Admin for Schools.

my %lex = ('Main' => 'Main',
	   'Error' => 'Error',
	   'Reading Report' => 'Reading Report',
	   'Reading Level' => 'Reading Level',
	   'Name' => 'Name',
	   'Date' => 'Date',
	   'Student' => 'Student',
	   'No Students Found' => 'No Students Found',
	   'Last,First/Last/Initials/Studnum' => 'Last,First/Last/Initials/Studnum',
	   'Search' => 'Search',
	   'No Tests Found' => 'No Tests Found',
	   'Tot' => 'Tot',
	   'Start Date' => 'Start Date',
	   'End Date' => 'End Date',
	   'Test' => 'Test',
	   'EGr' => 'EGr',
	   'Continue' => 'Continue',
	   'Level' => 'Level',
	   'Sort Order' => 'Sort Order',
	   'New to Old' => 'New to Old',
	   'Old to New' => 'Old to New',
	   
	   
	   );

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

my $self = 'readRptStudent.pl';

my @time = localtime(time);
my $year = $time[5] + 1900;
my $month = $time[4] + 1;
my $currdate = "$year-$month-$time[3]";

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

# Get current dir so know what CSS to display and shift settings.
my $tcgiurl = 'tcgi-bin';
if ( getcwd() !~ /tcgi/ ) { # we are in cgi
    $tchcss = $css;
    $tchpage = $homepage;
    $tchdownloaddir = $downloaddir;
    $tchwebdownloaddir = $webdownloaddir;
    $tcgiurl = 'cgi-bin';
}


my $q = new CGI;
print $q->header; 
my %arr = $q->Vars;

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

# Page Header
my $title = qq{$lex{Student} $lex{'Reading Report'}};

print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$tchcss" type="text/css">
<style type="text/css">
th.fs6{font-size:60%;}
td.r { background-color:#822;color:white;font-size:120%;font-weight:bold; }
td.y { background-color:#BB1;color:white;font-size:120%;font-weight:bold; }
td.b { background-color:#228;color:white;font-size:120%;font-weight:bold; }
td.g { background-color:#282;color:white;font-size:120%;font-weight:bold; }
a {color:white;}
a.alt {color:blue;}
</style>\n};

print qq{<script language="javascript" type="text/javascript">
function showhelp(type) {
  winName=window.open('/$tcgiurl/reading/showhelp.pl?id=' + type,'helpWindow',
  'height=300,width=700,screenX=100,screenY=100,resizeable');
  winName.focus();
}
</script>
$chartype\n</head><body style="padding:1em 2em;">\n};

print qq{[ <a class="alt" href="$tchpage">$lex{Main}</a> ]\n};
if ( getcwd() !~ /tcgi/ ) { # we are in cgi
    print qq{[ <a href="/ssp.html" style="color:blue;">SSP</a> ]\n};
}

print qq{<h1 style="text-align:left;margin:0;padding:0.2em;">};
print qq{<span style="font-size:80%;">$lex{Student} $lex{'Reading Report'}</span>};
print qq{ $schoolname <span style="font-size:80%;">}. fmtDate($currdate). qq{</span></h1>\n};

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


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

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

} elsif ( $arr{page} == 2 ) {
    delete $arr{page};
    showReport();
}


#----------
sub fmtDate {
#----------
    my ( $year, $mon, $day ) = split '-', shift;
    return qq{$year-$s_month[$mon]-$day};
}


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

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

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

    
    my ($studnum) = @_;
    
    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};

    print qq{<tr><td class="ra">$lex{Student} ($lex{'Last,First/Last/Initials/Studnum'})</td>\n};
    print qq{<td class="la"><input type="text" name="student" size="30" value="$studnum"></td></tr>\n};

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

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

    print qq{<tr><td class="ra">$lex{'Sort Order'}</td>\n};
    print qq{<td class="la"><select name="sortorder">};
    print qq{<option value="descending">$lex{'New to Old'}</option>\n};
    print qq{<option value="ascending">$lex{'Old to New'}</option></select></td></tr>\n};

    
    print qq{<tr><td></td><td class="la"><input type="submit" value="$lex{Search}"></td></tr>\n};
    print qq{</table>\n};
    print qq{</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


#----------------
sub selectStudent {
#----------------

    my $student = $arr{student};

    # Setup the Search
    if ($student =~ /\d+/) {  # we have a student number
	$studnum = $student;
	$sth = $dbh->prepare("select lastname, firstname, studnum from studentall
           where studnum = ?");
	$sth->execute( $studnum );

    } else { # we have words hopefully with a comma
	($lastname,$firstname)  = split /\,/, $student;
	$firstname =~ s/^\s*//;
	$lastname =~ s/^\s*//;
	if ($lastname and $firstname){ # both entered.
	    $sth = $dbh->prepare("select lastname, firstname, studnum 
              from studentall where lastname = ? and firstname = ?
              order by lastname, firstname");
	    $sth->execute( $lastname, $firstname );
	} elsif ( $lastname and not $firstname ){ # only lastname (no comma)
	    if (length($lastname) == 2){ # search by initials: fi, li.

		$fi = substr($lastname,0,1); 
		$li = substr($lastname,1,1);
		$fi .= '%';
		$li .= '%';
		$sth = $dbh->prepare("select lastname,firstname, studnum from studentall
                   where lastname $sql{like} ? and firstname $sql{like} ?
                   order by lastname, firstname");
		$sth->execute( $li, $fi );
	    } else {
		$sth = $dbh->prepare("select lastname, firstname, studnum 
                 from studentall where lastname = ? 
                 order by lastname, firstname");
		$sth->execute( $lastname );
	    }
	} else {
	    $sth = $dbh->prepare("select lastname, firstname, studnum 
              from studentall order by lastname, firstname");
	}
    } # Last Else

    if ( $DBI::errstr ) { print $lex{Error}. ": $DBI::errstr"; die $DBI::errstr; }
    my $first = 1;
    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
    print qq{<tr><th>$lex{Name}</th><th>$lex{Test}</th><th></th></tr>\n};

    my $sth1 = $dbh->prepare("select count(*) from read_test 
      where studnum = ? and to_days( tdate ) >= to_days( '$arr{startdate}' ) 
      and to_days( tdate ) <= to_days( '$arr{enddate}')");
    

    # Loop through each found student.

    while ( my ( $lastname, $firstname,$studnum ) = $sth->fetchrow ) {

	$sth1->execute( $studnum );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my $testcount = $sth1->fetchrow;

	print qq{<tr><td style="text-align:right;">$firstname <strong>$lastname</strong>};
	print qq{ ($studnum)</td><td>$testcount</td><td>\n};
	if ( $testcount ) {
	    print qq{<form action="$self" method="post">\n};
	    print qq{<input type="hidden" name="page" value="2">\n};
	    print qq{<input type="hidden" name="startdate" value="$arr{startdate}">\n};
	    print qq{<input type="hidden" name="enddate" value="$arr{enddate}">\n};
	    print qq{<input type="hidden" name="sortorder" value="$arr{sortorder}">\n};
	    print qq{<input type="hidden" name="studnum" value="$studnum">\n};
	    print qq{<input type="submit" value="$lex{Continue}"></form>\n};
	}
	print qq{</td></tr>\n};
	$first = 0;

    }

    if ( $first ) { # no students
	print qq{<tr><td colspan="2">$lex{'No Students Found'}</td></tr>\n};
	print qq{</table></div><p></p>\n};
	showStartPage();
    } else {
	print qq{</table></body></html>\n};
    }

    exit;

} # end of selectStudent



#-------------
sub showReport {
#-------------

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

    # if only passed the studnum from class report, do current year data
    if ( not $arr{startdate} ) {
	# $arr{startdate} = $schoolstart;
	$arr{startdate} = '2015-08-01';  # get ALL years data
	
    }
    if ( not $arr{enddate} ) {
	$arr{enddate} = $currdate;
    }
    if ( not $arr{sortorder} ) {
	$arr{sortorder} = 'descending';
    }

    
    my $studnum = $arr{studnum};

    # 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";
    }
    
    # Get Student Name
    my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");
    $sth->execute( $studnum );
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    my ( $lastname, $firstname ) = $sth->fetchrow;

    print qq{<h3 style="text-align:left;font-size:120%;margin:0;padding:0.3em;">};
    print qq{$firstname $lastname ($studnum)</h3>\n};
    
    my $sth1 = $dbh->prepare("select distinct readlevel, dratype, cast( readlevel as signed int) 
			     as newrl from read_test where studnum = ? order by newrl desc"); 
    $sth1->execute( $studnum );
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    
    my $first = 1;

    # Check for tests at this reading level in this date range.
    my $sth2 = $dbh->prepare("select count(*) from read_test where studnum = ? 
     and readlevel = ? and dratype = ? and to_days( tdate ) >= to_days( '$arr{startdate}' ) 
     and to_days( tdate ) <= to_days( '$arr{enddate}') ");


    while ( my ( $readlevel,$dratype ) = $sth1->fetchrow ) {

	# check for tests in date range (at this read level for this dratype).
	$sth2->execute( $studnum, $readlevel, $dratype );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my $count = $sth2->fetchrow;

	if ( $count ) { # if we have some tests...
	    $first = 0;
	    my @students; # although only a single student in this case.
	    push @students, $studnum;
	    if ( $dratype == 2 ) {
		showReadingLevel( $readlevel, 0,  \@students , $arr{startdate}, $arr{enddate},
				  $arr{sortorder}, $dratype ); # note: no bktype
	    } else { # dratype == 3  # loop over both types fiction/nonfiction
		showReadingLevel( $readlevel, 0,  \@students , $arr{startdate}, $arr{enddate},
				  $arr{sortorder}, $dratype, 'fiction' );
		
		showReadingLevel( $readlevel, 0,  \@students , $arr{startdate}, $arr{enddate},
				  $arr{sortorder}, $dratype, 'nonfiction' );
	    }
	}
    } # reading level, dratype
    
    if ( $first ) {
	print qq{<h3>$lex{'No Tests Found'}</h3>\n};
    }

    showStartPage(); # always allow for change/update
    print qq{</body></html>\n};

    exit;

}


#-------------------
sub showReadingLevel {
#-------------------
    my ( $readinglevel, $onlylatest, $stud_ref, $startdate, $enddate,
	 $sortorder,$dratype,$bktype ) = @_;
    
    # Reading tests are distinguished by reading level, but also book
    # type (fiction / nonfiction) where dra2 didn't have a book type and also
    # as well as a dratype (DRA 2 or DRA 3).

#    print "Book Type:$bktype<br>\n";
    
    my $helptable = 'read_level_dra2'; # the table holding the help information (dra2 or dra3)
    if ( $dratype == 3 ) {
	$helptable = 'read_level_dra3';
    }
    
    if ( $sortorder eq 'ascending' ) {
	$sortorder = ''; # normal ascending sort
    } else {
	$sortorder = 'desc'; # descending sort
    }
    
    my @students = @$stud_ref;


    
    # Get reading score objectives (not scores yet) from the first record scores table.
    my %objectives; # from read_level_dra2 or 3.
    my $sth;
    if ( $dratype == 2 ) {
	$sth = $dbh->prepare("select name, category, seq from $helptable
			     where readlevel = ?"); # no worries from fic/nonfiction
	$sth->execute( $readinglevel );
    } else { # dratype is 3
	$sth = $dbh->prepare("select name, category, seq from $helptable
			     where readlevel = ? and bktype = ?"); # no worries from fic/nonfiction
	$sth->execute( $readinglevel, $bktype);
    }
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

    while ( my ( $name, $category, $seq ) = $sth->fetchrow ) {
	$objectives{ $seq } = $category. '::'. $name;
    }


    # Set Index values for all objectives
    my $count = 0;
    my $startcount;
    my %skip;
    my $currcat = '';

   # Print out First Heading Line
    my $colspan = 4;
    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
    print qq{<tr><th colspan="$colspan">$lex{'Reading Level'} $readinglevel DRA$dratype $bktype</th>\n};


    foreach my $key ( sort { $a <=> $b } keys %objectives ) { # numeric sort 

	my ( $category, $name ) = split(/::/, $objectives{$key} );
	$oldcat = $currcat;
	$currcat = $category;

	if ( $oldcat ne $currcat and $count ) {
	    $diff = $count - $startcount;
	    print qq{<th colspan="$diff" style="font-size:100%;">$oldcat</th>\n};
	    $skip{$oldcat} = $diff;
	    $startcount = $count;

	}
	
	$count++;

    }
    $diff = $count - $startcount;
    $skip{$currcat} = $diff;
    print qq{<th colspan="$diff" style="font-size:100%;">$currcat</th></tr>\n};


    # Print Out Second Heading Line
    print qq{<tr><th>$lex{Name}</th><th>$lex{Date}</th><th>$lex{Tot}</th><th>$lex{EGr}</th>\n};

    # SQL Query of global reading level table.
    my $sth1 = $dbh->prepare("select id, help1 from $helptable where readlevel = ? and
      category = ? and name = ?");

    foreach my $key ( sort { $a <=> $b } keys %objectives ) { # numeric sort 
	my ( $category, $name ) = split(/::/, $objectives{$key} );
	
	# Get the record id and help for this...
	$sth1->execute( $readinglevel, $category, $name );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my ($id, $help1 ) = $sth1->fetchrow;

	print qq{<th class="fs6">};
	if ( $help1 ) {
	    print qq{<a href="javascript:showhelp($id)">};
	    print qq{&#9405; $name</a>};
	} else {
	    print qq{$name};
	}
	print qq{</th>\n};

    }
    print qq{</tr>\n};



    # Now loop through all students printing results; setup queries first
    my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");

    my $sth1 = $dbh->prepare("select id, tdate, dratype, bktype from read_test 
			     where studnum = ? and readlevel = ? and 
			     to_days( tdate ) >= to_days( '$startdate' ) and
			     to_days( tdate ) <= to_days( '$enddate') 
			     order by tdate $sortorder"); # get tests
    
    my $sth2 = $dbh->prepare("select category, name, score from read_test_score 
			     where testid = ? and seq = ?");

    # Those DRA 2 Reading levels that are nonfiction booktypes; otherwise fiction
    my %nonfiction = ( '16N' => 1, '28N' => 1, '38N' => 1 );

    foreach my $studnum ( @students ) {

        # Get Name
	$sth->execute( $studnum );
	my ( $lastname, $firstname ) = $sth->fetchrow;
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

	# Get Tests
	$sth1->execute( $studnum, $readinglevel );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my $trows = $sth1->rows;

	# if $onlylatest, limit to 1 test
	if ( $onlylatest and $trows > 1 ) { $trows = 1; } 

	for ( 1 .. $trows ) {

	    my ( $testid, $tdate, $dratype, $testbktype ) = $sth1->fetchrow;
	    if ( $testbktype ne $bktype and $testbktype ) { next; } # skip if not same fiction/nonfic 

	    print qq{<tr><td class="la"><b>$lastname</b>, $firstname</td><td>}.
		fmtDate($tdate). qq{</td>\n};
	    
	    if ( not $testbktype ) {
		if ( $nonfiction{$readlevel} ) {
		    $bktype = 'nonfiction';
		} else {
		    $bktype = 'fiction';
		}
	    }

	    # Loop through all the scores
	    my %studata;
	    my $total = 0;
	    my $count = 0;

	    foreach my $seq ( sort { $a <=> $b } keys %objectives ) { # numeric sort
#		print qq{SEQ:$seq<br>\n};
		$sth2->execute( $testid,$seq );
		if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		my ( $category, $name, $score ) = $sth2->fetchrow;

		# Check against objectives
	        my ( $tcat, $tname ) = split(/::/, $objectives{ $seq } );

		if ( not $score ) { # missing
		    print qq{<div>Missing Score for $tcat, $tname SEQ:$seq</div>\n};
		}
		
		
		if ( $tcat ne $category or $tname ne $name ) { # error
		    print qq{$lex{Error} Mismatch: <b>$tcat - $category</b> OR };
		    print qq{<b>$tname - $name</b><br>\n};
		    next;
		}
		$studata{$seq} = $score;
		$total += $score;
		$count++;
	    }

=head
	    # Print the average
	    my $average;
	    if ( $count ) {
		$average = format_number( $total / $count, 2,2 );
	    } else {
		$average = 0;
	    }
=cut
	    print qq{<td>$total</td>\n}; # was $average, from above.
	    
	    # Equivalent Grade
	    my $equivgrade = scoreToGrade( $total, $readinglevel, $dratype );
	    print qq{<td>$equivgrade</td>\n};


	    # Now do the numeric print.
	    my %class = ( 1 => 'r', 2 => 'y', 3 => 'b', 4 => 'g' );
	    foreach my $key ( sort { $a <=> $b } keys %objectives ) { # numeric sort 
		my $val = $studata{$key};
		my $cl = $class{ $val };
		print qq{<td class="$cl">$val</td>};
	    }
	    print qq{</tr>\n};
	} # end of test print loop

    } # end of student loop.

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

}
