#!/usr/bin/perl
#  Copyright 2001-2020 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 = ('User Id' => 'User Id',
	   'Password' => 'Password',
	   'Duration' => 'Duration',
	   'Login' => 'Login',
	   'Log In' => 'Log In',
	   'Log Out' => 'Log Out',
	   'min' => 'min',
	   'No Userid Found' => 'No Userid Found',
	   'Incorrect Password' => 'Incorrect Password',
	   'Logged In' => 'Logged In',
	   'Error' => 'Error',
	   'Continue' => 'Continue',
	   'User' => 'User',
	   'Teacher Administration' => 'Teacher Administration',
	   'Announcements' => 'Announcements',
	   'Hover=Full View' => 'Hover on Title to see Full Text',
	   'View All' => 'View All',
	   'Logged Out' => 'Logged Out',
	   'Main' => 'Main',
	   'No Announcements' => 'No Announcements',

	   );

my $self = 'tindex.pl';

my $defaultpage = 'teacher.html';
my $defaultpath = './';

my $textlength = 100;

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

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

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

my $title = qq{$lex{'Teacher Administration'} - Open Admin $g_OpenadminVersion};

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

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

# print $session->header( -charset, $charset );
# foreach my $key ( sort keys %ENV ) { print "K:$key V:$ENV{$key}<br>\n"; }

my $userid = $session->param('userid');
my $logged_in = $session->param('logged_in');

#print $q->header;
#print "Userid:$userid<br>\n";
#print "Logged In:$logged_in<br>\n";

if ( $arr{page} == 4 ) { 
    doLogout(); # it will halt here.
}

if ( $arr{page} == 3 ) { # display login form due to error
    print $q->header( -charset, $charset );
    showLoginForm();  # this sets page=1;
}

if ( ( $logged_in and $userid ) or  # no issues, display page.
     ( not $logged_in and not $userid ) or # for initial login (they got in...)
     ( $arr{page} == 1 ) # they have entered login values; check credentials inside.
    ) {

    displayPage(); # also had $arr{file} value;

} else  { # enter password and duration, session timed out.
    print $q->header( -charset, $charset );
    showLoginForm(); # the login form.
}


#--------------
sub displayPage {
#--------------

    my $file = shift; 

    if ( not $logged_in and $arr{page} == 1 ) { # use values passed in form from page 1
	
	# Check password/userid against database (-1 no user, -2 wrong password );
	my $error = checkPassword( $arr{userid}, $arr{password} );

	if ($error == -1){
	    print $session->header( -charset, $charset );
	    print qq{<html><body><h3>$lex{'No Userid Found'}</h3>\n};
	    print qq{</body></html>\n};
	    exit;
	}
	if ($error == -2){ 
	    print $session->header( -charset, $charset );
	    print qq{<html><body><h3>$lex{'Incorrect Password'}</h3>\n};
	    print qq{</body></html>\n};
	    exit;
	}

    }

    my $updateflag;
    if ( not $userid) {
	$userid = $ENV{'REMOTE_USER'};
	$updateflag = 1;

	# Check if correct case.
	my $sth = $dbh->prepare("select userid from staff where userid = ?");
	$sth->execute($userid);
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $testid = $sth->fetchrow;

	if ( $testid ne $userid ) { # we have a case mismatch
	    print $session->header( -charset, $charset );
	    print qq{<html><body style="color:red;">};
	    print qq{<h1>$lex{Error}: $userid does not match correct userid $testid</h1>\n};

	    print qq{<h3>[<a href="tcgi-bin/tlogin.pl">Log In</a> ]</h3>\n};
	    print qq{</body></html>\n};
	    exit;
	}

    } elsif ( $arr{userid} and $userid ne $arr{userid} ) {
	# logging in as new user with diff userid; update session.
	$userid = $arr{userid};
	$updateflag = 1;
    }

    if ( not $duration ) {
	my $dur;
	if ( $arr{duration} ) { $dur = $arr{duration}; } else { $dur = $g_SessionDuration; }
	$duration = checkCookieTime( $dur );
	$updateflag = 1;
    }

    if ( $updateflag ) {
	$session->param('userid', $userid);
	$session->param('duration', $duration);
    }

    $session->param('logged_in', '1');
    $session->expire('logged_in', $duration );
    $session->flush();
    print $session->header( -charset, $charset );

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

    if ( not $file ) { 

	print qq{<!DOCTYPE html>\n};
	print qq{<html><head><title>$title</title>\n};
	print qq{<meta charset="utf-8">\n};
	print qq{<link rel="stylesheet" type="text/css" href="tadmin.css">\n};

	print qq{</head><body style="padding:0;margin:0;">\n};

	print qq{<!--\n};
	print qq{Copyright 2001-2020 Leslie Richardson\n\n};

	print qq{This file is part of Open Admin for Schools.\n};

	print qq{Open Admin for Schools is free software; you can redistribute it \n};
	print qq{and/or modify it under the terms of the GNU General Public License\n};
	print qq{as published by the Free Software Foundation; either version 2 of \n};
	print qq{the License, or (at your option) any later version.\n};
	print qq{-->\n};

	print qq{<div style="position:absolute;top:0.2em;right:0.2em;font-weight:bold;">\n};

	# Log In
	print qq{<form action="$self" method="post" style="display:inline;">\n};
	print qq{<input type="hidden" name="page" value="3">\n};
	print qq{<input type="submit" value="$lex{'Log In'}"></form>\n};

	# Log Out
	print qq{<form action="$self" method="post" style="display:inline;">\n};
	print qq{<input type="hidden" name="page" value="4">\n};
	print qq{<input type="submit" value="$lex{'Log Out'}"></form>\n};

	print qq{<span style="border:1px solid gray;padding:0.3em;">$userid  $duration</span></div>\n};


	print qq{<h1 style="padding-top:0.4em;margin:0;text-align:center;">};
	print qq{$lex{'Teacher Administration'}\n};
	print qq{<span style="font-size:70%; font-style:italic;padding:0;margin:0;">};
	print qq{Open Admin $g_OpenadminVersion</span></h1>\n\n};

	print qq{<div style="float:left;width:70%;padding:0;margin:0;">\n};

	$file = $defaultpage; 

    } # end main page header

    my $path = "$defaultpath/$file";

    open(FH,'<', $path) || die "Cannot open:\n";

    my $htmlfile;
    { local $/; $htmlfile = <FH>; close FH; }
    print $htmlfile;

    print qq{</div><div style="float:left;width:29%;font-size:80%;">\n};
    viewAnnouncements();
    print qq{</div>\n};

    exit;

} # end of displayPage()



#--------------------
sub viewAnnouncements {
#--------------------

    print qq{<h2>$lex{Announcements}</h2>\n};
    print qq{<div style="font-weight:bold;font-style:italic;text-align:center;">};
    print qq{$lex{'Hover=Full View'} | };
    print qq{<form action="/tcgi-bin/announce/announceview.pl" method="post" };
    print qq{target="_blank" style="display:inline;">};
    print qq{<input type="submit" value="$lex{'View All'}"></form>\n};
    print qq{</div><hr>\n};


    # Load Top Announcements
    my $acount = 1; # announcement counter;
    my $topselect = "where topstay = 1";
    my $sth = $dbh->prepare("select * from announce $topselect order by adate desc");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }
    my %topstay = ();
    my $first = 1;

    while ( my $ref = $sth->fetchrow_hashref ) {
	$ref->{atopic} = qq{<span style="color:red;">*</span>}. $ref->{atopic}; # mark top
	my $id = $ref->{id};
	$topstay{$id} = 1; # holds records already displayed.
	prAnnounce( $ref );
	$first = 0;
	$acount++;
    }

    # Rest of Page Announcements
    if ( $select ) { $select = 'where '. $select; } # put in 'where'

    $sth = $dbh->prepare("select * from announce $select order by adate desc");
    $sth->execute;
    if ( $DBI::errstr ) { print $DBI::errstr; die $DBI::errstr; }

    while ( my $ref = $sth->fetchrow_hashref ) {
	if ( $topstay{ $ref->{id} } ) { next; } # skip if already displayed on top.
	prAnnounce( $ref );
	$first = 0;
	$acount++;
	if ( $acount > 10) { last; }
	    
    }

    if ( $first ) {
	print "<h3>$lex{'No Announcements'}</h3>\n";
    }

    return;

} # end of viewAnnouncements


#-------------
sub prAnnounce {
#-------------

    my $ref = shift;
    my $date = fmtdate( $ref->{adate} );
    my $text = substr( $ref->{adesc}, 0, $textlength );
    $text =~ m/(^.+\b)/;
    $text = $1;
    my $titleattr = $q->escapeHTML( $ref->{adesc} );

    print qq{<div class="annce" title="$titleattr">};
    print qq{<b>$ref->{atopic}</b><br><i>$date</i></div>\n};
    print qq{<div>$text ...</div><hr>\n\n};
}



#----------------
sub showLoginForm {
#----------------

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

    # Print Page Heading
    print qq{$doctype\n};
    print qq{<html><head><title>$title</title>\n};
    print qq{<link rel="stylesheet" href="$tchcss" type="text/css">\n};
    print qq{$chartype\n};
    print qq{</head><body onload="document.forms[0].elements[1].focus()">\n};

    print qq{<h3>$lex{User} $lex{'Log In'}</h3>\n};

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


    print qq{<table cellpadding="6" cellspacing="0" border="1">\n};
    print qq{<tr><th colspan="2"></th></tr>\n};

    print qq{<tr><td class="bra">$lex{'User Id'}</td>\n};
    print qq{<td class="la"><input type="text" name="userid" value="$userid_env"></td></tr>\n};

    print qq{<tr><td class="bra">$lex{Password}</td>\n};
    print qq{<td class="la"><input type="password" name="password" size="20"></td></tr>\n};

    print qq{<tr><td class="bra">$lex{Duration}</td>\n};
    print qq{<td class="la"><input type="text" name="duration" size="5" value="$g_SessionDuration"> };
    print qq{$lex{min}</td></tr>\n};

    print qq{<tr><td class="cn" colspan="2">\n};
    print qq{<input type="submit" value="$lex{Login}"></td></tr>\n};

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

    exit;

}



#----------------
sub checkPassword {
#----------------

    my ($userid, $password) = @_;
    
    if (not $userid){ return -1;}
    if (not $password){ return -2;}

    # Sanitize 
    unless ( $password =~ m#^([\w\d.-@_+]+)$# ) {
      return -2;
    }
    $password = $1;

    #check for presence of userid
    my $sth = $dbh->prepare("select count(userid) from staff 
     where userid = ?");
    $sth->execute($userid);
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $count = $sth->fetchrow;
    # Now check for a match in case.
    if ( $count ) {
	my $sth = $dbh->prepare("select userid from staff where userid = ?");
	$sth->execute($userid);
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $testid = $sth->fetchrow;
	if ( $testid ne $userid ) { # we have a case mis match
	    return -1; # no userid;
	}
    }
    if ($count < 1){ return -1;} # no userid

    #check for presence of correct password and userid
    my $sth = $dbh->prepare("select count(userid) from staff 
     where userid = ? and password = ?");
    $sth->execute($userid, $password);
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $count = $sth->fetchrow;
    if ($count < 1){ return -2;} # not correct password

    return 0; # if all ok...

}


#------------------
sub checkCookieTime {
#------------------

    # defaults
    $minimumtime = 3; # minutes
    $maximumtime = 90;

    my ($duration) = @_;

    if ($duration) { 
	$cookietime = $duration;
    } else { 
	$cookietime = $g_SessionDuration;
    }

    $cookietime = $minimumtime if $cookietime < $minimumtime; 
    $cookietime = $maximumtime if $cookietime > $maximumtime; 
    $cookietime = "+".$cookietime."m"; # set format
    
    return $cookietime;

}

#----------
sub fmtdate {
#----------

    my $date = shift;
    my ($yr, $mo, $da) = split(/-/, $date);

    my $month = $month[$mo];

    my $jd = julian_day( split(/-/,$date) );
    my $dayindex = day_of_week( $jd )+ 1;
    my $day = $dow[$dayindex];

    my $rv = "$day, $month $da, $yr";

    return $rv;

}


#-----------
sub doLogout {
#-----------

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

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

#    $session->expire('logged_in', '1'); #alternate way to have logout done. Both work.
    $session->param('logged_in', '0');

    $session->flush;

    print $q->header( -charset, $charset );

    print qq{<!DOCTYPE html>\n};
    print qq{<html><head><title>$title</title>\n};
    print qq{<meta charset="utf-8">\n};
    print qq{<link rel="stylesheet" type="text/css" href="tadmin.css">\n};
    print qq{</head><body>\n};

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

    print qq{<h3>$lex{User} <b>$userid</b> $lex{'Logged Out'}</h3>\n};

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

    exit;

}
