use vars qw($VERSION %IRSSI);
use Irssi 20020120;

$VERSION = "0.1.1";

%IRSSI = (
    authors     => "Akke",
    contact     => "irc://akke",
    name        => "Typing notice",
    description => "none",
    license     => "none",
    url         => "http://www.akke.net/bitlbee",
    changed     => "first release... not even completed!",
);

# Added by Dracula:
# 
#  - Anti-flood protection, otherwise irssi would queue dozens of typing notification
#    commands before sending the actual message
#    
#  - Ignore control sequences, like scrolling in history or switching between windows
#  
#  - Turn off key logging for non-bitlbee non-query windows, to speed up pasting text
#    in other channels.
#

Irssi::theme_register(
[
 'typing_notice_crap', '{line_start}{hilight ' . $IRSSI{'name'} . ':} $0',
]);
  

my $SERVER_TAG = 'local';
my $TYPING_TIMEOUT = 5;
my $CONTROL_TIMEOUT = 0.5;

my %notice_time = 0;
my %control_time = 0;
my $control_sequence = 0;
my $keylog_active = 0;


sub sig_window_changed ($) {
    #my ($newwin, $oldwin) = @_;
   
    my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
    if ( ref $win && ( $win->{server}->{tag} eq $SERVER_TAG ) && ( $win->{type} eq "QUERY" ) ) {
        if (! $keylog_active ) {
            $keylog_active = 1;
            Irssi::signal_add('gui key pressed', 'sig_key_pressed');
            #Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'typing_notice_crap', 'key logged started');
        }
    } else {
        if ( $keylog_active ) {
            $keylog_active = 0;
            Irssi::signal_remove('gui key pressed', 'sig_key_pressed');
            #Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'typing_notice_crap', 'key logged stopped');
        }
    }
}

# todo: only send the TYPING only once per second per nickname ?
# todo: check cmd_max_speed &nd cmds_max_at_once settings!

sub sig_key_pressed ($) {
    my ($key) = @_;

    my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
    
    if (! ( ref $win && ( $win->{server}->{tag} eq $SERVER_TAG ) && ( $win->{type} eq "QUERY" ) )) {
        return 1;
    }
    
    # The escape key triggers a control sequence (eg. switching between windows, or scrolling in history)
    # Ignore the entire sequence so it won't send a typing notice
    if ($key == 27) {
        # We don't know the length of the sequence, so ignore all keys within 0.5 seconds with a maximum of 5 keys.
        $control_sequence = 5;
        $control_time = time;
    } else {
        # Check whether we still want to ignore keys
        if ($control_sequence > 0) {
            $control_sequence = $control_sequence - 1;
            # Time has expired
            if (time - $control_time > $CONTROL_TIMEOUT) {
                $control_sequence = 0;
            }
        }
    }

    # If not in a control sequence
    if ($control_sequence == 0) {
        # and it's a regular character
        if ($key > 32 && $key < 126) {
            # and there are at least 5 seconds between now and the previous notice
            if (time - $notice_time{$win->{name}} > $TYPING_TIMEOUT) {
                # Yes! Send a typing notice for this nickname, and remember the current time
                $win->command("QUOTE TYPING ".$win->{name});
                $notice_time{$win->{name}} = time;
            }
        }
    }
}

Irssi::signal_add('window changed', 'sig_window_changed');