#!/usr/bin/perl -T

use CGI ':standard';
use CGI::Carp 'fatalsToBrowser';
use Fcntl ':flock';
use Time::HiRes 'sleep';

#print header(), qq{Sorry, the <a href="http://www.plover.com/rainbowice/">Rainbow Ice</a> guestbook is temporarily closed</a>.</p>};
#exit;
$|=1;

%escape = ('<' => 'lt',
           '>' => 'gt',
           '"' => 'quot',
           '&' => 'amp',
          );

@fields = qw(AGE GENDER ORIENTATION BLAH TIME);

$HOME = '/home/lorrie/rainbowice/gb';
# $HOME = '/home/mjd/public_html/gb';
$DATABASE = "$HOME/gb.data";
$SEMAPHORE = "$HOME/gb.data.lock";

$PAGE_HEADER = "$HOME/gb.header";
$PAGE_FOOTER = "$HOME/gb.footer";
$FORM = "$HOME/gb.form";
$TEMPLATE = "$HOME/gb.item";

$RSEP = "\n---\n";
$FSEP = "\n-\n";

http_header();

exit if $ENV{PATH_INFO};
exit if $ENV{REMOTE_ADDR} eq "68.114.40.181";
if (param()) {
  if ($ENV{REQUEST_METHOD} eq "GET") { exit ; }
  { my $gender = param('GENDER');
    exit unless $gender =~ /^\s*(m|male|f|female)\s*$/i;
  }
  param('TIME' => time);
  append_data();
}
show();

sub http_header {
  print "Content-type: text/html\n\n";
}

sub open_data_reading {
  open S, "> $SEMAPHORE" or die "Couldn't open semaphore file $SEMAPHORE: $!";
  flock S, LOCK_SH or die "Couldn't flock semaphore file: $!";
  open D, "< $DATABASE" or die "Couldn't open database: $!";
}

sub open_data_writing {
  open S, "> $SEMAPHORE" or die "Couldn't open semaphore file $SEMAPHORE: $!";
  flock S, LOCK_EX or die "Couldn't flock semaphore file: $!";
  open D, ">> $DATABASE" or die "Couldn't open database: $!";
}

sub close_data {
  close D;
  close S;
}

sub append_data {
  my @items = map {param($_)} @fields;
  for (@items) {
    s/[<>"&]/&$escape{$&};/g;
    s/\n-\n/\n--\n/g;
    s/\n---\n/\n----\n/g;
  }
  open_data_writing();
  print D join $FSEP, @items;
  print D $RSEP;
  close_data();  
}

sub show {
  my @items;
  print_file($PAGE_HEADER);
  print_file($FORM);
  my $template = get_file($TEMPLATE);
  open_data_reading();
  { local $/ = $RSEP;
    @items = reverse <D>;
    chomp @items;
  }
  for my $item (@items) {
    my(@data) = split /$FSEP/o, $item;
    for (@data) { s/\n/<br>/g }
    my $entry = $template;
    for my $i (0 .. $#fields) {
      if ($fields[$i] eq 'TIME') {
        $entry =~ s/\%$fields[$i]%/$data[$i] ? localtime($data[$i]) : ""/e;
      } else {
        $entry =~ s/\%$fields[$i]%/$data[$i]/;
      }
    }
    print $entry;
    sleep 0.25;  # Throttle
  }
  print_file($PAGE_FOOTER);
  close_data();
}    

sub get_file {
  my $FILENAME = shift;
  open F, "< $FILENAME" or die "Couldn't open $FILENAME: $!";
  my @data = <F>;
  close F;
  wantarray ? @data : join '', @data;
}

sub print_file {
  print get_file(@_);
}


