# [&bitlbee] set typing_notice true
# <@root> typing_notice = `true'
# AND
# /statusbar window add typing_notice
#
# After changing Irssi settings reload the script.
# 
# Changelog:
#
# 2005-08-26:
# Some fixes for AIM, Thanks to Dracula.
#
# 2005-08-16:
# AIM supported, for sending notices, using CTCP TYPING 0. (Use the AIM patch from Hanji http://get.bitlbee.org/patches/)
# 
# 2004-10-31:
# Sends typing notice to the bitlbee server when typing a message in irssi. bitlbee > 0.92
#
# 2004-06-11:
# shows [typing: ] in &bitlbee with multiple users.
#
# 
#use Data::Dumper;
use strict;
use Irssi::TextUI;

use vars qw($VERSION %IRSSI);

$VERSION = '1.3';
%IRSSI = (
    authors     => 'Tijmen "timing" Ruizendaal',
    contact     => 'tijmen@fokdat.nl',
    name        => 'BitlBee_typing_notice',
    description => '	1. Adds an item to the status bar wich shows [typing] when someone is typing a message on the supported IM-networks
    			2. Sending typing notices to the supported IM networks (the other way arround)',
    license => 'GPLv2',
    url     => 'http://the-timing.nl/stuff/irssi-bitlbee',
    changed => '2005-08-26',
);

Irssi::settings_add_str('misc', 'bitlbee_send_typing', undef);

my $KEEP_TYPING_TIMEOUT = 1;
my $STOP_TYPING_TIMEOUT = 7;
my %timer_tag;

my %typing;
my %tag;
my $line;
my %out_typing;
my $bitlbee_channel = "&bitlbee";
my $bitlbee_server_tag = "local";
my $lastkey;
my $keylog_active = 1;
my $command_char = Irssi::settings_get_str('cmdchars');
my $to_char = Irssi::settings_get_str("completion_char");
my $send_typing = Irssi::settings_get_str('bitlbee_send_typing');

sub chan_sync {
  my( $channel ) = @_;
  if( $channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information." ){
    #print Dumper($channel);
    $bitlbee_server_tag = $channel->{server}->{tag};
    $bitlbee_channel = $channel->{name};
  }
}

sub event_notice {
  my ($server, $cmd, $from, $address, $to) = @_;
  #my ($my_nick, $msg) = split(/:/,$msg,2);
  #print "C: $cmd, S: $server, T: $to, F: $from, A: $address";
  if ($cmd eq "TYPING 1"){
    Irssi::signal_stop();
    $typing{$from} = 1;
    Irssi::timeout_remove($tag{$from});
    $tag{$from} = Irssi::timeout_add($STOP_TYPING_TIMEOUT*1000, 'empty', $from);
       
    my $window = Irssi::active_win();
    my $channel = $window->get_active_name();
    #if ($from eq $channel || $channel eq $bitlbee_channel || $channel =~ /#chat_0/){ ## COMMENT this line for the notices in all channels
      Irssi::statusbar_items_redraw('typing_notice');
    #} ## and COMMENT this one
  }
}

sub event_privmsg {
  my ($server, $data, $from, $address) = @_;
  if ($typing{$from} == 1){
    delete($typing{$from});
    Irssi::timeout_remove($tag{$from});
    Irssi::statusbar_items_redraw('typing_notice');
#    print "remove notice";
  }
#  my $window = Irssi::active_win();
#  my $channel = $window->get_active_name();
  
#  if ($channel eq $from || $channel eq $bitlbee_channel || $channel =~ /#chat_0/){ 
    #delete($typing{$channel}); #done twice?
#    Irssi::timeout_remove($tag{$from});
#    Irssi::statusbar_items_redraw('typing_notice');
#    print "remove bar";
#  }
}

sub typing_notice {
  my ($item, $get_size_only) = @_;
  my $window = Irssi::active_win();
  my $channel = $window->get_active_name();
    
  if (exists($typing{$channel})){
    $item->default_handler($get_size_only, "{sb typing}", 0, 1);
  }else{
    $item->default_handler($get_size_only, "", 0, 1);
    Irssi::timeout_remove($tag{$channel});
  }
  #if ($channel eq $bitlbee_channel || $channel =~ /#chat_0/){ ## COMMENT this one
  if($channel =~ /^#/){ ## unCOMMENT this one
    foreach my $key (keys(%typing) )
    {
      $line = $line." ".$key;
    }
    if ($line ne "" ){
      $item->default_handler($get_size_only, "{sb typing:$line}", 0, 1);
      $line = "";
    }
  } 
}

sub empty {
  my $from = shift;
  delete($typing{$from});
  Irssi::statusbar_items_redraw('typing_notice');
}

sub window_change {
  Irssi::statusbar_items_redraw('typing_notice');

    my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
    if ( ref $win && ( $win->{server}->{tag} eq $bitlbee_server_tag ) ) {
        if (! $keylog_active ) {
            $keylog_active = 1;
            Irssi::signal_add_last('gui key pressed', 'key_pressed');
            #print "Keylog started";
        }
    } else {
        if ( $keylog_active ) {
            $keylog_active = 0;
            Irssi::signal_remove('gui key pressed', 'key_pressed');
            #print "Keylog stopped";
        }
    }
}

sub key_pressed {
  if($send_typing){
    my $key = shift;
#    print $key;
    if($key != 9 && $key != 10 && $lastkey != 27 && $key != 27 && $lastkey != 91 && $key != 126 && $key != 127){
#      print "fetched: ".$key;
      my $server = Irssi::active_server();
      my $window = Irssi::active_win();
      my $nick = $window->get_active_name();
      if ($server->{tag} eq $bitlbee_server_tag && $nick ne "(status)"){
        if($nick eq $bitlbee_channel){
          my $input = Irssi::parse_special("\$L");
          my ($first_word) = split(/ /,$input);
          if ($input !~ /^$command_char.*/ && $first_word =~ s/$to_char$//){
            send_typing($first_word);
          }
  	}else{
          my $input = Irssi::parse_special("\$L");
          if ($input !~ /^$command_char.*/ && length($input) > 0){
            send_typing($nick);
	  }
        }
      }
    }
    $lastkey = $key; 
  }
}

sub out_empty {
  my ($a) = @_;
  my @a = @{$a};
  my $winnum=$a[1];
  my $nick=$a[0];
  delete($out_typing{$nick});
  #print $winnum."|".$nick;
  if(my $window=Irssi::window_find_refnum($winnum)){
    $window->command("^CTCP $nick TYPING 0");
    #print("Typing (0): ", $nick);
  }
}

sub send_typing {
  my $nick = shift;
  if (!exists($out_typing{$nick}) || time - $out_typing{$nick} > $KEEP_TYPING_TIMEOUT){
    my $window = Irssi::active_win();
    $window->command("^CTCP $nick TYPING 1");

    #print("Typing (1): ", $nick);
    
    $out_typing{$nick} = time;
    my @array=("$nick", $window->{refnum});

    ### Reset 'stop-typing' timer
    if ($timer_tag{$nick}) {
        Irssi::timeout_remove($timer_tag{$nick});
        delete($timer_tag{$nick});
    }
    $timer_tag{$nick} = Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*7000, 'out_empty', ["$nick", $window->{refnum}]);
  }
}
Irssi::signal_add("ctcp msg", "event_notice");
Irssi::signal_add("event privmsg", "event_privmsg");
Irssi::signal_add_last('window changed', 'window_change');
Irssi::statusbar_item_register('typing_notice', undef, 'typing_notice');
Irssi::signal_add_last('gui key pressed', 'key_pressed');
Irssi::signal_add_last('channel sync','chan_sync');
Irssi::statusbars_recreate_items();