# irssi channel scanning script
# scans channels for clones. can filter for a minimum amount of clones.
# sorts by user@host. displays channel status (@%+). shows ircop status and away status.
# © jast aka. Jan Krüger, 2002. All rights reserved.
# The GPL (version 2) applies to this script.

# syntax:
# /cscan {ms} [additional parameter]
# m: sort by user@host (groups by host automagically)
# s: sort by channel status (op, voice)
# if neither m nor s is given, users are sorted by nick.
# parameter for m: limit display to users with that many clones
# parameter for s: show users with that status only (x: none)

$VERSION = "0.0.1";
%IRSSI = (
    authors     => 'Jan \'jast\' Krueger',
    contact     => 'jast@heapsort.de',
    name        => 'chanscan',
    description => 'Lists the users in a channel with great verbosity',
    license     => 'GNU GPLv2 or later',
    url         => 'http://jast.heapsort.de/dev/irssi.html'
);

Irssi::settings_add_str("chanscan", "chanscan_default_sort", "");

sub cscan_cmd {
  my ($data, $server, $witem) = @_;
  my @nicklist;
  my %hostlist;
  my %nickhash;

  $data = Irssi::settings_get_str("chanscan_default_sort") if(!$data);
  my ($params, $limit) = split(/ /, $data);

  if (!$server || !$server->{connected}) {
    Irssi::print("CSCAN: Not connected to server");
    return;
  }
  if (!$witem || $witem->{type} ne 'CHANNEL') {
    Irssi::print("CSCAN: can only be used on channels.");
    return;
  }
  @nicklist = Irssi::Channel::nicks($witem);

  foreach(@nicklist) {
      my $h = $_->{host};
      my $u = $h;
      $u =~ s/\@.*$//;
      $h =~ s/^[^\@]+\@//;
      my $formnick = ($_->{gone}?"%C(%n":"").($_->{serverop}?"%_":"").$_->{nick}.($_->{serverop}?"%_":"").($_->{gone}?"%C)%n":"");
      $formnick = "%C+%n".$formnick if($_->{voice});
      $formnick = "%C%%%n".$formnick if($_->{halfop});
      $formnick = "%C@%n".$formnick if($_->{op});
      $nickhash{$_} = $formnick;
      if($params eq 'm') {
	  push @{$hostlist{$h}{nicks}}, $formnick;
	  push @{$hostlist{$h}{users}}, $u;
	  push @{$hostlist{$h}{ref}}, $_;
      }
  }
  $witem->print("\%_$witem->{name}\%_: ---- Channel report");
  
  ($params eq 'm') && do {
      foreach(sort keys %hostlist) {
	  next if(@{$hostlist{$_}{nicks}} < $limit);
	  $witem->print(join(", ", @{$hostlist{$_}{nicks}})." \%C(\%c". join(",", @{$hostlist{$_}{users}}) ."%C\@%c$_\%C)");
      }
      $witem->print("\%_$witem->{name}\%_: ---- End of channel report");
      return;
  };
  if ($params eq 's') {
      @nicklist = sort { ($b->{op} - $a->{op}) * 8 + ($b->{halfop} - $a->{halfop}) * 4 + ($b->{voice} - $a->{voice}) * 2 +
			     (uc($a->{nick}) cmp uc($b->{nick})) } @nicklist;
  } else {
      @nicklist = sort { uc($a->{nick}) cmp uc($b->{nick}) } @nicklist;
  }
  foreach(@nicklist) {
      my $h = $_->{host};
      $h =~ s/\@/\%C\@\%c/;
      if($params eq 's' && $limit) {
	  my $hasit = 0;
	  $hasit = 1 if($limit =~ /\@/ && $_->{op});
	  $hasit = 1 if($limit =~ /\%/ && $_->{halfop});
	  $hasit = 1 if($limit =~ /\+/ && $_->{voice});
	  if($limit eq 'x') {
	      next if($_->{op} || $_->{halfop} || $_->{voice});
	      $hasit = 1;
	  }
	  next if(!$hasit);
      }
      $witem->print($nickhash{$_}." %C(%c$h\%C)");
  }
  $witem->print("\%_$witem->{name}\%_: ---- End of channel report");
}

Irssi::command_bind('cscan','cscan_cmd');
