#! /usr/bin/perl
#  Copyright 2001-2024 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',
	   'Continue' => 'Continue',
	   'Grade' => 'Grade',
	   'Error' => 'Error',
	   'Common Math Assessment' => 'Common Math Assessment',
	   'Report' => 'Report',
	   'Name' => 'Name',
	   'Tests' => 'Tests',
	   'No Students Found' => 'No Students Found',
	   'Last,First/Last/Initials/Studnum' => 'Last,First/Last/Initials/Studnum',
	   'Search' => 'Search',
	   'Show Withdrawn' => 'Show Withdrawn',
	   'Attendance' => 'Attendance',
	   'View' => 'View',
	   
	   );

my $self = 'cmaRpt9.pl'; # individual student report.

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

my @strands = qw(P N SS SP);
my %strandnames = ('P' => 'Patterns and Relations', 
		   'N' => 'Numbers and Operations',
		   'SS' => 'Shape and Space',
		   'SP' => 'Stats and Prob'
    );

=head
my %colormap = ( 1 => '#822',
		 2 => '#BB1',
		 3 => '#228',
		 4 => '#282'
    );
=cut

my %colormap = ( 1 => 'r',
		 2 => 'y',
		 3 => 'b',
		 4 => 'g'
    );


my  $configpath = '../../..';
my $linkpath = '../../attendance';  # for links to rptattstud1.pl
if ( getcwd() =~ /tcgi/ ){ # we are in tcgi
    $configpath = '../..';
    $linkpath = '..';
}

eval require "$configpath/etc/admin.conf";
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 $currsdate = "$year-$mon-$mday";
my $currdate = "$dow[$wday], $month[$mon] $mday, $year";
my $currjd = julian_day( split('-', $currsdate) );

# setup values for links to student attendance report (studattrpt1.pl)
my ($sy,$ey) = split('-', $schoolyear); # global config
my $endmonth = "$year-$mon";  # based on current month.
my $startmonth = "$sy-08";



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


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


my $title = "$lex{Report} 9 - Student Report - $schoolname";
print qq{$doctype\n<html><head><title>$lex{'Common Math Assessment'} $title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\n};
print qq{$chartype\n</head><body style="padding:1em 5em;">\n};

print qq{<style>\n};
print qq{td.r { background-color:#822;color:white;font-size:120%;font-weight:bold;text-align:center;}\n};
print qq{td.y { background-color:#BB1;color:white;font-size:120%;font-weight:bold;text-align:center;}\n};
print qq{td.b { background-color:#228;color:white;font-size:120%;font-weight:bold;text-align:center;}\n};
print qq{td.g { background-color:#282;color:white;font-size:120%;font-weight:bold;text-align:center;}\n};
print qq{</style>\n};


print qq{<div>[ <a href="$homepage">$lex{Main}</a> ] $lex{'Common Math Assessment'}</div>\n};
print qq{<h1>$title</h1>\n};


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

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


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

    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="la"><input type="text" name="student" size="30">};
    print qq{<input type="submit" value="$lex{Search}"></td></tr>\n};
    
    print qq{<tr><td class="la"> $lex{'Last,First/Last/Initials/Studnum'}</td>\n};

    # Withdrawn
    print qq{<tr><td class="la">$lex{'Show Withdrawn'}};
    print qq{<input type="checkbox" name="showwithdrawn" value="1"></td></tr>\n};
    
    
    print qq{</table></form>\n};

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

    exit;

} # end of showStartPage


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

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

    # Setup the Search
    if ($student =~ /\d+/) {  # we have a student number
	$studnum = $student;
	$sth = $dbh->prepare("select lastname, firstname, studnum, grade from $studenttable
           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, grade
              from $studenttable 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, grade from $studenttable
                   where lastname $sql{like} ? and firstname $sql{like} ?
                   order by lastname, firstname");
		$sth->execute( $li, $fi );
	    } else {
		$sth = $dbh->prepare("select lastname, firstname, studnum, grade 
                 from $studenttable where lastname = ? 
                 order by lastname, firstname");
		$sth->execute( $lastname );
	    }
	} else {
	    $sth = $dbh->prepare("select lastname, firstname, studnum, grade 
              from $studenttable 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};
    if ( $arr{showwithdrawn} ) {
	print qq{<caption style="color:red;font-weight:bold;">WD = Withdrawn Student</caption>\n};
    }
    
    print qq{<tr><th>$lex{Name}</th><th title="Grade">Grd</th><th title="Attendance">Attend</th>};
    print qq{<th>#$lex{Tests}</th><th>Results</th></tr>\n};

    
    my $sth1 = $dbh->prepare("select count(*) from mathca_scores where studnum = ?");
    my $sth2 = $dbh->prepare("select count(*) from studentwd where studnum = ?");
    
    # Loop through each found student.

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

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

	# Withdrawn?
	$sth2->execute( $studnum );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my $wdcount = $sth2->fetchrow;
	my $wd;
	if ( $wdcount ) { 
	    $wd = qq{<span style="font-weight:bold;color:red;">WD</span>\n};
	}
	
	print qq{<tr><td class="la">$wd <b>$lastname</b>, $firstname};
	print qq{ ($studnum)</td><td class="cn">$grade</td>};

	# Attendance/Enrollment Link
	print qq{<td><form action="$linkpath/rptattstud1.pl" method="post">\n};
	print qq{<input type="hidden" name="page" value="2">\n};
	print qq{<input type="hidden" name="startmonth" value="$startmonth">\n};
	print qq{<input type="hidden" name="endmonth" value="$endmonth">\n};
	print qq{<input type="hidden" name="$studnum" value="1">\n};
	print qq{<input type="submit" value="$lex{View}"></form></td>\n};

	# Tests
	print qq{<td class="cn">$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="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 "K:$key V:$arr{$key}<br>\n"; }

    my $studenttable = 'studentall';
#    if ( $arr{showwithdrawn} ) {
#	$studenttable = 'studentwd';
#    }


=head
    # Figure out the number of days in the school year and also where
    # the current date fits into that.
    my %closed;    # $closed{julian date} = fraction of day closed.
    my $sth = $dbh->prepare("select date, dayfraction from dates");
    $sth->execute;
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my ($d, $frac) = $sth->fetchrow ) {
	if ( not $frac ) { next; } # just in case
	my $jd = julian_day( split('-', $d) );
	$closed{$jd} = $frac;
    }

    my $startjd = julian_day( split('-', $schoolstart) );
    my $endjd = julian_day( split('-', $schoolend) );

#    print "School Start: $schoolstart School End:$schoolend<br>\n";


    # loop through the school year; count # number of days until end and also until the current date.
    my ($totaldays, $partdays );
    for my $jd ( $startjd..$endjd ) { # run through the school year

	my $dow = day_of_week( $jd );
	if ( $dow == 6 or $dow == 1 ) { next; }

	if ( $closed{$jd} ) {
	    my $open = 1 - $closed{$jd};
	    $totaldays += $open;
	    if ( $jd <= $currjd ) { $partdays += $open; }

	} else {
	    $totaldays++;
	    if ( $jd <= $currjd ) { $partdays++; }
	}
    }


#    print "<br><br>Total:$totaldays Part:$partdays<br>\n";
 
    my $percentdone = format_number( $partdays * 100 / $totaldays, 1,1 );
    print qq{<h3>Percent of School Year Complete: $percentdone%</h3>\n};
    print qq{<h3>$classname  &ndash; $currdate</h3>\n};

=cut


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

    
    # Build Outcomes selection
    my %outcomes; # lists outcomes.
    my %odesc; # outcomes description.

    my $sth = $dbh->prepare("select * from mathca_outcomes");
    $sth->execute;
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $ref = $sth->fetchrow_hashref ) {
	my %r = %$ref;

	my $oid = $r{oid};
	my $grade = $r{grade};

	my ($cat, $seq)  = split(/\./, $oid);
	$cat =~ s/$grade$//; # remove grade

	$outcomes{$grade}{$cat}{$seq} = $oid;
	$odesc{$oid} = $r{odesc};

    } # Done building data structure.

    my $sth1 = $dbh->prepare("select tgrade from  mathca_scores where studnum = ? and schoolyear = ?");
    
    # Get the student's school years
    my $sth = $dbh->prepare("select distinct schoolyear from mathca_scores where studnum = ? order by schoolyear");
    $sth->execute( $arr{studnum} );
    if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $year = $sth->fetchrow ) {

	# Get the grade for this school year (assume only 1)
	$sth1->execute( $arr{studnum}, $year );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $grade = $sth1->fetchrow;


	# Now build a structure for this grade
	my %strandcount;  # $catcount{category} = number in this category.
	foreach my $cat ( sort keys %{ $outcomes{$grade} } ) {
	    foreach my $seq ( sort keys %{ $outcomes{$grade}{$cat} } ) {
		if ( $seq > $strandcount{$cat} ) { $strandcount{$cat} = $seq; }
	    }
	}

	my $totaloutcomes;
	foreach my $key ( keys %strandcount ) {
	    $totaloutcomes += $strandcount{$key};
	}

	
	my %data; # holds all data $data{studnum}{outcome}{prepost} = score;
	my %pass; # $pass{studnum} = count of passes ( >= 3)
	my %strandpass; 
	my %tdates; # store test dates for outcomes and pre/post  $tdates{outcome}{pretest/posttest};

	# Get Student Data
	my $sth1 = $dbh->prepare("select prepost, outcome, score, tdate from mathca_scores
          where schoolyear = ? and studnum = ? order by tdate");

	# Get this student's data
	$sth1->execute( $year, $arr{studnum} );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }

	while ( my ($prepost, $outcome, $score, $tdate) = $sth1->fetchrow ) {
	    if ( $prepost eq 'posttest' ) {  # only do posttests for data.
		push @{ $data{$studnum}{$outcome} }, $score;
		if ( $score >= 3 ) { $pass{$studnum}{'pass'}++; }
		$pass{$studnum}{'count'}++; 
	    }
	}
	


	# Start Printing Data
	print qq{<div style="font-size:120%;font-weight:bold;margin-top:1em;">Grade $grade</div>\n};
	print qq{<table cellpadding="2" cellspacing="0" border="1">\n};
	print qq{<caption>Hover on Column Titles to see text descriptions</caption>\n};

	# header section.
	print qq{<tr><th>Student</th><th title="Pass Percentage">Pass<br>Per</th>};
	print qq{<th title="Mastery Level for Complete Curriculum">MST</th>};
	foreach my $strand ( @strands ) {
	    if ( $strandcount{$strand} ) { # print IF we have that strand
		print qq{<th colspan="$strandcount{$strand}" };
		print qq{title="Number in brackets is number of outcomes in this strand for this grade">};
		print qq{$strandnames{$strand} ($strandcount{$strand})</th>\n};
	    }
	}

	print qq{</tr>\n};

	# Second Line: Desc;
	print qq{<tr><th></th><th></th><th></th>};
	foreach my $strand ( @strands ) {
	    if ( $strandcount{$strand} ) { # print IF we have that strand
		foreach my $seq ( sort keys %{ $outcomes{$grade}{$strand} } ) {
		    my $outcome = $outcomes{$grade}{$strand}{$seq};
		    print qq{<th title="$odesc{$outcome}">$outcome</th>};
		}
	    }
	}
	print qq{</tr>\n};


	print qq{<tr><td><b>$lastname</b>, $firstname</td>\n};

	# %pass
	my ($pass, $mst, $outcomecount);
	if ( $pass{$studnum}{count} ) {
	    $pass = format_number( $pass{$studnum}{pass} * 100 / $pass{$studnum}{count}, 0, 0);
	    #if ( $pass ) { $pass .= '%'; }
	}

	# now figure out how many outcomes have scores
	foreach my $outcome ( keys %{ $data{$studnum} } ) {
	    if ( ${ $data{$studnum}{$outcome} }[0] ) {
		$outcomecount++;
	    }
	}
	if ( $pass{$studnum}{count} and $totaloutcomes ) {
	    $mst = format_number( $pass{$studnum}{pass} /
				  $pass{$studnum}{count} * $outcomecount / $totaloutcomes,  2, 2);
	}

	print qq{<td>$pass</td><td>$mst</td>};

	foreach my $strand ( @strands ) {

	    if ( not $strandcount{$strand} ) { next; } # skip any strands not covered in this grade.
		
	    foreach my $seq ( sort keys %{ $outcomes{$grade}{$strand} } ) {
		my $outcome = $outcomes{$grade}{$strand}{$seq};
		
		my @scores = @{ $data{$studnum}{$outcome} };
		
		my $displayval;
		my $first = 1;
		my $max;

		foreach my $score ( @scores ) {
		    if ( not $first ) { 
			$displayval .= qq{/}; 
		    } else { 
			$first = 0; 
		    }
		    $displayval .= $score;
		    if ( $score > $max ) { $max = $score; }
		    
		}

		my $class = $colormap{$max};
		    
		print qq{<td class="$class">$displayval</td>};

	    }

	} # end of this strand
	print qq{</tr></table>\n};
	
    } # end of this year

=head
	# now totals for this student
	my ($pretotalavg, $posttotalavg);
	if ( $pretotalcount ) {
	    $pretotalavg = format_number( $pretotalsum / $pretotalcount, 2);
	}

	if ( $posttotalcount ) {
	    $posttotalavg = format_number( $posttotalsum / $posttotalcount, 2);
	}

	my $diff = format_number( $posttotalavg - $pretotalavg, 2);

	print qq{<td class="cn">$posttotalcount</td><td class="cn">$pretotalavg</td>};
	print qq{<td class="cn">$posttotalavg</td><td class="cn">$diff</td>\n};

	# Passes;
	my $passpercent;
	if ( $pass{$studnum}{'count'} and $pass{$studnum}{'pass'} ) {
	    $passpercent = format_number( $pass{$studnum}{'pass'} * 100 / $pass{$studnum}{'count'}, 2);
	}
	
	if ( $passpercent ) {
	    print qq{<td>$passpercent% ($pass{$studnum}{'pass'}/$pass{$studnum}{'count'})</td></tr>\n};
	} elsif ( $pass{$studnum}{'count'} ) { # have count, but no passes
	    print qq{<td>0% (0/$pass{$studnum}{'count'})</td></tr>\n};
	} else { # print blank.
	    print qq{<td></td></tr>\n};
	}
=cut


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


     # next grade.

    print qq{<div style="padding:1em 1em 0 1em;font-weight:bold;">};
    print qq{All scores are posttest scores. Pretest scores are };
    print qq{not shown on this report</div>\n};

    print qq{<div style="padding:1em 1em 0 1em;font-weight:bold;">};
    print qq{If more than one test is given to a student on the };
    print qq{same outcome, these scores are separated by slashes</div>\n};

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

    exit;

} # end of showReport
