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

#  This file is part of Open Admin for Schools.

# confperiods_teacher.pl - manage periods for a teacher

my %lex = ('Error' => 'Error',
	   'Continue' => 'Continue',
	   'Main' => 'Main',
	   'Edit' => 'Edit',
	   'Add' => 'Add',
	   'New' => 'New',
	   'Set' => 'Set',
	   'Please Log In' => 'Please Log In',
	   'User Id' => 'User Id',
	   'Password' => 'Password',
	   'Cookie Duration' => 'Cookie Duration',
	   'Not Found' => 'Not Found',
	   'Ending Time' => 'Ending Time',
	   'Length' => 'Length',
	   'Number of' => 'Number of',
	   'Period' => 'Period',
	   'Periods' => 'Periods',
	   'Start' => 'Start',
	   'Starting Time' => 'Starting Time',
	   'Times' => 'Times',
	   'Periods' => 'Periods',
	   'Select' => 'Select',
	   
	   );


my $self = 'confperiods_teacher.pl';

my $defaultEtcPath = '../../etc';

use DBI;
use CGI;
use Data::Dumper;
use Time::JulianDay;
use CGI::Session;


$Data::Dumper::Purity = 1;
$Data::Dumper::Indent = 0;

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

# Set Path to etc directory 
if ( not $g_EtcPath ) {
    $g_EtcPath = $defaultEtcPath;
}


my $q = CGI->new;
print $q->header( -charset, $charset ); 
my %arr = $q->Vars;

my $dbtype = 'mysql';
my $dsn = "DBI:$dbtype:dbname=$dbase";
my $dbh = DBI->connect($dsn,$user,$password);
$dbh->{mysql_enable_utf8} = 1;


# Load Configuration
my $sth = $dbh->prepare("select datavalue from conf_system where dataname = ?");
foreach my $var ( qw( doctype chartype tchcss tchpage g_jquery_url g_jquery_ui_url 
  g_AttendanceEntryMethod g_JqueryUiCss tchpage g_DaysPerCycle g_PeriodTime g_PeriodMap )) {
    $sth->execute( $var );
    my $datavalue = $sth->fetchrow;
    eval $datavalue;
    if ( $@ ) {
	print "$lex{Error}: $@<br>\n";
	die "$lex{Error}: $@\n";
    }
}


my $userid = $ENV{'REMOTE_USER'};


# Page Header
my $title = qq{$lex{Set} $lex{Period} $lex{Times}};
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$tchcss" type="text/css">\n};


if ( $arr{page} == 1 ) { # load jQuery libs for setPeriods

    print qq{<link rel="stylesheet" href="$g_JqueryUiCss">\n};
    print qq{<link rel="stylesheet" href="/js/jquery.ui.timepicker.css" type="text/css">\n};
    print qq{<script type="text/javascript" src="$g_jquery_url"></script>\n};
    print qq{<script type="text/javascript" src="$g_jquery_ui_url"></script>\n};
    print qq{<script type="text/javascript" src="/js/jquery.ui.timepicker.js"></script>\n};

}

    
print qq{$chartype\n</head><body>\n};

print qq{[ <a href="$tchpage">$lex{Main}</a> ]\n};

print qq{<h1>$title</h1>\n};
my $cycletext;
if ( $g_DaysPerCycle == 1 ) {
    $cycletext = "( Every Day is the same. )";
} elsif ( $g_DaysPerCycle == 5 or $g_DaysPerCycle eq 'w' or $g_DaysPerCycle eq 'W' ) {
    $cycletext = "( Weekly Cycle - Each monday the same, each tuesday, etc. )";
}
    
print qq{<h3>Days in a School Cycle - $g_DaysPerCycle };
print qq{<span style="font-size:80%;">$cycletext</span></h3>\n};



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

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

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


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

    # load existing timesets, including this user.  If no userid
    # mapped timeset, then display these to allow teacher to select
    # one as a starting point.

    my %timedata;
    
    # Check for a user timeset.
    my $sth = $dbh->prepare("select timeset from period_map where timetype = 'userid' and timeval = ?");
    $sth->execute( $userid );
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    my $usertimeset = $sth->fetchrow;

    print qq{<p style="width:40ch;">If the School Wide period times
    agree with what you want for numbers of periods and period times
    for your homeroom, no addition of periods is required
    here. Otherwise you can set your own period times for use with
    your daybook.</p>\n};

    
    # Display School wide Period Times.
    my @tmp = keys %g_PeriodTime;
    if ( @tmp ) {
	my %p = %{ $g_PeriodTime{$tmp[0]} }; # only use the first ID for period mapping.
	foreach my $period ( keys %p ) {
	    $ptime{$period}{starttime} = conv24to12( $p{$period}{s} );
	    $ptime{$period}{endtime} = conv24to12( $p{$period}{e} );
	}

	print qq{<table cellpadding="3" cellspacing="0" border="1" style="margin:1em;">\n};
	print qq{<caption style="font-weight:bold;color:red;">};
	print qq{School Wide Period Times</caption>\n};
	print qq{<tr><th>$lex{Period}</th><th>$lex{Times}</th></tr>\n};

	foreach my $period ( sort keys %ptime ) {
	    print qq{<tr><td class="cn">$period</td>};
	    print qq{<td>$ptime{$period}{starttime} - $ptime{$period}{endtime}</td></tr>\n};
	}
	print qq{</table>\n};
    } else {
	print qq{<div>No School Wide Period times have been set!</div>\n};
    }


    # Load Any Values in period_data
    $sth = $dbh->prepare("select * from period_data");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

    while ( my $ref = $sth->fetchrow_hashref ) {
	my %r = %$ref;
	$timedata{ $r{timeset} }{ $r{period} } = { start => $r{starttime}, end => $r{endtime} };
    }

    # Display current values, floated
    foreach my $timeset ( sort keys %timedata ) {
	my %r = %{ $timedata{$timeset}};

	print qq{<table cellpadding="3" cellspacing="0" border="1" style="margin:1em;">\n};
	print qq{<caption style="font-weight:bold;">Time Set $timeset</caption>\n};
	print qq{<tr><th>$lex{Period}</th><th>$lex{Times}</th><th>$lex{Length}</th></tr>\n};

	foreach my $period ( sort keys %{ $timedata{$timeset} } ) {
	    my $stime = conv24to12($r{$period}{start});
	    my $etime = conv24to12($r{$period}{end});
	    
	    my ($shr,$smin) = split(':', $r{$period}{'start'} );
	    $smin = $shr * 60 + $smin;
		
	    my ($ehr,$emin) = split(':', $r{$period}{'end'} );
	    $emin = $ehr * 60 + $emin;

	    my $length = $emin - $smin;
	    
	    print qq{<tr><td class="cn">$period</td><td class="la">};
	    print qq{$stime - $etime</td><td class="cn">$length</td></tr>\n};
	}
	
	# Edit this Time Set
	print qq{<tr><td colspan="3" class="cn">};
	print qq{<form action="$self" method="post">\n};
	print qq{<input type="hidden" name="page" value="1">\n};
	print qq{<input type="hidden" name="id" value="$timeset">\n};
	print qq{<input type="submit" value="$lex{Edit}/$lex{Select} $lex{Periods}"></form>\n};
	print qq{</td></tr>\n};
	print qq{</table>\n};

	
    } # end of display current timeset for editing


    # Display Any Values in period_map
    # Get Staff Name
    my $sth1 = $dbh->prepare("select lastname, firstname from staff where userid = ?");
    
    my $first = 1;
    $sth = $dbh->prepare("select timeset, timeval from period_map order by timeset, timeval");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    while ( my ($set,$uid) = $sth->fetchrow ) {

	# Get Staff Name
	$sth1->execute($uid);
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth1->fetchrow;
	
	if ( $first ) {
	    print qq{<table cellpadding="3" cellspacing="0" border="1" style="margin:1em;">\n};
	    print qq{<tr><th>Timeset</th><th>User Id</th></tr>\n};
	    $first = 0;
	}
	print qq{<tr><td class="cn">$set</td><td>$firstname $lastname ($uid)</td></tr>\n};
    }
    if ( not $first ) {
	print qq{</table>\n\n};
    }
    
    
    # Add new Time Set
    print qq{<form action="$self" method="post" style="margin:1em;">\n};
    print qq{<input type="hidden" name="page" value="1">\n};
    print qq{<table style="float:left;border:1px solid black;padding:0.4em;">\n};
    print qq{<tr><td>\n};
    print qq{<input type="submit" value="$lex{Add} $lex{New} $lex{Periods}">\n};
    print qq{$lex{'Number of'} $lex{Periods}\n};
    print qq{<select name="periods"><option></option>\n};
    foreach my $per (1..10) {
	print qq{<option>$per</option>};
    }
    print qq{\n</select></td></tr></table></form>\n};
    

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

    exit;

} # end of showStartPage



#------------
sub setPeriods {
#------------

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


    my $periods;  # passed in %arr if no records yet.
    my $timeset = $arr{id};
    my %timedata;
    
    if ( $timeset ) {

	# Load Periods
	my $sth = $dbh->prepare("select * from period_data where timeset = ?");
	$sth->execute( $timeset );
	

	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	while ( my $ref = $sth->fetchrow_hashref ) {
	    my %r = %$ref;
	    $timedata{ $r{period} } = { start => $r{starttime}, end => $r{endtime}, id => $r{id} };
	}

	$periods = (keys %timedata );
    } else {
	$periods = $arr{periods};
    }

    
#    foreach my $period ( sort keys %timedata ) {
#	print "Per:$period S:$timedata{$period}{start} E:$timedata{$period}{end} ID:$timedata{$period}{id}<br>\n";
#    }

    # Convert to 12 hour clock.
    foreach my $period ( sort keys %timedata ) {
	$timedata{$period}{start} = conv24to12( $timedata{$period}{start} );
	$timedata{$period}{end} = conv24to12( $timedata{$period}{end} );
    }

    # Check Periods value
    if ( not $periods or ( $periods < 0 or $periods > 10 )) {
	print qq{<h3>$lex{Error} - $lex{Periods}:$periods</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    
    # Form / Table Start
    print qq{<form action="$self" method="post">\n};
    print qq{<input type="hidden" name="page" value="2">\n};
    print qq{<input type="hidden" name="timeset" value="$timeset">\n};

    
    print qq{<table cellpadding="3" cellspacing="0" border="0">\n};
    print qq{<tr><th>$lex{Period}</th><th>$lex{'Starting Time'}</th>};
    print qq{<th>$lex{'Ending Time'}</th></tr>\n}; 

    my $periodsPlus = $periods + 2;

    
    foreach my $period ( 1..$periodsPlus ) {

	if ( $period > $periods ) {
	    print qq{<tr><td class="bcn">Extra $lex{Periods} $period</td>\n};
	} else {
	    print qq{<tr><td class="bcn">$lex{Period} $period</td>\n};
	}

	
	print qq{<td class="la"><input type="text" size="8" };
	print qq{id="S$period" name="s:$period:$timedata{$period}{id}" };
	print qq{value="$timedata{$period}{'start'}">\n};
	print qq{<script type="text/javascript">
	    \$(document).ready(function() {
		\$('#S$period').timepicker({showPeriod:true, onHourShow:OnHourShowCallback});
	    });
	    function OnHourShowCallback(hour) {
               if ((hour > 17 ) || (hour < 7 )) {
                   return false;
               }
               return true;
	    }
        </script></td>\n};

	
    	print qq{<td class="la"><input type="text" size="8" id="E$period" name="e:$period" };
	print qq{value="$timedata{$period}{'end'}">\n};
	print qq{<script type="text/javascript">
	    \$(document).ready(function() {
		\$('#E$period').timepicker({showPeriod:true, onHourShow:OnHourShowCallback});
	    });
	    function OnHourShowCallback(hour) {
               if ((hour > 17 ) || (hour < 7 )) {
                   return false;
               }
               return true;
	    }
        </script></td>\n};
	print qq{</tr>\n};

    }

    
    print qq{<tr><td colspan="2" class="ra"><input type="submit" value="$lex{Continue}"></td></tr>\n};
    print qq{</table></form>\n};

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

}


#---------------
sub writeRecords {
#---------------

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

    my $timeset = $arr{timeset};
    delete $arr{timeset};


    my (%periods,%check, %recid);  # $recid{period} = id of record in db.
    foreach my $key ( keys %arr ) {

	my $time = conv12to24( $arr{$key} );
	my ($type, $per, $id) = split(':', $key);  # type is start 's' or end 'e'.
	if ( $id ) { # store the record holding this info for this period.
	    $recid{$per} = $id;
	}
	
	$periods{$per}{$type} = $time;
	
	my ($h,$m) = split(':', $time);
	my $minutes = $h * 60 + $m;
	if ( not $minutes ) { next; } # not checking blanks.
	my $idx = $per;
	if ( $type eq 'e' ) { # add on .5
	    $idx += 0.5;
	}
	$check{$idx} = $minutes; # these will be total minutes from start of the day.
    }

    
=head    
    # Display values for periods
    foreach my $period ( sort keys %periods ) {
	foreach my $type ( sort keys %{ $periods{$period} } ) {
	    print qq{Period:$period Type:$type Val:$periods{$period}{$type}<br>\n};
	}
    }
=cut

    
    # Check values for length, sequence, and overlap.

    my ($curr, $prev);
    foreach my $key ( sort keys %check ) {
	$prev = $curr;
	$curr = $key;
	if ( $prev ) { # not at first;
	    if ( $check{$curr} < $check{$prev}  ) { # error;
		my ($currerr, $preverr );
		$currerr = "Start";
		if ( $curr =~ m/\./ ) { # is it a decimal value, if so, an end time
		    $currerr = "End";
		    $curr =~ s/\..+//g;
		}
		$currerr = "Period $curr ". $currerr;

		$preverr = "Start";
		if ( $prev =~ m/\./ ) { # is it a decimal value, if so, an end time
		    $preverr = "End";
		    $prev =~ s/\..+//g;
		}
		$preverr = "Period $prev ". $preverr;

		print qq{<h3>$lex{Error}: $currerr < $preverr</h3>\n};
		print qq{</body></html>\n};
		exit;
	    }
	}
	
#	print "K:$key V:$check{$key}<br>\n";
    }

   
    # Now get period lengths.
    my %lengths; # of periods in minutes.
    print qq{<table cellpadding="3" cellspacing="0" border="1">};
    print qq{<tr><th>$lex{Period}</th><th>$lex{Times}</th><th>$lex{Length}</th></tr>\n};

    foreach my $period ( sort keys %periods ) {
	my ($shr,$smin) = split(':', $periods{$period}{'s'} );
	$smin = $shr * 60 + $smin;

	my ($ehr,$emin) = split(':', $periods{$period}{'e'} );
	$emin = $ehr * 60 + $emin;

	my $length = $emin - $smin;
	$lengths{$period} = $length;

	if ( not $length ) { next; }
	
	print qq{<tr><td>$period</td><td>$periods{$period}{s} - $periods{$period}{e}</td>};
	print qq{<td>$length</td></tr>\n};
    }
    
    print qq{</table>\n};
        
    my $newtimeset;
    if ( not $timeset ) { # pick the next available number from the period_data table.
	my $sth = $dbh->prepare("select max(timeset) from period_data");
	$newtimeset = $sth->execute;
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	$newtimeset++;
    }

    # print qq{NEW Timeset:$newtimeset<br>\n};


     
=head    
    if ( $newtimeset ) {
	print qq{<div>New $lex{Period} $lex{Set} ID:$newtimeset</div>\n};
    } else {
	print qq{<div>$lex{Period} $lex{Set} ID:$timeset</div>\n};
    }
=cut

    # Insert
    my $sth = $dbh->prepare("insert into period_data (timeset, period, starttime, endtime) 
     values(?,?,?,?) ");

    # Update
    my $sth1 = $dbh->prepare("update period_data set starttime = ?, endtime = ? where id = ?");

    # Delete
    my $sth2 = $dbh->prepare("delete from period_data where id = ?");
    
    
    foreach my $period ( sort keys %periods ) {
	my $recid = $recid{$period};
	if ( $recid ) { # we have an existing record. Update or Delete?
	    # Do we have values for time?
	    if ( $periods{$period}{s} and $periods{$period}{e} ) { 
		# both a start and end, update the record
		$sth1->execute( $periods{$period}{'s'}, $periods{$period}{'e'}, $recid );
		if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		print qq{<div>Period $period Updated</div>\n};
		
	    } elsif ( not $periods{$period}{s} and not $periods{$period}{e} ) { 
		# no times found, delete the rec
		$sth2->execute( $recid );
		if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		print qq{<div>Period $period Deleted</div>\n};
		
	    } else { # an error in start/end times
		print qq{<div style="color:red;font-weight:bold;">};
		print qq{$lex{Error} in Period $period times. No Change</div>\n};
	    }
	    
	} else { # no record id.... add a record, if we have values.
	    if ( $periods{$period}{s} and $periods{$period}{e} ) { # both a start and end time
		my $ts = $timeset;
		if ( not $timeset ) { $ts = $newtimeset; }
		
		$sth->execute( $ts, $period, $periods{$period}{'s'}, $periods{$period}{'e'} );
		if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
		print qq{<div>New Period Added: $period</div>\n};
	    }
	}
    } # end of periods loop

    # insert userid into map table if newtimeset
    if ( $newtimeset ) {
	my $sth = $dbh->prepare("insert into period_map (timeset, timetype, timeval) 
             values($newtimeset,'userid',?) ");
	$sth->execute($userid);
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
	print qq{<div>Userid Record Added for $userid</div>\n};
	
    } else { # update the period_map value to this
	my $sth = $dbh->prepare("update period_map set timeset = ? where timeval = ?");
	$sth->execute($timeset, $userid);
	if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    }
    
    print qq{<p>[ <a href="$self">$lex{Edit} $lex{Periods}</a> ]</p>\n};

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

    exit;
}



#-------------
sub conv12to24 {
#-------------

    my $time = shift;
    if ( not $time ) { return }

    $time =~ s/(AM|PM|am|pm)//; # strip am/pm.
    $ampm = $1; 
    $ampm = uc $ampm; # uppercase value
    
    my ($hr, $min) = split(':', $time);
    if ( $ampm eq 'PM' and $hr < 12 ) {
	$hr += 12;
    } elsif ( not $ampm and $hr < 7 ) { # manually typed.
	$hr += 12;
    }

    if ( $hr > 24 or $hr < 0  or  $min < 0 or $min > 60 ) {
	print qq{<h3>$lex{Error}: $time</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    return qq{$hr:$min};

}



#-------------
sub conv24to12 {
#-------------

    my $time = shift;
    if ( not $time ) { return }
    my ($hr, $min) = split(':', $time);
    my $ampm = 'AM';
    if ( $hr == 12 ) { $ampm = 'PM'; }
    if ( $hr == 0 ) { $hr = 12; };

    if ( $hr > 12 ) { 
	$hr -= 12;
	$ampm = 'PM';
    }

    return qq{$hr:$min $ampm};

}
