#!/usr/local/bin/perl
# qademo.cgi: cgi interface to Dutch QA system
# usage: echo question | qademo.cgi
# 20041112 erikt@science.uva.nl

use IPC::Open2;

$answered = 0;
$baseurl = "http://staff.science.uva.nl/~erikt/demol";
$command = $0;
$correct = 0;
# $date = `export TZ=UTC+03; /usr/bin/date '+\%Y\%m\%d:\%H:\%M'`;
open(INFILE,"/usr/bin/date -u '+\%Y\%m\%d:\%H:\%M' |");
$date = <INFILE>;
close(INFILE);
chomp($date);
$logFile = "/home/erikt/misc/www/logs/demol.quiz";
$maxQuestions = 20;
$name = "";
$prevANbr = 0;
$prevQNbr = 0;
$questionFile = "/home/erikt/misc/www/logs/demol.questions";
$startTime = 0;
$url = "$baseurl/quiz.cgi";
@history = ();
@questions = ();
%used = ();
%usedClass = ();

# aliases for players that use more than one name
%alias = ();
$alias{"esther"} = "molletjem";
$alias{"essie"} = "molletjem";
$alias{"esthur"} = "molletjem";
$alias{"esth\%c3\%bbr"} = "molletjem";
$alias{"it's+me+mm"} = "marc-marie";
$alias{"ruud"} = "its+me+marc-marie";
$alias{"ruud+koelewijn"} = "its+me+marc-marie";
$alias{"ruud+katwijk"} = "its+me+marc-marie";
$alias{"ruud+de+beste+mol+kenner"} = "its+me+marc-marie";
# do not use spaces: uses plusses

srand(time ^ ($$ + ($$ << 15)));
print "Content-type: text/html\n\n";

&readQuestions();

$queryString = defined $ENV{"QUERY_STRING"} ? $ENV{"QUERY_STRING"} : "";
if ($queryString =~ /^NAME=(.*)$/) { 
   $name = $1; 
} else {
#   ($prevQNbr,$prevANbr,$answered,$correct) =
#      &processQueryString($ENV{"QUERY_STRING"});
   ($name,$startTime,$answered,$correct,$prevQNbr,$prevANbr,@history) =
      &readQueryString($queryString);
}
# process stdin, just in case there is something here
while (<STDIN>) {
   $line = $_;
   chomp($line);
   if ($line =~ /^NAME=(.*)$/) { 
      $name = $1; 
   }
}
# process previous answer if any
if ($answered > 0 and defined $questions[$prevQNbr]) {
   push(@history,$prevQNbr);
   @fields = split(/\#/,$questions[$prevQNbr]);
   if (defined $fields[$prevANbr+2] and $fields[$prevANbr+2] =~ /^!/) {
      $correct++;
   }
}
# mark questions that have already been used
foreach $i (@history) { 
   if (defined $questions[$i] and $questions[$i] =~ /^([^\#]+)\#/) {
      $usedClass{$1} = 1;
      $used{$i} = 1; 
   }
}

# html page: start
print <<THEEND;
<html>
<head>
<title>Wie is de Mol 2005 Quiz</title>
</head>
THEEND

$answered++;
if ($answered == 1) { $startTime = time(); }

if ($answered > $maxQuestions) { 
   $time = time-$startTime;
   $mins = int($time/60);
   $secs = $time - $mins*60;
   if (open(LOGFILE,">>$logFile")) {
      print LOGFILE "$date $name $correct $time $ENV{REMOTE_ADDR} $startTime\n";
      close(LOGFILE);
   }
   $line = "Je hebt $correct ";
   $line .= ($answered == 1) ? "vraag" : "vragen";
   $line .= " goed beantwoord in ";
   if ($secs == 0) { $line .= "precies "; }
   if ($mins > 1) { $line .= "$mins minuten"; }
   elsif ($mins == 1) { $line .= "$mins minuut"; }
   if ($mins > 0 and $secs > 0) { $line .= " en"; }
   if ($secs > 1) { $line .= " $secs seconden."; }
   elsif ($secs == 1) { $line .= " $secs seconde."; }
   if ($correct >= 0.8*$maxQuestions) { print "<body bgcolor=\"green\">\n"; $line .= " Proficiat!"; }
   else { print "<body bgcolor=\"red\">\n"; }
   print <<THEEND;
<br><br><br>
<p>
<div align="center">
<form action="$url">
<font face="Comic Sans MS" size="6" color="yellow">$line</font>
<br><br<br>
<p>
<font face="Comic Sans MS" size="6" color="yellow"><a href="$url?NAME=$name">Nog eens</a></font>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<font face="Comic Sans MS" size="6" color="yellow"><a href="$url">Andere naam</a></font>
THEEND
   &showTopTen();
   `/home/erikt/bin/molquiz`;
} else {
   print <<THEEND;
<body bgcolor="black">
<p>
<div align="center">
<form action="$url">
THEEND
   if ($name eq "") { 
      print <<THEEND;
<br><br><br><br><br>
<p>
<font face="Comic Sans MS" size="6" color="red">Naam:</font> 
&nbsp;&nbsp;&nbsp; 
<input name="NAME" size="20" style="font-size: x-large; color: red">
THEEND
      &showTopTen(); } 
   else {
      # always finish with main question
      if ($answered == $maxQuestions) { $qNbr = $#questions; }
      else {
         # choose question
         $qNbr = -1;
         $class = "";
         while ($qNbr < 0 or defined $used{$qNbr} or defined $usedClass{$class}) {
            $qNbr = int(rand($#questions));
            $questions[$qNbr] =~ /^([^\#]+)\#/;
            $class = $1;
         }
      }
      &printQuestion($qNbr); 
   }
}

# html page: end
print <<THEEND;
</form>
</div>
</body>
</html>
THEEND

exit(0);

sub readQuestions {
   my ($line);

   open(INFILE,$questionFile) or die "cannot open $questionFile\n";
   while (<INFILE>) {
      $line = $_;
      chomp($line);
      if ($line !~ /^\s*$/) { push(@questions,$line); }
   }
   close(INFILE);
}

sub printQuestion {
   my ($i,$line,$qNbr,$queryString,$question,
       @fields);

   $qNbr = shift(@_);
   @fields = split(/\#/,$questions[$qNbr]);
   shift(@fields);
   $question = shift(@fields);
   print <<THEEND;
<table width="800" border="0" cellpadding="0" cellspacing="20">
<tr>
<td align="left" valign="middle">
<img src="images/mol.gif" alt="" align="center" height="159" width="100">
<td align="left" valign="middle">
<font face="Comic Sans MS" color="red" size="6">
<ol start="$answered">
<li> $question
</ol>
</font>
<tr>
<td> &nbsp;
<td>
<p>
<table>
THEEND
   if ($#fields > 5) { $half = int(($#fields+2)/2); }
   else { $half = $#fields+1; }
   for ($i=0;$i<$half;$i++) {
      $answer = $fields[$i];
      $answer =~ s/^!//;
      $aNbr = $i;
      $queryString = &makeQueryString($aNbr);
      print "<tr> <td> <a href=\"$url?$queryString\"><img src=\"images/block.gif\" alt=\"[]\" align=\"center\" border=\"0\" height=\"25\" width=\"25\"></a> &nbsp;&nbsp; <font face=\"Comic Sans MS\" color=\"yellow\" size=\"6\">$answer \&nbsp;\&nbsp\&nbsp;</font>\n";
      if ($#fields > 5 and $i+$half <= $#fields) {
         $answer = $fields[$i+$half];
         $answer =~ s/^!//;
         $aNbr = $i+$half;         
         $queryString = &makeQueryString($aNbr);
         print "     <td> <a href=\"$url?$queryString\"><img src=\"images/block.gif\" alt=\"[]\" align=\"center\" border=\"0\" height=\"25\" width=\"25\"></a> &nbsp;&nbsp; <font face=\"Comic Sans MS\" color=\"yellow\" size=\"6\">$answer \&nbsp;\&nbsp;\&nbsp;</font>\n";
      }
   }
   print "</table>\n</table>\n";
}

sub processQueryString {
   my ($answered,$correct,$prevANbr,$prevQuestion,$queryString);

   $queryString = shift(@_);
   if ($queryString == 0) { return(0,0,0,0); }
   $prevQuestion = int($queryString/10000);
   $prevANbr = int(($queryString-10000*$prevQuestion)/1000);
   $answered = int(($queryString-10000*$prevQuestion-1000*$prevANbr)/10);
   $correct = $queryString-10000*$prevQuestion-1000*$prevANbr-10*$answered;
   return($prevQuestion,$prevANbr,$answered,$correct);
}

sub readQueryString {
   my ($i,$line,$queryString);

   $queryString = shift(@_);
   if ($queryString eq "") { return("",0,0,0,0); }
   $queryString =~ s/^.//; # remove extra initial char
   $queryString =~ s/%0[aA]/\#/g;
   @fields = split(/\#/,$queryString);
   open2(INFILE,OUTFILE,"/home/erikt/bin/uudecode -o -") or 
      die "$command: cannot process input string\n";
   print OUTFILE "begin-base64 644 xxx\n";
   for ($i=0;$i<=$#fields;$i++) { print OUTFILE "$fields[$i]\n"; }
   print OUTFILE "====\n";
   close(OUTFILE);
   $line = <INFILE>;
   chomp($line);
   @fields = split(/\s/,$line);
   return(@fields);
}

sub makeQueryString {
   my ($aNbr,$c,$i,$line,$queryString);

   $aNbr = shift(@_);
   open2(INFILE,OUTFILE,"/home/erikt/bin/uuencode -m xxx") or 
      die "$command: cannot create output string\n";
   print OUTFILE "$name $startTime $answered $correct $qNbr $aNbr";
   # previous questions
   for ($i=0;$i<=$#history;$i++) { print OUTFILE " $history[$i]"; }
   close(OUTFILE);
   $i = 0;
   $queryString = "";
   while (<INFILE>) {
      $line = $_;
      chomp($line);
      $i++;
      if ($i == 1) { next; }
      elsif ($line ne "====") {
         $queryString .= $queryString ? "\n$line" : $line;
      }
   }
   $c = chr(65+rand(26));
   return("$c$queryString"); # add extra initial char
}

sub showTopTen {
   my ($i,$date,$host,$lastScore,$lastTime,$line,$mins,$name,
       $score,$secs,$time,$today,
       %scores,%times);

   $today = "";
   %scores = ();
   %times = ();
   if (open(INFILE,$logFile)) {
      while (<INFILE>) {
         $line = $_;
         chomp($line);
         ($date,$name,$score,$time,$host) = split(/\s+/,$line);
         $date =~ s/:.*$//;
         $name =~ s/\%21//g;
         $name =~ s/\%5C//g;
         $name =~ s/\%27/\'/g;
         $name =~ s/\+*\%2[89].*$//g;
         $name =~ tr/A-Z/a-z/;
         $name =~ s/[\.]*$//;
         if (defined $alias{$name}) { $name = $alias{$name}; }
         if ($host eq "80.61.190.138") { $name = "its+me+marc-marie"; }
         if (not defined $time) { next; }
         if ($date ne $today) { %scores = (); %times = (); $today = $date; }
         if ($name =~ /^erik.tks$/i and $score > 16) { $score = 16; }
         if (not defined $scores{$name} or
             $score > $scores{$name} or
             ($score == $scores{$name} and $time < $times{$name})) {
            $scores{$name} = $score;
            $times{$name} = $time;
         }
      }
      close(INFILE);
      $i = 1;
      print "<br><br><br>\n<p>\n<font face=\"Comic Sans MS\" color=\"white\" size=\"4\">Beste scores van de dag</font>\n";
      print "<p>\n<table cellspacing=\"10\">\n";
      $lastScore = 0;
      $lastTime = 0;
      foreach $name (sort { mysort() } keys %scores) {
         $line = $name;
         $line =~ s/\+/ /g;
         $mins = int($times{$name}/60);
         $secs = $times{$name} - $mins*60;
         if ($secs < 10) { $secs = "0$secs"; }
         print "<tr><td align=\"right\"> ";
         print "<font face=\"Comic Sans MS\" color=\"white\" size=\"4\">\n";
         if ($lastScore != $scores{$name} or $lastTime != $times{$name}) {
            print "$i.";
         } else { print "&nbsp;"; }
         print "</font>\n<td>";
         print "<font face=\"Comic Sans MS\" color=\"white\" size=\"4\">\n";
         print "$line</font>\n<td align=\"right\">";
         print "<font face=\"Comic Sans MS\" color=\"white\" size=\"4\">\n";
         print "$scores{$name}</font>\n<td align=\"right\">";
         print "<font face=\"Comic Sans MS\" color=\"white\" size=\"4\">\n";
         print "$mins:$secs</font>\n";
         $lastScore = $scores{$name};
         $lastTime = $times{$name};
         $i++;
         if ($i > 10) { last; }
      }
      print <<THEEND;
</table>
<p>
<font face="Comic Sans MS" size="4" color="yellow"><a href="$baseurl/quizG.html">Gisteren</a></font>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<font face="Comic Sans MS" size="4" color="yellow"><a href="$baseurl/quizA.html">Aller tijden</a></font>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<font face="Comic Sans MS" size="4" color="yellow"><a href="$baseurl/">Home</a></font>
THEEND
   }

   sub mysort {
      if ($scores{$b} <=> $scores{$a}) { return($scores{$b} <=> $scores{$a}); }
      else { return($times{$a} <=> $times{$b}); }
   }
}
