#!/usr/bin/perl
#  Copyright 2001-2019 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',
	   'Student' => 'Student',
	   'Continue' => 'Continue',
	   'No User Id' => 'No User Id',
	   'No Password' => 'No Password',
	   'Please Log In' => 'Please Log In',
	   'Grade' => 'Grade',
	   'Select' => 'Select',
	   'Grade' => 'Grade',
	   'Select' => 'Select',
	   'No Students Found' => 'No Students Found',
	   'Group' => 'Group',
	   'Attendance' => 'Attendance',
	   'Kit' => 'Kit',
	   'Lesson' => 'Lesson',
	   'Initial' => 'Initial',
	   'Progress' => 'Progress',
	   'Report' => 'Report',
	   'Pre-test' => 'Pre-test',
	   'Post-test' => 'Post-test',
	   'Data' => 'Data',
	   'Gain' => 'Gain',
	   'Loss' => 'Loss',
	   'Total Hours' => 'Total Hours',
	   'Percentage' => 'Percentage',
	   'Attendance' => 'Attendance',
	   'Name' => 'Name',
	   'Years' => 'Years',
	   'Date' => 'Date',
	   'Not Found' => 'Not Found',

	   );

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


my $self = 'lintRptProgress.pl';

my $searchinterval = 30; # How many days forward or backwards to look for pre/post tests.


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


my @tim = localtime(time);
my $year = $tim[5] + 1900;
my $month = $tim[4] + 1;
my $day = $tim[3];
if ( length( $month) == 1 ) { $month = '0'. $month; }
if ( length( $day) == 1 ) { $day = '0'. $day; }
my $currdate = "$year-$month-$day";


# Yes, both the same but leave in case locations change.
my  $configpath = '../..';
if ( getcwd() =~ m/tcgi/ ){ # we are in tcgi
    $configpath = '../..';
}


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


eval require "$configpath/lib/libreading.pl";
if ( $@ ) {
    print $lex{Error}. " $self: $@<br>\n";
    die $lex{Error}. "$self: $@\n";
}


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

# If no session we do this about here.
print $q->header( -charset, $charset );

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


=head

# Session Setup Here
my $session = new CGI::Session("driver:mysql;serializer:FreezeThaw",
 undef,{Handle => $dbh}) or die CGI::Session->errstr;

my ( $userid, $duration);
# Get/Set  Session Values (a defined userid means it was passed)
if ( $arr{userid} ){ # we want to login, passed userid/password pair.

    # Check password/userid against database (-1 no user, -2 wrong password);
    my $error = checkPassword($arr{userid}, $arr{password});
    if ($error == -1){ print $q->header( -charset, $charset ); login($lex{'No User Id'}); }
    if ($error == -2){ print $q->header( -charset, $charset ); login($lex{'No Password'}); }

    $cookietime = checkCookieTime( $arr{duration} );

    # Set values for userid and logged_in in session
    $session->param( 'logged_in','1');
    $session->expire( 'logged_in', $cookietime );
    $session->param( 'userid',$arr{userid} );
    $session->param( 'duration',$cookietime );

    $userid = $arr{userid};


} else { # check logged_in value in session

    if ( not $session->param('logged_in') ){
	$userid = $session->param('userid');
        print $q->header( -charset, $charset );
	print qq{<p>[ <a href="$tchpage">$lex{Main}</a> ]</p>\n};
        print qq{<h3>$lex{'Please Log In'}</h3></body></html>\n}; 
        exit;
    }
    # Ok, we have a login. Values below we have in environment.

    $userid = $session->param('userid');
    $duration = $session->param('duration');

    if ( not ($duration =~ /\+/)) { # if not in +20m format, do so.
	$duration = checkCookieTime( $duration );
    }

    $session->expire('logged_in', $duration );


} # End of check for logged_in value

print $session->header( -charset, $charset );
# Session Setup End

=cut


# Page Header
my $title = "$lex{Student} $lex{Progress} $lex{Report}";
my $fulltitle = "Primary, Intermediate &amp; Middle Years<br>Literacy Intervention &ndash; $title";

print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\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};
print qq{<style type="text/css">div.head { font-weight:bold;font-size:90%; }</style>\n};

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


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

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

    print qq{<h2>$fulltitle</h2>\n};
    
    foreach my $id ( keys %arr ) {
	showReport($id);
    }
    print qq{</body></html>\n};

    
} 


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

    print qq{<h1>$title</h1>\n}; # both edit and delete

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

    print qq{<div style="font-weight:bold;">$lex{Select} $lex{Group}</div>\n};
    print qq{<table cellpadding="5" cellspacing="0" border="1">\n};

    print qq{<tr><th>Name</th><th>Description</th><th>ID</th><th>Start Date</th><th>End Date</th></tr>\n};
    print qq{<tr><td colspan="5"><input type="submit" value="$lex{Continue}"></td></tr>\n};

    # Select Program
    my $sth = $dbh->prepare("select p.*, s.lastname,s.firstname from lint_program p
      left join staff s on s.userid = p.userid  order by startdate desc, s.lastname, s.firstname");

    $sth->execute;
    if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; }

    while ( my $ref = $sth->fetchrow_hashref ) {

	my %lr = %$ref;

	# Get Staff Member Name; part of main query.
	my $teachername;
	if ( $lr{lastname} ) {
	    $teachername = qq{<b>$lr{lastname}</b>, $lr{firstname}};
	} else {
	    $teachername = qq{<span style="color:red;">$lex{'Not Found'}:</span> $lr{userid}}
	}

	print qq{<tr><td><input type="checkbox" name="$ref->{id}" value="1">$teachername</td>\n};
	print qq{<td>$lr{groupdesc}</td><td class="cn">$lr{id}</td>};
	print qq{<td>$lr{startdate}</td><td>$lr{enddate}</td></tr>\n};

    }


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

    print qq{</table></form>\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}; }

    my $id = shift;  # from @_;


    # Get the Program Information
    my $sth = $dbh->prepare("select * from lint_program where id = ?");
    $sth->execute( $id );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $progref = $sth->fetchrow_hashref;
    my %pr = %$progref;

    # Get JD of start/end of program and search dates, if required
    my $programstartjd = julian_day( split('-', $pr{startdate}) );
    my $prgstartPlus = join('-', inverse_julian_day( $programstartjd + $searchinterval ));
    my $prgstartMinus = join('-', inverse_julian_day( $programstartjd - $searchinterval ));

    my $programendjd = julian_day( split('-', $pr{enddate}) );
    my $prgendPlus = join('-', inverse_julian_day( $programendjd + $searchinterval ));
    my $prgendMinus = join('-', inverse_julian_day( $programendjd - $searchinterval ));

#    print qq{Program: prgstartPlus: $prgstartPlus Minus:$prgstartMinus<br>\n};
#    print qq{Program: End: $prgendPlus Minus:$prgendMinus<br>\n};


    # Get the LLI Instructor
    $sth = $dbh->prepare("select lastname, firstname from staff where userid = ?");
    $sth->execute( $pr{userid} );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my ($lastname, $firstname) = $sth->fetchrow;

    print qq{<div class="head">$firstname $lastname &ndash; $pr{groupdesc} (ID $id)</div>\n};
    print qq{<div class="head">}. formatDate($pr{startdate}). q{ &ndash; }. formatDate($pr{enddate}). qq{</div>\n};

    print qq{<div class="head">Search Interval +/- $searchinterval Days from Start/End of Program</div>\n};

    # Start Table and Headings.
    print qq{<table cellpadding="3" cellspacing="0" border="1" style="text-align:center;">\n};
    print qq{<tr><th>$lex{Name}</th><th>$lex{Grade}</th>\n};
    print qq{<th colspan="4">$lex{'Pre-test'} $lex{Data}</th>\n};
    print qq{<th>$lex{Initial} $lex{Kit}<br>/$lex{Lesson}</th>\n};
    print qq{<th colspan="4">$lex{'Post-test'} $lex{Data}</th>\n};
    print qq{<th>$lex{Gain}/$lex{Loss}<br>($lex{Years})</th><th>$lex{'Total Hours'}</th>\n};
    print qq{<th>$lex{Percentage}<br>$lex{Attendance}</th></tr>\n};

    print qq{<tr><th colspan="2"></th><th>$lex{Date}</th><th>DRA</th><th>Tot<br>Sc</th><th>Gr<br>Eq</th><th></th>\n};
    print qq{<th>$lex{Date}</th><th>DRA</th><th>Tot<br>Sc</th><th>Gr<br>Eq</th><th colspan="3"></th></tr>\n};


    # Get the students in program and names, studnum
    $sth = $dbh->prepare("select l.*,s.lastname,s.firstname, s.grade from lint_student l, studentall s
      where s.studnum = l.studnum and progid = ? order by s.lastname, s.firstname, l.id");

    # Get this test score and grade level
    my $sth2 = $dbh->prepare("select sum(score), count(*) from read_test_score 
      where testid = ?");

    my @students;
    my %comment;
    my %name;
    my $first = 1;


    $sth->execute( $id );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    while ( my $ref = $sth->fetchrow_hashref ) {

	$first = 0;

	my %sr = %$ref; # sr = Student Record
	if ( $sr{comment} ) {
	    push @students, $sr{studnum};
	    $comment{$sr{studnum}} = $sr{comment};
	    $name{$sr{studnum}} = "<b>$sr{lastname}</b>, $sr{firstname}";
	}
	# foreach my $key ( sort keys %sr ) { print qq{SKey:$key V:$sr{$key}<br>\n}; } print qq{<br>\n};


	# Find the Pretest.
	my $sth1 = $dbh->prepare("select * from read_test where studnum = ? and
         to_days( tdate ) <= to_days('$pr{startdate}') and 
         to_days( tdate ) >= to_days('$prgstartMinus') order by tdate desc ");
	$sth1->execute( $sr{studnum} );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $pretestref = $sth1->fetchrow_hashref;


	if ( not $pretestref ) { # move the date to look at first test WITHIN date range
	    my $sth1 = $dbh->prepare("select * from read_test where studnum = ? and
             to_days( tdate ) > to_days('$pr{startdate}') and  to_days( tdate ) <= to_days('$prgstartPlus')
             order by tdate "); # first one within this date range.
	    $sth1->execute( $sr{studnum} );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	    $pretestref = $sth1->fetchrow_hashref;
	}


	my %pretest = %$pretestref;

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

	# Get the pretest Scores
	$sth2->execute( $pretest{id} );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my ( $prescoretotal, $prescorecount ) = $sth2->fetchrow;
	my $prepossibletotal = $prescorecount * 4;

	my $equivgrade = scoreToGrade( $prescoretotal, $pretest{readlevel} );


	# Start of Line
	print qq{<tr><td class="la"><b>$sr{lastname}</b>, $sr{firstname} };
	if ( $sr{startdate} ) { print qq{<br><span style="font-size:80%;"><b>Late Entry</b> $sr{startdate}</span>}; }
	print qq{</td><td>$sr{grade}</td>\n};
	print qq{<td>$pretest{tdate}</td>};
	print qq{<td>$pretest{readlevel}</td>};
	if ( $pretest{readlevel} < 40 ) {
	    print qq{<td>$prescoretotal</td>\n};
	} else {
	    print qq{<td>$prescoretotal / $prepossibletotal</td>\n};
	}
	print qq{<td>$equivgrade</td>\n};


	# Now the Kit info
	print qq{<td>$sr{initialkit} / $sr{initiallesson}</td>\n};

	if ( $sr{withdrawtype} ) { # dropped course
	    print qq{<td>$sr{enddate}</td><td colspan="3"><b>$sr{withdrawtype}</b></td>};
	    print qq{<td></td><td></td><td></td></tr>\n};

	} else {

	    # Find the Posttest.
	    $sth1 = $dbh->prepare("select * from read_test where studnum = ? and
              to_days( tdate ) >= to_days('$pr{enddate}') and 
              to_days( tdate ) <= to_days( '$prgendPlus' )");
	    $sth1->execute( $sr{studnum} );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	    my $posttest_ref = $sth1->fetchrow_hashref;
#	    print qq{Post Test ref: $posttest_ref<br>\n};

	    if ( not $posttest_ref ) { # move the date to look at first test WITHIN date range
		$sth1 = $dbh->prepare("select * from read_test where studnum = ? and
                  to_days( tdate ) <= to_days( '$pr{enddate}' ) and 
                  to_days( tdate ) >= to_days( '$prgendMinus' ) order by tdate desc");
		$sth1->execute( $sr{studnum} );
		if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
		$posttest_ref = $sth1->fetchrow_hashref;
		if ( $posttest_ref and $posttest_ref->{id} == $pretestref->{id} ) { # same test; bad!
		    $posttest_ref = undef;
		}
	    }

#	    print qq{Post Test 2 ref: $posttest_ref<br>\n};

	    my %posttest = %$posttest_ref;

#	    print qq{Post: ", %posttest, qq{<br>\n};


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

	    # Get the posttest Scores
	    $sth2->execute( $posttest{id} );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	    my ( $postscoretotal, $postscorecount ) = $sth2->fetchrow;
	    my $postpossibletotal = $postscorecount * 4;

	    my $postequivgrade = scoreToGrade( $postscoretotal, $posttest{readlevel} );

	    print qq{<td>$posttest{tdate}</td>\n};
	    print qq{<td>$posttest{readlevel}</td>\n};
	    if ( $posttest{readlevel} < 40 ) {
		print qq{<td>$postscoretotal</td>\n};
	    } else {
		print qq{<td>$postscoretotal / $postpossibletotal</td>\n};
	    }
	    print qq{<td>$postequivgrade</td>\n};

	    # Loss/Gain.
	    my $delta;
	    if ( $postequivgrade ) {
		$delta = format_number( $postequivgrade - $equivgrade, 2,2);
	    }
	    print qq{<td>$delta</td>};

	    # Hours Taught / Percent Attendance. 
	    # Hours taught is entered by teacher, attendance is calculated.
	    print qq{<td>$sr{programhours}</td>};

	    # Attendance
	    my $attendance;
	    if ( not $pr{programhours} ) { 
		print qq{<h3>$lex{Error}: Program Hours not defined</h3>\n};
		print qq{</body></html>\n};
		exit;
	    } else { # OK, $pr{programhours} has a non zero value.

		my $enrolledhours;
		if ( $sr{attendance} ) { # late start student; attendance field holds hours enrolled
		    $enrolledhours = $sr{attendance};
		} else { 
		    $enrolledhours = $pr{programhours};
		}

		$attendance = format_number( ($sr{programhours} / $enrolledhours ) * 100, 0);
	    }

	    print qq{<td>$attendance%</td></tr>\n};

	} # end of else: (ie. not dropped)

    } # end of student loop.

    if ( $first ) {
	print qq{</table></form><h1>$lex{'No Students Found'}</h1>\n};
	print qq{</body></html>\n};
	return;
    }

    print qq{</table>};


    # Comments section.
    my $first = 1;
    foreach my $studnum ( @students ) { 
	if ( $first ) {
	    print qq{<h3>Comments</h3>\n};
	    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
	    $first = 0;
	}

	print qq{<tr><td style="la">$name{$studnum}</td><td class="la">$comment{$studnum}</td></tr>\n}
    }

    if ( not $first ) { # close table.
	print qq{</table>\n};
    }

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

    return;

} # end of showReport



#-------------
sub formatDate {
#-------------

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


