#!perl -w
use strict;

use vars qw(%CmdName %OptName $last_move);

BEGIN {
  %CmdName = map {/^\d/ ? chr($_) : $_} (
      0 => 'IS'  ,
      1 => 'SEND',
    240 => 'SE'  , # subnegotiation end
    241 => 'NOP' ,
    242 => 'DM'  , # Data Mark - not implemented
    243 => 'BRK' , # Break - not implemented
    244 => 'IP'  , # Interrupt Process
    245 => 'AO'  , # Abort output - not implemented
    246 => 'AYT' , # Are You There
    247 => 'EC'  , # Erase character
    248 => 'EL'  , # Erase Line
    249 => 'GA'  , # go ahead
    250 => 'SB'  , # subnegotiation begin
    251 => 'WILL', # \
    252 => 'WONT', #  \ option negotiation 
    253 => 'DO'  , #  /
    254 => 'DONT', # /
    255 => 'IAC' , # Interpret As Command
  );
  foreach (keys %CmdName) {
    eval "sub $CmdName{$_} () {chr(" . ord($_) . ")}"; die $@ if $@;
  }
  %OptName = map {/^\d/ ? chr($_) : $_} (
     1 => 'ECHO',
     6 => 'TIMING-MARK',
    24 => 'TERMINAL-TYPE',
    31 => 'NAWS',
  );
  foreach (keys %OptName) {
    my $name = $OptName{$_};
    $name =~ tr/-/_/;
    eval "sub OPT_$name () {chr(" . ord($_) . ")}"; die $@ if $@;
  }
}

use Net::Telnet;
use Chatbot::Eliza;

my $user = 'Eliza';
my $pass = 'zickelgork';
my $EL = "\cJ";

my $s = IO::Socket::INET->new(
  Proto => 'tcp',
  PeerAddr => 'g4.reid.loc',
  PeerPort => '4000',
) or die $!;
$s->autoflush(1);

$s->print(IAC.WONT.OPT_TERMINAL_TYPE);
#$s->print(IAC.WONT.OPT_NAWS);
$s->print("$user$EL");
$s->print("$pass$EL");
$s->print("1$EL");

my $bot = Chatbot::Eliza->new();
$last_move = 0;

MAIN: while ($s->opened) {
  $_ = $s->getline;
  tr/\x00-\x1F\x7F-\xFF//d;
  defined $_ or last;
  if (/^(\w.*) says "(.*)"$/mg) {
    my ($who, $text) = ($1, $2);
    print "Got $who: $text\n";

    if ($text =~ /Eliza/i and $bot->_testquit($text)) {
      $s->print("quit$EL"."0$EL");
      last MAIN;
    }

    my $reply =  $bot->transform($text);
    select(undef, undef, undef, 0.28);
    print "Replying $reply\n";
    $s->print("'$reply$EL");
  } elsif (0 and /you/i and !/You have connected|You say/) {
    print "Got $_\n";
    my $reply = $bot->transform($_);
    select(undef, undef, undef, 0.28);
    print "Replying $reply\n";
    $s->print("'$reply$EL");
  } else {
    next if time() < $last_move + 2;
    $s->print([qw(n e s w ne se sw nw u d)]->[rand 10], $EL);
    $last_move = time();
  }
}

sub nb_sock_read {
  my ($socket) = @_;
  my $mask = my $junk = my $junk2 = ''; vec($mask,fileno($socket),1) = 1;
  return '' unless select($junk=$mask, undef, $junk2=$mask, 0);
  my $res = sysread $socket, my($buf), 4096;
  defined $res or die "$!\n";
  return $buf;
}

