###################################################################

package KoLBot::Chatbot::Action;
 
# Copyright (c) 2004 Alan W. Mahoney. All rights reserved. 
# This program is free software.  You may modify and/or 
# distribute it under the same terms as Perl itself.  
# This copyright notice must remain attached to the file.  
#

# This needs some work to make it more flexible, but I haven't had
# any real needs to extend it with my applications.  The following
# would be the most useful.  Then more flexible substitutions, etc.

# Flag for custom function: return 0/1 or return based on function
# Flag for whether rule "matches" if rate limited

# 26 July 2004

use warnings;
use strict;

use POSIX qw( floor );

BEGIN 
{
  use Exporter ();
  our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $ID);

  $VERSION     = 0.5;
  $ID          = '$Id: Action.pm 173 2006-10-30 17:29:34Z alan $';

  @ISA         = qw(Exporter);
  @EXPORT      = qw();
  %EXPORT_TAGS = ( );

  @EXPORT_OK   = qw();
}

our @EXPORT_OK;

##########################################
## element access
##########################################

for my $field (qw( 
		   action

		   ouser
		   ochannel
		   omessage
		   omeat
		   oitem
		   onumber
		   )) {
  no strict "refs";
  *$field = sub {
    my $self = shift;
    $self->{$field} = shift if @_;
    return $self->{$field};
  }
}

##########################################
## Constructor:
##########################################

# Needs to be called with a full config hashref.  See examples.

sub new {
  my $invocant = shift;
  my $class = ref($invocant) || $invocant;
  my $action = { action   => 'pm',
		 ouser    => '$u',
		 ochannel => '$c',
		 omessage => [],
		 omeat    => 0,
		 oitem    => [],
		 onumber  => [],

		 @_ };
  bless $action, $class;
}

##########################################
## The rest
##########################################

sub do {
  my $action = shift;
  my $bot = shift;
  my $imessage = shift;		# Class Message/KMail
  my $m = shift;		# Matches []
  my $user = shift;		# Ick.
  my $rule = shift;
  my $user_id = shift;

  my $c = $imessage->{channel};

  # these are exactly the same :)
  if($action->{action} eq 'none') {
    return undef;
  }
  if($action->{action} eq 'log') {
    if(exists($action->{file})) {
      my $file = $action->{file};
      unless(open LOGFILE,'>>',$file) {
	print "Cant open $file\n";
	return;
      }
      print LOGFILE time(), ' ', $imessage,"\n";
      close LOGFILE;
    } else {
      print time() . " " . $imessage->as_string . "\n";
    }

    return undef;
  }

  if($action->{action} eq 'done') {
    return 1;
  }

  if($action->{action} eq 'print') {
    print $action->{omessage} . "\n";
    return undef;
  }

  if($action->{action} eq 'pm') {
    my $message2 = new KoLBot::ChatMessage;

    if(ref( $action->{omessage}) eq 'ARRAY') {
      my $s = @{$action->{omessage}};
      $message2->{message} = $action->{omessage}->[floor(rand($s))];
    } else {
      $message2->{message} = $action->{omessage};
    }

    $message2->{message} = sub_message($message2->{message},
				       $imessage,
				       $m);
    $message2->{user} = $action->{ouser};
    if($user_id) {
      $message2->{user} =~ s/\$u/$user_id/g;
    } else {
      $message2->{user} =~ s/\$u/$user/g;
    }

    $message2->{type} = 'private';

    print "out: (" . $rule->{name} . ") " . $message2->as_string . "\n";
    $bot->send_message($message2);
    return undef;
  }

  if($action->{action} eq 'normal') {
    my $message2 = new KoLBot::ChatMessage;

    if(ref( $action->{omessage}) eq 'ARRAY') {
      my $s = @{$action->{omessage}};
      $message2->{message} = $action->{omessage}->[floor(rand($s))];
    } else {
      $message2->{message} = $action->{omessage};
    }

    $message2->{message} = sub_message($message2->{message},
				       $imessage,
				       $m);

    $message2->{user} = '';
    $message2->{type} = 'normal';
    $message2->{channel} = $action->{ochannel} || 'clan';
    $message2->{channel} =~ s/\$c/$c/g;
    
    print "out: " . $message2->as_string . "\n";
    $bot->send_message($message2);
    return undef;
  }

  if($action->{action} eq 'emote') {
    my $message2 = new KoLBot::ChatMessage;

    if(ref( $action->{omessage}) eq 'ARRAY') {
      my $s = @{$action->{omessage}};
      $message2->{message} = $action->{omessage}->[floor(rand($s))];
    } else {
      $message2->{message} = $action->{omessage};
    }

    $message2->{message} = sub_message($message2->{message},
				       $imessage,
				       $m);
    $message2->{channel} = $action->{ochannel};
#    $message2->{user} =~ s/\$u/$u/g;
    $message2->{channel} =~ s/\$c/$c/g;

    $message2->{user} = '';
    $message2->{type} = 'emote';
    
    print "out: " . $message2->as_string . "\n";
    $bot->send_message($message2);
    return undef;
  }

  if($action->action eq 'custom') {

#    ($rule->log) and
#      print "custom rule = ", $rule->name;

    my $r = &{$action->{function}}($imessage,$bot,$rule,$rule->lqueue); 
    return $r;
  }

  if($action->{action} eq 'kmail') {

    my $ouser = $action->{ouser};
    $ouser = sub_message($ouser,$imessage,$m);
    my $omessage = $action->{omessage};
    $omessage = sub_message($omessage,$imessage,$m);

    my $omeat = $action->{omeat} || 0;
    $omeat = sub_message($omeat,$imessage,$m);

    ($omeat eq 'd4*d4*d4') and
      $omeat = floor(rand(4)*rand(4)*rand(4))+1;
    ($omeat eq 'd6*d6*d6') and
      $omeat = floor(rand(6)*rand(6)*rand(6))+1;
    ($omeat eq 'd10*d10*d10') and
      $omeat = floor(rand(10)*rand(10)*rand(10))+1;
    ($omeat eq 'd21*d21*d21') and
      $omeat = floor(rand(10)*rand(10)*rand(10)*rand(10))+1;
    ($omeat eq 'd100*d100') and
      $omeat = floor(rand(100)*rand(100))+1;

    my $onumber = $action->{onumber} || [];
    my $oitem = $action->{oitem} || [];

    if(ref($onumber) ne 'ARRAY') {
      $onumber = [$onumber];
    }
    if(ref($oitem) ne 'ARRAY') {
      $oitem = [$oitem];
    }
    my @items = ();
    for my $i (0..$#{$onumber}) {
      push @items,new KoLBot::Item(id => $oitem->[$i],
				   number => $onumber->[$i],);
    }

    $bot->send_kmail(new KoLBot::KMail(
			       user      => $ouser,
			       message   => $omessage,
			       items     => \@items,
#			       number    => $onumber,
#			       item_id   => $oitem,
			       meat      => $omeat,));

    my $msg =  "sent kmail, rule = " . $rule->name . " ($omeat) ";

    for(@items) {
      $msg .= $_->{number} . " \@ " . $_->{id} . ' ';
    }
    $msg .= "\n";
    print $msg;
    return undef;
  }

  die "Unknown action, ",$action->{action},"\n";
}

sub sub_message {
  my $omessage = shift;
  my $imessage = shift;
  my $m = shift;		# Matches []
  my $p = shift;		# Politify

  $omessage =~ s/\$1/$m->[0]/g;
  $omessage =~ s/\$2/$m->[1]/g;
  $omessage =~ s/\$3/$m->[2]/g;

  my $u0 = $imessage->{user};
  my $user = $u0;

  if($p) {
    if($imessage->{message} =~ /\bdear|\blov/) {
      my @ches = ("$u0, dear","$u0, dearest","dear $u0","dearest $u0");
      $user = $ches[rand(@ches)];
    }
  }

  $omessage =~ s/\$u/$user/g;

  if($p) {
    if($imessage =~ /\bchatbot\b/) {
      if(int(rand(2))) {
	$omessage =~ /^(.)(.*)$/;
	$omessage = lc($1) . $2;
	$user =~ /^(.)(.*)$/;
	$omessage = uc($1). $2 . ', ' . $omessage;
      } else {
	$omessage =~ s/(.)$/, $user$1/;
      }
    }
  }
  return $omessage;
}


END {} ;

1;

