use Irssi 20020101.0250 ();
$VERSION = "1.16";

# Once you have loaded this script run the following command:
# /statusbar window add usercount
# You can also add -alignment left|right option

# /set usercount_show_zero on or off to show users when 0 users of that type
# /set usercount_show_ircops (default off)
# /set usercount_show_halfops (default on)

# you can customize the look of this item from theme file:
#  sb_usercount = "{sb %_$0%_ nicks ($1-)}";
#  sb_uc_ircops = "%_*%_$*";
#  sb_uc_ops = "%_@%_$*";
#  sb_uc_halfops = "%_%%%_$*";
#  sb_uc_voices = "%_+%_$*";
#  sb_uc_normal = "$*";
#  sb_uc_space = " ";


use strict;
use Irssi::TextUI;

my ($ircops, $ops, $halfops, $voices, $normal, $total);
my ($timeout_tag, $recalc);
my (@nicklist);

# Called to make the status bar item
sub usercount {
  my ($item, $get_size_only) = @_;
  my $wi = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
  my $window=Irssi::active_win();

  if(!ref $wi || $wi->{type} ne "CHANNEL") { # only works on channels
    return unless ref $item;
    $item->{min_size} = $item->{max_size} = 0;
    return;
  }

  if ($recalc) {
    $recalc = 0;
    calc_users($wi);
  }

  my $theme = Irssi::current_theme();
  my $format = $theme->format_expand("{sb_usercount}");

    my $str = " ";
    my $nick="";

    if ($total!=0)
    {
	    my $leftover_space=($window->{width}-1)%($total);
	    my $leftover_median_nick=($total-$leftover_space)/2;

	    my $substr;
	    my $i=0;
		foreach (@nicklist)
		{
			$nick=$_;
			$substr=int(($window->{width}-1)/($total))-1;
			
			if ($leftover_space>0 && $i>=$leftover_median_nick)
			{
				$leftover_space--;
				$substr++;
			}

			if (substr($nick,0,1) eq "A")
			{
				$str.="{nohilight";
			}
			else
			{
				$str.="{hilight";
			}

			if (substr($nick,1,1) eq "@")
			{
				$str.=" %y";
			}
			elsif (substr($nick,1,1) eq "+")
			{
				$str.=" %g";
			}
			else
			{
				$str.=" %w";
			}

			$nick=substr($nick,2,$substr);
			$str.="$nick} ";
			$i++;
		}

	    $format = $theme->format_expand("{sb_usercount $str}",
		    Irssi::EXPAND_FLAG_IGNORE_REPLACES);

	  $item->default_handler($get_size_only, $format, undef, 1);
    }
}

sub calc_users() {
  my $channel = shift;
  my $server = $channel->{server};
  my @nicks;
  my $nick;

  $ircops = $ops = $halfops = $voices = $normal = 0;
  @nicks=sort {lc $a->{nick} cmp lc $b->{nick}} $channel->nicks();
  @nicklist=();
  $total=0;
  for (@nicks) {
	  $nick=$_->{nick};
	  if ($_->{op})
	  {
		  $nick="\@$nick";
	  }
	  elsif ($_->{voice})
	  {
		  $nick="+$nick";
	  }
	  else
	  {
		  $nick=" $nick";
	  }

	  if ($_->{gone})
	  {
		  $nick="A$nick";
	  }
	  else
	  {
		  $nick=" $nick";
	  }
	push(@nicklist, $nick);
	$total++;
  }

}

sub refresh {
   if ($timeout_tag > 0) {
      Irssi::timeout_remove($timeout_tag);
      $timeout_tag = 0;
   }
   Irssi::statusbar_items_redraw('usercount');
}

sub refresh_check {
   my $channel = shift;
   my $wi = ref Irssi::active_win() ? Irssi::active_win()->{active} : 0;

   return unless ref $wi && ref $channel;
   return if $wi->{name} ne $channel->{name};
   return if $wi->{server}->{tag} ne $channel->{server}->{tag};

   # don't refresh immediately, or we'll end up refreshing 
   # a lot around netsplits
   $recalc = 1;
   Irssi::timeout_remove($timeout_tag) if ($timeout_tag > 0);
   $timeout_tag = Irssi::timeout_add(500, 'refresh', undef);
}

sub refresh_recalc {
  $recalc = 1;
  refresh();
}

$recalc = 1;
$timeout_tag = 0;

Irssi::settings_add_bool('usercount', 'usercount_show_zero', 1);
Irssi::settings_add_bool('usercount', 'usercount_show_ircops', 0);
Irssi::settings_add_bool('usercount', 'usercount_show_halfops', 1);

Irssi::statusbar_item_register('usercount', undef, 'usercount');
Irssi::statusbars_recreate_items();

Irssi::signal_add_last('nicklist new', 'refresh_check');
Irssi::signal_add_last('nicklist remove', 'refresh_check');
Irssi::signal_add_last('nick mode changed', 'refresh_check');
Irssi::signal_add_last('setup changed', 'refresh_recalc');
Irssi::signal_add_last('window changed', 'refresh_recalc');
Irssi::signal_add_last('window item changed', 'refresh_recalc');

