#!/usr/bin/perl
#  Copyright 2001-2025 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',
	   'Error' => 'Error',
	   'Class Reading Report' => 'Class Reading Report',
	   'Reading Level' => 'Reading Level',
	   'Name' => 'Name',
	   'Date' => 'Date',
	   'Continue' => 'Continue',
	   'Select' => 'Select',
	   'Student' => 'Student',
	   'Homeroom' => 'Homeroom',
	   'Grade' => 'Grade',
	   'Blank=All' => 'Blank=All',
	   'No Students Found' => 'No Students Found',
	   'Show Only Latest Test' => 'Show Only Latest Test',
	   'Gr' => 'Gr',
	   'Levels' => 'Levels',
	   'Score' => 'Score',
	   'Start Date' => 'Start Date',
	   'End Date' => 'End Date',
	   'EGr' => 'EGr',
	   'Students' => 'Students',
	   'Starting Season' => 'Starting Season',
	   'Ending Season' => 'Ending Season',
	   
	   );


# Grade => Start:End Reading Level
my %levelExpect = ( K => '0:3', 1 => '3:16', 2 => '16:28', 3 => '28:38', 4 => '40:50', 
		    5 => '50:60', 6 => '60:70', 7 => '70:80', 8 => '80:80', 9 => '90:90'); 


my %shortCategory = ( 'Oral Fluency' => 'OrFlu', 'Reading Engagement' =>'RdEg',
		      'Comprehension' => 'Comp', 'Printed Language Concepts' => 'pLgCcp',
		      'Oral Reading Fluency' => 'OrFlu');


my %seasondates = ('Spring' => {'start' => '01-01', 'end' => '03-31' },
		   'Summer' => {'start' => '05-15', 'end' => '06-30' },
		   'Fall' => {'start' => '09-01', 'end' => '10-31' }
    );


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

my $self = 'readRptClass.pl';

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.


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 to teacher settings.
my $tcgiurl = 'tcgi-bin'; # not correctly set in configuration?
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{'Class Reading Report'} - $schoolname};
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 { text-align:center; }
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};

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{<script language="javascript" type="text/javascript">
function showhelp(type,dra) {
  winName=window.open('/$tcgiurl/reading/showhelp.pl?id=' + type + '&dt=' + dra,'helpWindow',
  'height=300,width=700,screenX=100,screenY=100,resizeable');
  winName.focus();
}
</script>
$chartype\n</head><body style="padding:1em 6em 0 1em;">\n};


# Show Grade and Reading Levels Expected.
print qq{<div style="position:absolute;top:1em;right:1em;">\n};
print qq{<table cellspacing="0" cellpadding="3" border="1">\n};
print qq{<tr><th>$lex{Gr}</th><th>$lex{'Levels'}</th></tr>\n};
foreach my $key ( sort {$a <=> $b} keys %levelExpect ) {
    my ($start, $end ) = split(':', $levelExpect{$key} );
    if ( $start == '0' ) { $start = 'A'; }
    print qq{<tr><td>$key</td><td>$start - $end</td></tr>\n};
}
print qq{</table></div>\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.5em;">$title</h1>\n};


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

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



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

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


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

    # Get grades and homerooms
    my (@homerooms, @grades );
    my $sth = $dbh->prepare("select distinct homeroom from student 
      where homeroom is not NULL and homeroom != ''");
    $sth->execute;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    while ( my $hr = $sth->fetchrow ) {
	push @homerooms, $hr;
    }
    @homerooms = sort {$a <=> $b} @homerooms;

    # Grades
    $sth = $dbh->prepare("select distinct grade from student where grade is not NULL and grade != ''");
    $sth->execute;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    while ( my $gr = $sth->fetchrow ) {
	push @grades, $gr;
    }
    @grades = sort {$a <=> $b} @grades;

=head    
    # Distinct Seasons
    my (@seasons, %seasons);
    $sth = $dbh->prepare("select distinct season from read_test where season is not NULL");
    $sth->execute;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my %seasons;
    while ( my $season = $sth->fetchrow ) {
	my ($y,$s) = split('-',$season);
	if ( $s eq 'Fall' ) { $season = "$y-ZZZ"; } # fix sorting order.
	$seasons{$season} =  1; # Spring, Summer or Fall
    }
    @seasons = sort {$b cmp $a}  keys %seasons; # with 'aaa' rather than 'Spring'.
    @revseasons = sort {$a cmp $b}  keys %seasons; # with 'aaa' rather than 'Spring'. 
=cut
    
    # Form Start - Student Group
    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 value=""></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-- ) {
	print qq{<option value="$yr-Fall">$yr Fall (Sept 1 - Oct 31)</option>\n};
	print qq{<option value="$yr-Summer">$yr Summer (May 15 - June 30)</option>\n};
	print qq{<option value="$yr-Spring">$yr Spring (Jan 1 - March 31)</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};

    
    # Select Grade
    print qq{<tr><td class="bra">$lex{Select} $lex{Grade}</td>\n};
    print qq{<td class="la"><select name="grade"><option value=""></option>\n};
    foreach my $grade ( @grades ) {
	print qq{<option>$grade</option>\n};
    }
    print qq{</select></td></tr>\n};


    print qq{<tr><td class="bra">OR</td><td></td></tr>\n};

    # Select Homeroom
    my $sth = $dbh->prepare("select lastname, firstname from staff s, staff_multi sm 
      where s.userid = sm.userid and field_name = 'homeroom' and field_value = ?");


    print qq{<tr><td class="bra">$lex{Select} $lex{Homeroom}</td>\n};
    print qq{<td class="la"><select name="homeroom"><option value=""></option>\n};
    foreach my $hr ( @homerooms ) {
	$sth->execute($hr);
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth->fetchrow;
	my $hrname = $hr;
	if ( $lastname ) { $hrname = "$hr ($firstname $lastname)"; }

	print qq{<option value="$hr">$hrname</option>\n};
    }
    print qq{</select></td></tr>\n};

    # Show Withdrawn?
    print qq{<tr><td  class="bra">Show Withdrawn Students</td>};
    print qq{<td class="la"><input type="checkbox" name="showwithdrawn" value="1"></td></tr>\n};


    # Show Only Latest
    print qq{<tr><td class="bra">$lex{'Show Only Latest Test'}</td>\n};
    print qq{<td class="la">\n};
    print qq{<input type="checkbox" name="onlylatest" value="1" checked="checked">\n};
    print qq{</td></tr>\n};

    # Default to always only the latest value.
    #print qq{<tr><td colspan="2"><input type="hidden" name="onlylatest" value="1"></td></tr>\n};

#    print qq{<tr><td colspan="2"><hr></td></tr>\n};
    


=head    
    # Select Single Season
    print qq{<tr><td class="bra">$lex{'Starting Season'}</td>\n};
    print qq{<td class="la"><select name="startseason"><option></option>\n};
    foreach my $season ( @revseasons ) {
	if ( $season eq 'Undefined' ) { next; } # remove undefined.
	$season =~ s/ZZZ/Fall/;
	print qq{<option>$season</option>\n};
    }
    print qq{</select></td></tr>\n};


    # Select Ending Season
    print qq{<tr><td class="bra">$lex{'Ending Season'}</td>\n};
    print qq{<td class="la"><select name="endseason"><option></option>\n};
    foreach my $season ( @seasons ) {
	if ( $season eq 'Undefined' ) { next; } # remove undefined.
	$season =~ s/ZZZ/Fall/;
	print qq{<option>$season</option>\n};
    }
    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



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

    # foreach my $key ( sort keys %arr ) { print qq{K:$key V:$arr{$key}<br>\n}; }
    # Passed: startdate, enddate, season, grade or homeroom, onlylatest(always).
    # Previously I was using starting and ending season without any date ranges.
    
    # Load the reading library containing the scoreToGrade / showReadingLevel
    eval require "../../lib/libreading.pl";
    if ( $@ ) {
	print $lex{Error}. " $self: $@<br>\n";
	die $lex{Error}. "$self: $@\n";
    }

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

    if ( $arr{season} ) { # override start and end dates. Only use those dates below (no season)
	# Passed "Year-Season" values; convert into dates

	my ($yr,$ss) = split('-', $arr{season} );
	# print "YR:$yr SS:$ss<br>\n";
	
	# The seasondates lookup is text based 'Fall', etc.
	$startdate = $seasondates{$ss}{start};
	$startdate = qq{$yr-$startdate};
	$enddate = $seasondates{$ss}{end};
	$enddate = qq{$yr-$enddate};

    }
    delete $arr{season};
    # remove season.

    # Substitute in the Month with text value for display below.
    my $sdate = fmtDate( $startdate );
    my $edate = fmtDate( $enddate );

    
    my $studtable = 'student';
    if ( $arr{showwithdrawn} ) {
	$studtable = 'studentall';
    };

    # Get students in this grade or homeroom
    my ($select,$selectvalue);  # value of homeroom or grade
    print qq{<h3 style="text-align:left;font-size:120%;margin:0;padding:0.3em;">};
    
    if ( $arr{grade} ) {
	print qq{$lex{Grade} $arr{grade}};
	$selectvalue = $dbh->quote($arr{grade});
	$select = "where grade = $selectvalue";

    } elsif  ( $arr{homeroom} ) {

	print qq{$lex{Homeroom} $arr{homeroom}};
	$selectvalue = $dbh->quote( $arr{homeroom} );
	$select = "where homeroom = $selectvalue";

    } else {
	print qq{All Students\n};
    }
    

    # Get Teacher Name if a homeroom
    if ( $arr{homeroom} ) {
	my $sth = $dbh->prepare("select lastname, firstname from staff as s, staff_multi as sm
          where sm.userid = s.userid and field_name = 'homeroom' and field_value = ?");
        $sth->execute( $arr{homeroom} );
        if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my ( $lastname, $firstname ) = $sth->fetchrow;
	print qq{ &ndash; $firstname $lastname};
    }
    print qq{</h3>\n}; # finish description line
    
    # Display Dates;
    print qq{<div style="font-size:120%;margin:0.5em;">};
    print qq{Start <span style="font-weight:bold;">$sdate</span> |\n};
    print qq{End <span style="font-weight:bold;">$edate</span></div>\n};

    
    # Get students in this homeroom or grade.
    my (%sort, %studname );
    my $sth = $dbh->prepare("select studnum, lastname, firstname, grade from $studtable $select");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    while ( my ($studnum,$lname,$fname,$grade ) = $sth->fetchrow ) {
	$sort{"$lname$fname$studnum"} = $studnum;
	$studname{$studnum} = qq{<b>$lname</b>, $fname (Gr $grade)};
    }

    
    # Find any student tests
    my $sth = $dbh->prepare("select * from read_test where studnum = ? and
			    to_days(tdate) >= to_days('$startdate') and 
			    to_days(tdate) <= to_days('$enddate') ");
    

    # Loop over all student tests.
    my $first = 1;
    my (%readDra, %notests);
    foreach my $key ( sort keys %sort ) {
	my $studnum = $sort{$key};
	$sth->execute($studnum);
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	while ( my $ref = $sth->fetchrow_hashref ) {
	    $first = 0;
	    if ( not $ref ) { # no tests in this time period
		$notests{$studnum} = 1;
		next; # student
	    }
	    my %r = %$ref;  # will also have bktype here... fiction or nonfiction.
#	    print "SN:$r{studnum} Grade:$r{tgrade}<br>\n";
	    if ( not $r{dratype} ) { $r{dratype} = 2; }
	    if ( not defined $r{bktype} ) {  # for older tests without a book type
		if ( $r{readlevel} eq '16N' or $r{readlevel} eq '28N' or $r{readlevel} eq '38N' ) {
		    $r{bktype} = 'nonfiction';
		} else {
		    $r{bktype} = 'fiction';
		}
	    }
	    $readDra{ $r{readlevel} }{ $r{bktype} }{ $r{dratype} }{ $studnum } = 1;
	    
#	    print "RL:$r{readlevel} BK:$r{bktype} DRA:$r{dratype} SN:$studnum<br>\n";
	} # end of loop for single student.
    } # end of all students

     if ( $first ) { # No tests.
	 print qq{<h3 style="margin:1em;">No Records Found</h3>\n};
	 print qq{</body></html>\n};
	 exit;
    }
     

    # Next Description Line
    print qq{<div style="font-size:120%;text-align:left;">};
    print qq{<span style="color:red;">**</span> = Prev LLI program, };
    print qq{<span style="color:red;">***</span> = Current LLI program</div>\n};

    
#    use Data::Dumper;
#    print Dumper %readDra;
    
    foreach my $rl ( sort {$a <=> $b} keys %readDra ) {
	foreach my $bktype ( sort keys %{ $readDra{$rl} } ) {
	    foreach my $dratype ( sort keys %{ $readDra{$rl}{$bktype} } ) {
#		 print "RL:$rl DRA:$dratype BK:$bktype STUD:". %{$readDra{$rl}{$dratype}}. "<br>\n";
		my @temp = keys %{$readDra{$rl}{$bktype}{$dratype}};  # @temp are the students
		# print @temp, "<br>\n";
	    
		showReadingLevel( $rl, $arr{onlylatest}, \@temp, $startdate, $enddate,
				  $sortorder,$dratype, $bktype,$dbh );
	    }
	}
    }

    
    # Now add the exceptions table for this time period.
    my $sth1 = $dbh->prepare("select lastname, firstname, grade,homeroom from studentall 
			     where studnum = ?");
    
    my $sth = $dbh->prepare("select * from ssp_exceptions where to_days(tdate) >= to_days('$startdate')
			    and to_days(tdate) <= to_days('$enddate') and ssptype = 'dra' 
			    order by tdate");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    my $first = 1;
    
    while ( my $ref = $sth->fetchrow_hashref ) {
	my %r = %$ref;

	if ( $first ) { # start the table.
	    print qq{<table cellspacing="0" cellpadding="3" border="1" style="margin-bottom:1em;">\n};
	    print qq{<caption style="font-weight:bold;">Reasons for Students Missing Test</caption>\n};
	    # Table Heading
	    print qq{<tr><th>Date</th><th>Student</th><th>Reason</th></tr>};

	    $first = 0;
	}

	if ( not $studentname{$r{studnum}} ) { # find name and add to hash.
	    $sth1->execute($r{studnum});
	    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	    my ($lastname,$firstname,$grade,$homeroom) = $sth1->fetchrow;
	    if ( $arr{grade} and $grade ne $arr{grade} ) {
		next;
	    }
	    if ( $arr{homeroom} and $homeroom ne $arr{homeroom} ) {
		next;
	    }
	    
	    $studentname{$r{studnum}} = "<b>$lastname</b>, $firstname (Gr $grade/Hr $homeroom)";
	    # store in case needed later.
	}

	
	print qq{<tr><td>$r{tdate}</td><td class="la">$studentname{$r{studnum}}</td>};
	print qq{<td class="la">$r{reasoncode} $r{reasonother}</td></tr>\n};


    }

    print qq{</table>\n};
    # End of exceptions table section
    
    print qq{</body></html>\n};

    exit;

}
