#!/usr/bin/perl
#  Copyright 2001-2021 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' => 'Class',
	   'Reading Level' => 'Reading Level',
	   'Reading' => 'Reading',
	   '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',
	   'Avg' => 'Avg',
	   'Start Date' => 'Start Date',
	   'End Date' => 'End Date',
	   'EGr' => 'EGr',
	   'Graph' => 'Graph',
	   'Spring' => 'Spring',
	   'Fall' => 'Fall',
	   'Start Date' => 'Start Date',
	   'End Date' => 'End Date',


	   );


use DBI;
use CGI;
use Number::Format qw(:all);
use Cwd;
use GD::Graph::bars;
use GD::Graph::colour qw(:colours);
use Time::JulianDay;

my $self = 'readRptClassGraph.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 to teacher settings.
if ( getcwd() !~ /tcgi/ ) { # we are in cgi

    $tchcss = $css;
    $tchpage = $homepage;
    $tchdownloaddir = $downloaddir;
    $tchwebdownloaddir = $webdownloaddir;
}


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 = "$lex{Class} $lex{Reading} $lex{Graph}";

print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$tchcss" type="text/css">
<style type="text/css">
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) {
  winName=window.open('/tcgi-bin/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 6em 0 0.5em;">\n};


print qq{[ <a class="alt" href="$tchpage">$lex{Main}</a> ]\n};
print qq{<h1 style="text-align:left;margin:0;padding:0.5em;">};
print $title;
print qq{ - $schoolname }. fmtDate($currdate). qq{</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 {
#----------------


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

    print qq{<tr><td class="ra">$lex{Select} $lex{Student}</td>};
    print qq{<td><select name="group">};
    print qq{<option value="grade">$lex{Grade}</option>\n};
    print qq{<option value="homeroom">$lex{Homeroom}</option>\n};
    print qq{</select>\n};
    print qq{<input type="text" name="groupval" size="10"> };
    print qq{</td></tr>\n\n};


=head
    print qq{<tr><td class="ra">$lex{'Reading Level'}</td>\n<td class="la">};
    print qq{<select name="readlevel"><option></option>\n};
    foreach my $rl ( @readinglevel ) {
	print qq{<option>$rl</option>};
    }
    print qq{\n</select> $lex{'Blank=All'}</td></tr>\n\n};


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


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

    # 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 $startdate = $arr{startdate};
    my $enddate = $arr{enddate};
    delete $arr{startdate};
    delete $arr{enddate};   


    # Heading Section - Group Name
    my $title;
    if ( $arr{groupval} ) {
	print qq{<h3 style="text-align:left;font-size:120%;margin:0;padding:0.3em;">};
	if ( $arr{group} eq 'grade' ) {
	    $title = "$lex{Grade} $arr{groupval}";
	    print $title;
	} else {
	    $title = "$lex{Homeroom} $arr{groupval}";
	    print $title;
	}
	print qq{</h3>\n};
    }
    print qq{<div>$lex{'Start Date'} $startdate&nbsp;&nbsp;$lex{'End Date'} $enddate</div>\n};


    my @students;
    my $group;

    if ( $arr{group} eq 'grade' ) {
	$group = 'grade';
    } else {
	$group = 'homeroom';
    }


    my $groupval = $arr{groupval};
    $groupval =~ s/'//g;
    

    my $sth = $dbh->prepare("select studnum from student
     where $group = ? order by lastname, firstname");
    $sth->execute( $groupval );
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    while ( my $studnum = $sth->fetchrow ) {
	push @students, $studnum;
    }

    if ( not @students ) { 
	print qq{<div style="border:1px solid gray;padding:1em;};
	print qq{background-color:red;font-weight:bold;font-size:120%;">\n};
	print $lex{'No Students Found'};
	print qq{</div></body></html>\n};
	exit;
    }

    showMultiTest( \@students, $startdate, $enddate, $title );

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

    exit;

}



#----------------
sub showMultiTest {
#----------------
    
    my ( $studref, $startdate, $enddate, $title ) = @_;
    my @students = @$studref;

#    my $startjd = julian_day( split(/-/, $startdate) );
    my $endjd = julian_day( split(/-/, $enddate) );

    my @splits = (); # split dates
    my $currdate = $startdate;

    do {
	if ( $currdate ne $startdate ) {
	    push @splits, $currdate;
	}

	my ($yr, $mo, $da ) = split(/-/, $currdate);
	if ( $mo >= 7 ) {
	    $yr++;
	    $currdate = "$yr-01-01";
	} else {
	    $currdate = "$yr-07-01";
	}

    } until  $currdate > $enddate;


    my $blockstart;
    my $blockend = $startdate;
    my $blockcounter = 1;
    my %block = (); # store in julian format
    my %blockdate = (); # stores normal date formats

    while ( @splits ) {

	$blockstart = $blockend;
	$blockend = shift @splits;
	$bstartjd = julian_day( split(/-/, $blockstart) );
	$bendjd = julian_day( split(/-/, $blockend) );
	$block{$blockcounter} = { 'start' => $bstartjd, 'end' => $bendjd };
	$blockdate{$blockcounter} = { 'start' => $blockstart, 'end' => $blockend };
	# print qq{Block:$blockcounter Start:$blockstart  End:$blockend<br>\n};
	$blockcounter++;

    }

    # put in final block section.
    $block{$blockcounter} = { 'start' => $bendjd, 'end' => $endjd };
    $blockdate{$blockcounter} = { 'start' => $blockend, 'end' => $enddate };
    my $maxblock = $blockcounter;

    # Show block values
    # foreach my $blk ( sort keys %block ) {
    # print qq{Block:$blk Start:$block{$blk}{'start'}  End:$block{$blk}{'end'}<br>\n};
    #}


    # Put in the Legend values
    my (%legend, @legend);
    foreach my $blk ( sort keys %blockdate ) {
	my ( $yr,$mo,$da ) = split(/-/, $blockdate{$blk}{'start'} );
	if ( $mo < 7 ) {
	    $legend{$blk} = "$lex{Spring} $yr";
	} else {
	    $legend{$blk} = "$lex{Fall} $yr";
	}
	push @legend, $legend{$blk};
    }
    # currently only using @legend below


    my $graph = GD::Graph::bars->new(800,400);
    $graph->set( dclrs => [ qw{blue green red dblue dgreen dred} ]);    


    my %studtest; # holds all test data, all students

    # Check for tests within this date range for this student.
    my $sth = $dbh->prepare("select id, readlevel, tdate, dratype from read_test where studnum = ? 
      and to_days( tdate ) >= to_days( '$startdate' ) 
      and to_days( tdate ) <= to_days( '$enddate')");

    my $sth1 = $dbh->prepare("select sum(score) from read_test_score where testid = ?");
    my $max_y;  # maximum y valu on the graph

    foreach my $studnum ( @students ) { # Get all Test data.

	$sth->execute( $studnum );
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	while ( my ($id, $readlevel, $tdate, $dratype ) = $sth->fetchrow ) {

	    my $testjd = julian_day( split('-', $tdate) );

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

	    my $gradeEquiv = scoreToGrade( $score, $readlevel, $dratype );
	    if ( $gradeEquiv > $max_y ) { $max_y = $gradeEquiv; }

	    # Find which date block the test is in...

# Uncomment these to view matching of tests to date blocks.
#	    print qq{Start:$studnum - $tdate<br>\n";
	    my $blockval;
	    foreach my $blk ( sort keys %block ) {
#		print qq{Block:$blk $tdate|| $block{$blk}{'start'} $block{$blk}{'end'}<br>";

		if ( $testjd > $block{$blk}{'start'} and $testjd <= $block{$blk}{'end'} ) {
#		    print qq{<b>Match: $blk -> $tdate</b><br>";
		    $blockval = $blk;
		    last;
		}
	    }

#	    print qq{Final: $studnum $tdate $blockval<br><br>\n";

	    $studtest{$studnum}{$blockval} = $gradeEquiv;
	}
    } # end of Student Loop



    # prep for getting name
    $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");

    # Set Student Names into array.
    my @studnames = ();
    foreach my $studnum ( @students ) {

	# Get Name (shortened)
	$sth->execute( $studnum );
	my ( $lastname, $firstname ) = $sth->fetchrow;
	if ( length( $firstname ) > 6 ) {
	    $firstname = substr($firstname, 0, 6);
	}

	my $finitial = substr( $firstname, 0, 1);
	my $linitial = substr( $lastname, 0, 1);
	my $name = "$firstname$linitial";
	push @studnames, $name;

    }


    # organize test data into rows of values for display;
    my @tempdata;
    foreach my $blk ( 1 .. $maxblock ) {
	foreach my $studnum ( @students ) {
	    push @{ $tempdata[$blk] }, $studtest{$studnum}{$blk};
	}
    }


    my @data = ( \@studnames );

#    print qq{Size:$#tempdata<br>\n};

    my $rows = $#tempdata + 1;
    for my $row ( 1 .. $rows ) {
	my $ref = \@{ $tempdata[$row] };
	push @data, $ref; 

#	foreach my $val ( @{$tempdata[$_]} ) {
#	    print qq{V:$val \n};
#	}
    }


# Test Data
#    my @stud = [ qw(stud1 stud2 stud3) ];
#    my @row1 = [ 1,2,3 ];
#    my @row2 = [ 4,5,6 ];

#  Both of these approaches work fine.
#    my @data = ( @stud, @row1, @row2 );
#    my @data = ( [ qw(stud1 stud2 stud3) ], [1,2,3], [4,5,6] );

=head
    foreach my $ref ( @data ) {
	print qq{Ref: $ref<br>\n};
	foreach my $val ( @$ref ) {
	    print qq{V:",$val,' ';
	}
	print qq{<br>\n};
    }
    print qq{<br>\n};
=cut

    my $max_x = scalar @students + 1;
    $max_y = int $max_y + 1; # make larger, round to whole number

    $graph->set(
	x_label => 'Students',
	y_label => 'DRA Equivalent Grade',
	title  => $title,
	y_max_value => $max_y,
	x_max_value => $max_x,
	legend_placement => 'RT'


	) or die $graph->error;

    # bargroup_spacing => '1'

    $graph->set_legend( @legend );
    my $gd = $graph->plot(\@data) or die $graph->error;

    $filename = "class-$$.png";
    open(IMG,">$filename");
    binmode IMG;
    print IMG $gd->png;
    close IMG;


    system("mv $filename $tchdownloaddir");

    print qq{<div style="float:left;border:1px solid blue;padding:0.4em;};
    print qq{background-color:#DDC;margin:0.2em;">\n};
    print qq{<img src="$tchwebdownloaddir/$filename">\n};
    print qq{</div>\n};

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

    exit;

} # end of showMultiTest
