##############################################################################
#
# Jarl - Roster Tk Interface Code
#
#   Perl code to handle showing the Jarl Roster GUI and interfacing with the
# roster items.
#
##############################################################################

##############################################################################
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#  Jabber
#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
#
##############################################################################

##############################################################################
#
# jarlRosterIF_GUI - creates the Roster GUI.
#
##############################################################################
sub jarlRosterIF_GUI {
  my ($frame) = @_;

  $GUI{Roster}->{vars}->{rosterItem} = "";

  $GUI{Roster}->{ToolBar}->{top} =
    $$frame->
      Frame(-borderwidth=>0,
	    -relief=>"flat",
	    -background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -anchor=>"w",
		   -fill=>"x");

  $GUI{Roster}->{ToolBar}->{Connection} =
    $GUI{Roster}->{ToolBar}->{top}->
      Button(-image=>$GUI{Icons}->{Disconnected},
	     -relief=>"flat",
	     -borderwidth=>1,
	     -background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
	     -command=>sub {
	       if ($jabber{connected} == 1) {
		 &jarlDisconnect();
	       } else {
		 &jarlConnect();
	       }
	       &jarlMainIF_ChangeIcon($GUI{Roster}->{ToolBar}->{Connection},
				    ($jabber{connected} == 1 ?
				     "Connected" :
				     "Disconnected"),
				    ($jabber{connected} == 1 ?
				     "Disconnected":
				     "Connected"));
	     })->pack(-side=>"left",
		      -pady=>2,
		      -padx=>3);
  &jarlMainIF_RegisterIcon($GUI{Roster}->{ToolBar}->{Connection},"Disconnected");
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Roster}->{ToolBar}->{Connection},
	   -balloonmsg=>"Connect/Disconnect ");
  $GUI{Roster}->{ToolBar}->{Connection}->
    bind("<Enter>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{Connection}->configure(-relief=>"raised");
	 });
  $GUI{Roster}->{ToolBar}->{Connection}->
    bind("<Leave>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{Connection}->configure(-relief=>"flat");
	 });

  $GUI{Roster}->{ToolBar}->{RosterShow} =
    $GUI{Roster}->{ToolBar}->{top}->
      Button(-image=>($config{onlineonly} ?
		     $GUI{Icons}->{ShowOnline} :
		     $GUI{Icons}->{ShowMixed}),
	     -relief=>"flat",
	     -borderwidth=>1,
	     -background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
	     -command=>sub {
	       $config{onlineonly} ^= 1;
	       &jarlMainIF_UpdateOnlineOnly();
	     })->pack(-side=>"left",
		      -pady=>2,
		      -padx=>3);
  &jarlMainIF_RegisterIcon($GUI{Roster}->{ToolBar}->{RosterShow},
			 ($config{onlineonly} ?
			  "ShowOnline" :
			  "ShowMixed"));
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Roster}->{ToolBar}->{RosterShow},
	   -balloonmsg=>"Show On-Line only ");
  $GUI{Roster}->{ToolBar}->{RosterShow}->
    bind("<Enter>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{RosterShow}->configure(-relief=>"raised");
	 });
  $GUI{Roster}->{ToolBar}->{RosterShow}->
    bind("<Leave>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{RosterShow}->configure(-relief=>"flat");
	 });

  $GUI{Roster}->{ToolBar}->{NewMessage} =
    $GUI{Roster}->{ToolBar}->{top}->
      Button(-image=>($GUI{Icons}->{NewMessage}),
	     -relief=>"flat",
	     -borderwidth=>1,
	     -background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
	     -command=>sub {
	       my $to = $Roster->Selected();
	       if ($to ne "") {
		 my $toJID = new Net::Jabber::JID($to);
		 &jarlNormal_Compose("new",$toJID);
	       } else {
		 &jarlNormal_Compose("new");
	       }
	     })->pack(-side=>"left",
		      -pady=>2,
		      -padx=>3);
  &jarlMainIF_RegisterIcon($GUI{Roster}->{ToolBar}->{NewMessage},"NewMessage");
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Roster}->{ToolBar}->{NewMessage},
	   -balloonmsg=>"New Message ");
  $GUI{Roster}->{ToolBar}->{NewMessage}->
    bind("<Enter>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{NewMessage}->configure(-relief=>"raised");
	 });
  $GUI{Roster}->{ToolBar}->{NewMessage}->
    bind("<Leave>",
	 sub {
	   $GUI{Roster}->{ToolBar}->{NewMessage}->configure(-relief=>"flat");
	 });





  $GUI{Roster}->{top} =
    $$frame->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);

#  $GUI{Roster}->{Header} =
#    $GUI{Roster}->{top}->
#      Label(-text=>"Who's Online?",
#	    -anchor=>"w",
#	    -font=>$GUI{fonts}->{header},
#	    -background=>$GUI{color}->{bg}->{normal},
#	    -foreground=>$GUI{color}->{fg}->{dark},
#	   )->pack(-side=>"top",
#		   -fill=>"x");

  $GUI{Roster}->{List}->{top} =
    $GUI{Roster}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -relief=>"sunken",
	    -borderwidth=>2
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1,
		   -padx=>5,
		   -pady=>5);

  $Roster =
    $GUI{Roster}->{List}->{Roster} =
      $GUI{Roster}->{List}->{top}->
	Roster(
	       -background=>$GUI{color}->{bg}->{normal},
	       -groupbackground=>"gray70",
	       -groupforeground=>"black",
	       -jidbackground=>"gray80",
	       -jidforeground=>"black",
	       -selectbackground=>"light blue",
	       -resourcebackground=>"grey90",
	       -resourceforeground=>"black",
	       -balloon=>$GUI{ToolBar}->{Balloon},
	       -font=>$GUI{fonts}->{normal},
	       -jidleftcommand=>sub{
		 my ($jid,$resource) = @_;
		 my $toJID = new Net::Jabber::JID($jid);
		 if ($config{rosterdoubleclick} eq "normal") {
		   $toJID->SetResource($resource);
		   &jarlNormal_Compose("new",$toJID);
		 }
		 &jarlChat_AddMessage($toJID,"")
		   if ($config{rosterdoubleclick} eq "chat");
	       },
	       -jidrightcommand=>sub{
		 my ($group,$jid,$resource) = @_;
		 &jarlRosterIF_PopupConfig($group,$jid,$resource);
		 $GUI{RosterPopup}->{menu}->Popup(-popover=>"cursor",
						  -popanchor=>"nw");
	       },
	      )->pack(-side=>"left",
		      -fill=>"both",
		      -expand=>1,
		      -padx=>0,
		      -pady=>0);
}


##############################################################################
#
# jarlRosterIF_PopupConfig - configures the Roster popup menu based on the
#                            roster settings for that item.
#
##############################################################################
sub jarlRosterIF_PopupConfig {
  my ($group,$jid,$resource) = @_;

  $resource = "" unless defined($resource);

  my $toJID = new Net::Jabber::JID();
  $toJID->SetJID($jid);
  $toJID->SetResource($resource) unless ($resource eq "");

  my $fullJID = new Net::Jabber::JID();
  $fullJID->SetJID($jid);
  $fullJID->SetResource(($resource ne "") ? $resource : $Roster->Resource($jid));

  $GUI{RosterPopup}->{menu}->
    entryconfigure(0,-label=>$toJID->GetJID("full"));

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Send Message",
		   -state=>"normal",
		   -command=>sub{
		     &jarlNormal_Compose("new",$toJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Start Chat",
		   -state=>"normal",
		   -command=>sub{
		     &jarlChat_AddMessage($toJID,"");
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("CTCP...",-state=>"normal");

  $GUI{RosterPopup}->{CTCPMenu}->{menu}->
    entryconfigure("Client Version",
		   -command=>sub{
		     $jabber{client}->VersionQuery(to=>$fullJID);
		   });
  
  $GUI{RosterPopup}->{CTCPMenu}->{menu}->
    entryconfigure("Time / Ping",
		   -command=>sub{
		     $jabber{client}->TimeQuery(to=>$fullJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Edit Roster Item",
		   -state=>"normal",
		   -command=>sub{
		     &jarlRosterIF_EditItemGUI($toJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Delete Roster Item",
		   -state=>"normal",
		   -command=>sub{
		     &jarlRosterIF_VerifyDelete($toJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Subscribe to JID",
		   -state=>"normal",
		   -command=>sub{
		     $jabber{client}->Subscription(type=>"subscribe",
						   to=>$toJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Unsubscribe from JID",
		   -state=>"normal",
		   -command=>sub{
		     $jabber{client}->Subscription(type=>"unsubscribe",
						   to=>$toJID);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Show/Hide Resources",
		   -state=>"normal",
		   -command=>sub {
		     $Roster->Toggle($group,$jid);
		   });

  $GUI{RosterPopup}->{menu}->
    entryconfigure("CTCP...",-state=>"disabled")
      if ($Roster->GetValue($jid,"type") eq "unavailable");

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Edit Roster Item",-state=>"disabled")
      if ($resource ne "");
  $GUI{RosterPopup}->{menu}->
    entryconfigure("Delete Roster Item",-state=>"disabled")
      if ($resource ne "");

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Subscribe to JID",-state=>"disabled")
      if (($resource ne "") ||
	  ($Roster->GetValue($jid,"subscription") eq "both") ||
	  ($Roster->GetValue($jid,"subscription") eq "to"));
  $GUI{RosterPopup}->{menu}->
    entryconfigure("Unsubscribe from JID",-state=>"disabled")
      if (($resource ne "") ||
	  ($Roster->GetValue($jid,"subscription") eq "from") ||
	  ($Roster->GetValue($jid,"subscription") eq "none"));

  $GUI{RosterPopup}->{menu}->
    entryconfigure("Show/Hide Resources",-state=>"disabled")
      if (($resource ne "") ||
	  ($Roster->GetValue($jid,"type") eq "unavailable"));
  
}


##############################################################################
#
# jarlRosterIF_PopupGUI - creates the Roster Popup menu.
#
##############################################################################
sub jarlRosterIF_PopupGUI {

  $GUI{RosterPopup}->{menu} =
    $GUI{Main}->{top}->
      Menu(-tearoff=>0,
	   -borderwidth=>2,
	   -relief=>"raised",
	   -background=>$GUI{color}->{bg}->{normal},
	   -foreground=>$GUI{color}->{fg}->{dark},
	  );
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"JID",
	-font=>$GUI{fonts}->{normal},
	-background=>$GUI{color}->{bg}->{darkest},
	-state=>"disabled"
       );

  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Send Message",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Start Chat",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{menu}->
    add("cascade",
	-label=>"CTCP...",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
       );

  
  $GUI{RosterPopup}->{CTCPMenu}->{menu} =
    $GUI{RosterPopup}->{menu}->
      Menu(-tearoff=>0,
	   -borderwidth=>2,
	   -relief=>"raised",
	   -background=>$GUI{color}->{bg}->{normal},
	   -foreground=>$GUI{color}->{fg}->{dark},
	  );
  
  $GUI{RosterPopup}->{CTCPMenu}->{menu}->
    add("command",
	-label=>"Client Version",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{CTCPMenu}->{menu}->
    add("command",
	-label=>"Time / Ping",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});

  $GUI{RosterPopup}->{menu}->
    entryconfigure("CTCP...",-menu=>$GUI{RosterPopup}->{CTCPMenu}->{menu});
  
  $GUI{RosterPopup}->{menu}->
    add("separator",
	-background=>$GUI{color}->{bg}->{normal});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Edit Roster Item",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Delete Roster Item",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{menu}->
    add("separator",
	-background=>$GUI{color}->{jarl}->{menu}->{background});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Subscribe to JID",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Unsubscribe from JID",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});

  $GUI{RosterPopup}->{menu}->
    add("separator",
	-background=>$GUI{color}->{jarl}->{menu}->{background});
  
  $GUI{RosterPopup}->{menu}->
    add("command",
	-label=>"Show/Hide Resources",
	-font=>$GUI{fonts}->{normal},
	-foreground=>$GUI{color}->{fg}->{dark},
	-background=>$GUI{color}->{bg}->{normal},
	-command=>sub{
	});
  
}


##############################################################################
#
# jarlRosterIF_EditItemGUI - creates the Edit Item GUI.
#
##############################################################################
sub jarlRosterIF_EditItemGUI {
  my ($toJID) = @_;

  my $title;
  if (ref($toJID) eq "Net::Jabber::JID") {
    $title = "Edit Roster Item";
    $GUI{EditRosterItem}->{vars}->{mode} = "edit";

    my $jid = $toJID->GetJID("full");
    $GUI{EditRosterItem}->{vars}->{jid} = $jid;
    $GUI{EditRosterItem}->{vars}->{name} =
      $Roster->GetValue($jid,"name");
    $GUI{EditRosterItem}->{vars}->{name} = ""
      if ($GUI{EditRosterItem}->{vars}->{name} eq $toJID->GetJID("full"));
    $GUI{EditRosterItem}->{vars}->{subscription} =
      $Roster->GetValue($jid,"subscription");

    foreach my $group ($Roster->GetGroups()) {
      $GUI{EditRosterItem}->{vars}->{groups}->{$group} = 0;
    }
    if ($Roster->GetValue($toJID->GetJID("full")) == 1) {
      foreach my $group ($Roster->GetValue($toJID->GetJID("full"),"groups")) {
	$GUI{EditRosterItem}->{vars}->{groups}->{$group} = 1;
      }
    }
  } else {
    $GUI{EditRosterItem}->{vars}->{mode} = "new";
    $title = "Add Roster Item";
  }

  $GUI{EditRosterItem}->{window} = $GUI{top}->Toplevel();
  $GUI{EditRosterItem}->{window}->title($title);
  $GUI{EditRosterItem}->{window}->resizable(0,0);

  $GUI{EditRosterItem}->{top} =
    $GUI{EditRosterItem}->{window}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"y",
		   -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad},
		   -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		   -expand=>1);

  $GUI{EditRosterItem}->{JID}->{top} =
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{JID}->{Label} =
    $GUI{EditRosterItem}->{JID}->{top}->
      Label(-text=>"JID:",
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{label},
	    -anchor=>"e",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -background=>$GUI{color}->{bg}->{normal}
	   )->pack(-side=>"left",
		   -fill=>"y",
		   -anchor=>"e");
  $GUI{EditRosterItem}->{JID}->{Entry} =
    $GUI{EditRosterItem}->{JID}->{top}->
      Entry(-textvariable=>\$GUI{EditRosterItem}->{vars}->{jid},
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{entry},
	    -background=>($GUI{EditRosterItem}->{vars}->{mode} eq "new") ? $GUI{color}->{bg}->{light} : $GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -font=>$GUI{fonts}->{normal},
	    -state=>($GUI{EditRosterItem}->{vars}->{mode} eq "new") ? "normal" : "disabled",
	   )->pack(-side=>'left',
		   -anchor=>'w');
  
  $GUI{EditRosterItem}->{Name}->{top} =
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{Name}->{Label} =
    $GUI{EditRosterItem}->{Name}->{top}->
      Label(-text=>"Name:",
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{label},
	    -anchor=>"e",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -background=>$GUI{color}->{bg}->{normal}
	   )->pack(-side=>"left",
		   -fill=>"y",
		   -anchor=>"e");
  $GUI{EditRosterItem}->{Name}->{Entry} =
    $GUI{EditRosterItem}->{Name}->{top}->
      Entry(-textvariable=>\$GUI{EditRosterItem}->{vars}->{name},
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{entry},
	    -background=>$GUI{color}->{bg}->{light},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -font=>$GUI{fonts}->{normal},
	   )->pack(-side=>'left',
		   -anchor=>'w');

  $GUI{EditRosterItem}->{Subscription}->{top} =
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{Subscription}->{Label} =
    $GUI{EditRosterItem}->{Subscription}->{top}->
      Label(-text=>"Subscription:",
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{label},
	    -anchor=>"e",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -background=>$GUI{color}->{bg}->{normal}
	   )->pack(-side=>"left",
		   -fill=>"y",
		   -anchor=>"e");
  $GUI{EditRosterItem}->{Subscription}->{Entry} =
    $GUI{EditRosterItem}->{Subscription}->{top}->
      Label(-textvariable=>\$GUI{EditRosterItem}->{vars}->{subscription},
	    -background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -font=>$GUI{fonts}->{normal},
	   )->pack(-side=>'left',
		   -anchor=>'w');


  $GUI{EditRosterItem}->{Groups}->{top} =
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{Groups}->{Label} =
    $GUI{EditRosterItem}->{Groups}->{top}->
      Label(-text=>"Groups:",
	    -anchor=>"w",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -background=>$GUI{color}->{bg}->{normal}
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -anchor=>"w");
  $GUI{EditRosterItem}->{Groups}->{List}->{top} =
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -relief=>"sunken",
	    -borderwidth=>2,
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{Groups}->{List}->{Scrolled} =
    $GUI{EditRosterItem}->{Groups}->{List}->{top}->
      Scrolled("Text",
	       -scrollbars=>"e",
	       -wrap=>"none",
	       -width=>30,
	       -height=>5,
	       -borderwidth=>0,
	       -cursor=>$GUI{EditRosterItem}->{Groups}->{List}->{top}->cget(-cursor),
	       -background=>$GUI{color}->{bg}->{normal},
	       -foreground=>$GUI{color}->{fg}->{dark},
	      )->pack(-side=>"top",
		      -fill=>"both",
		      -padx=>0,
		      -pady=>0,
		      -expand=>1);

  $GUI{EditRosterItem}->{Groups}->{List}->{Scrollbar} = 
    $GUI{EditRosterItem}->{Groups}->{List}->{Scrolled}->
      Subwidget("yscrollbar");
  $GUI{EditRosterItem}->{Groups}->{List}->{Scrollbar}->
    configure(-width=>10,
	      -borderwidth=>1,
	      -relief=>"flat");
  $GUI{EditRosterItem}->{Groups}->{List}->{Text} = 
    $GUI{EditRosterItem}->{Groups}->{List}->{Scrolled}->Subwidget("text");

  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
    bind("<Button-4>",
	 sub{
	   $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
	     yviewScroll(-1,"units");
	 });
  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
    bind("<Button-5>",
	 sub{
	   $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
	     yviewScroll(1,"units");
	 });

  &jarlRosterIF_EditItemDrawGroupsCB();

  $GUI{EditRosterItem}->{Buttons}->{top} = 
    $GUI{EditRosterItem}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{EditRosterItem}->{Buttons}->{Cancel} =
    $GUI{EditRosterItem}->{Buttons}->{top}->
      Button(-text=>"Cancel",
	     -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
	     -background=>$GUI{color}->{bg}->{normal},
	     -foreground=>$GUI{color}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       &jarlRosterIF_EditItemCloseCB();
	     }
	    )->pack(-side=>"right",
		    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
  $GUI{EditRosterItem}->{Buttons}->{Save} =
    $GUI{EditRosterItem}->{Buttons}->{top}->
      Button(-text=>($GUI{EditRosterItem}->{vars}->{mode} eq "new") ? "Add" : "Edit",
	     -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
	     -background=>$GUI{color}->{bg}->{normal},
	     -foreground=>$GUI{color}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       return if ($GUI{EditRosterItem}->{vars}->{jid} eq "");
	       my @groups;
	       my $group;
	       foreach $group (keys(%{$GUI{EditRosterItem}->{vars}->{groups}})) {
		 push(@groups,$group) if ($GUI{EditRosterItem}->{vars}->{groups}->{$group} == 1);
	       }

	       $jabber{client}->
		 RosterAdd(jid=>$GUI{EditRosterItem}->{vars}->{jid},
			   name=>$GUI{EditRosterItem}->{vars}->{name},
			   group=>\@groups);
	       if ($GUI{EditRosterItem}->{vars}->{mode} eq "new") {
		 $jabber{client}->
		   Subscription(to=>$GUI{EditRosterItem}->{vars}->{jid},
				type=>"subscribe");
	       }
	       &jarlRosterIF_EditItemCloseCB();
	     }
	    )->pack(-side=>"right",
		    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
  $GUI{EditRosterItem}->{Buttons}->{NewGroup} =
    $GUI{EditRosterItem}->{Buttons}->{top}->
      Button(-text=>"New Group",
	     -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
	     -background=>$GUI{color}->{bg}->{normal},
	     -foreground=>$GUI{color}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       &jarlRosterIF_NewGroupGUI();
	     }
	    )->pack(-side=>"right",
		    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});

}


##############################################################################
#
# jarlRosterIF_EditItemCloseCB - closes Edit Item GUI.
#
##############################################################################
sub jarlRosterIF_EditItemCloseCB {
  $GUI{EditRosterItem}->{window}->destroy;
  delete($GUI{EditRosterItem});
}


##############################################################################
#
# jarlRosterIF_EditItemDrawGroupsCB - Draws the list of available groups.
#
##############################################################################
sub jarlRosterIF_EditItemDrawGroupsCB  {

  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->configure(-state=>"normal");
  my $group;
  my $start = 1;
  foreach $group (sort {$a cmp $b} $Roster->GetGroups()) {
    $GUI{EditRosterItem}->{Groups}->{List}->{Text}->insert("end","\n")
      if ($start == 0);
    $start = 0;
    $GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{top} =
      $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
	Frame(-background=>$GUI{color}->{bg}->{normal},
	      -foreground=>$GUI{color}->{fg}->{dark},
	     );
    $GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{Check} =
      $GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{top}->
	Checkbutton(-background=>$GUI{color}->{bg}->{normal},
		    -activebackground=>$GUI{color}->{bg}->{normal},
		    -foreground=>$GUI{color}->{fg}->{dark},
		    -selectcolor=>$GUI{color}->{bg}->{normal},
		    -indicatoron=>0,
		    -borderwidth=>0,
		    -image=>$GUI{Icons}->{Unchecked},
		    -selectimage=>$GUI{Icons}->{Checked},
		    -variable=>\$GUI{EditRosterItem}->{vars}->{groups}->{$group},
		   )->pack(-side=>'left',
			   -anchor=>'e',
			   -padx=>0,
			   -pady=>0);
    &jarlMainIF_RegisterIcon($GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{Check},"Unchecked");
    $GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{Label} =
      $GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{top}->
	Label(-text=>"$group",
	      -background=>$GUI{color}->{bg}->{normal},
	      -foreground=>$GUI{color}->{fg}->{dark},
	      -font=>$GUI{fonts}->{normal},
	     )->pack(-side=>'left',
		     -anchor=>'w');
    
    
    $GUI{EditRosterItem}->{Groups}->{List}->{Text}->
      windowCreate("end",
		   -window=>$GUI{EditRosterItem}->{Groups}->{List}->{Group}->{$group}->{top});
  }

  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->configure(-state=>"disabled");
}


##############################################################################
#
# jarlRosterIF_EditItemClearGroupsCB - clears the list of groups from the Edit
#                                    Item GUI.
#
##############################################################################
sub jarlRosterIF_EditItemClearGroupsCB  {
  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->configure(-state=>"normal");
  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->delete("1.0","end"); 
  $GUI{EditRosterItem}->{Groups}->{List}->{Text}->configure(-state=>"disabled");
}


##############################################################################
#
# jarlRosterIF_NewGroupGUI - creates the New Group GUI.
#
##############################################################################
sub jarlRosterIF_NewGroupGUI {

  $GUI{NewGroup}->{window} = $GUI{top}->Toplevel();
  $GUI{NewGroup}->{window}->title("New Group");
  $GUI{NewGroup}->{window}->resizable(0,0);

  $GUI{NewGroup}->{top} = 
    $GUI{NewGroup}->{window}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"y",
		   -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad},
		   -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		   -expand=>1);

  $GUI{NewGroup}->{JID}->{top} =
    $GUI{NewGroup}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{NewGroup}->{JID}->{Label} =
    $GUI{NewGroup}->{JID}->{top}->
      Label(-text=>"Group:",
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{label},
	    -anchor=>"e",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -background=>$GUI{color}->{bg}->{normal}
	   )->pack(-side=>"left",
		   -fill=>"y",
		   -anchor=>"e");
  $GUI{NewGroup}->{JID}->{Entry} =
    $GUI{NewGroup}->{JID}->{top}->
      Entry(-textvariable=>\$GUI{NewGroup}->{vars}->{group},
	    -width=>$GUI{width}->{jarl}->{rosteritem}->{entry},
	    -background=>$GUI{color}->{bg}->{light},
	    -foreground=>$GUI{color}->{fg}->{dark},
	    -font=>$GUI{fonts}->{normal},
	   )->pack(-side=>'left',
		   -anchor=>'w');

  $GUI{NewGroup}->{Buttons}->{top} =
    $GUI{NewGroup}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
	    -foreground=>$GUI{color}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1);
  $GUI{NewGroup}->{Buttons}->{Cancel} =
    $GUI{NewGroup}->{Buttons}->{top}->
      Button(-text=>"Cancel",
	     -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
	     -background=>$GUI{color}->{bg}->{normal},
	     -foreground=>$GUI{color}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       &jarlRosterIF_NewGroupCloseCB();
	     }
	    )->pack(-side=>"right",
		    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
  $GUI{NewGroup}->{Buttons}->{Save} =
    $GUI{NewGroup}->{Buttons}->{top}->
      Button(-text=>"Save",
	     -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
	     -background=>$GUI{color}->{bg}->{normal},
	     -foreground=>$GUI{color}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       return if ($GUI{NewGroup}->{vars}->{group} eq "");
	       &jarlRosterIF_EditItemClearGroupsCB();
	       $Roster->AddGroup($GUI{NewGroup}->{vars}->{group});
	       &jarlRosterIF_EditItemDrawGroupsCB();
	       &jarlRosterIF_NewGroupCloseCB();
	     }
	    )->pack(-side=>"right",
		    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
		    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
}


##############################################################################
#
# jarlRosterIF_NewGroupCloseCB - close the New Group GUI.
#
##############################################################################
sub jarlRosterIF_NewGroupCloseCB {
  $GUI{NewGroup}->{window}->destroy;
  delete($GUI{NewGroup});
}


##############################################################################
#
# jarlRosterIF_VerifyDelete - prompts the user when a "subscribe" comes in.
#
##############################################################################
sub jarlRosterIF_VerifyDelete {
  my ($toJID) = @_;

  $GUI{RosterVerifyDelete}->{window} = $GUI{top}->Toplevel();
  $GUI{RosterVerifyDelete}->{window}->title("Really Remove from Roster?");
  $GUI{RosterVerifyDelete}->{window}->resizable(0,0);

  $GUI{RosterVerifyDelete}->{top} = 
    $GUI{RosterVerifyDelete}->{window}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
            -foreground=>$GUI{color}->{fg}->{dark},
           )->pack(-side=>"top",
                   -fill=>"y",
                   -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad},
                   -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
                   -expand=>1);

  $GUI{RosterVerifyDelete}->{Text1}->{top} =
    $GUI{RosterVerifyDelete}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
            -foreground=>$GUI{color}->{fg}->{dark},
           )->pack(-side=>"top",
                   -fill=>"both",
                   -expand=>1);
  $GUI{RosterVerifyDelete}->{Text1}->{Label} =
    $GUI{RosterVerifyDelete}->{Text1}->{top}->
      Label(-text=>"Are you sure that you want to remove the following Jabber ID from your roster?",
            -anchor=>"w",
            -font=>$GUI{fonts}->{normal},
            -foreground=>$GUI{color}->{fg}->{dark},
            -background=>$GUI{color}->{bg}->{normal}
           )->pack(-side=>"left",
                   -fill=>"y",
                   -anchor=>"w");

  $GUI{RosterVerifyDelete}->{Text2}->{top} =
    $GUI{RosterVerifyDelete}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
            -foreground=>$GUI{color}->{fg}->{dark},
           )->pack(-side=>"top",
                   -fill=>"both",
                   -expand=>1);
  $GUI{RosterVerifyDelete}->{Text2}->{Label} =
    $GUI{RosterVerifyDelete}->{Text2}->{top}->
      Label(-text=>$toJID->GetJID("full"),
            -anchor=>"w",
            -font=>$GUI{fonts}->{header},
            -foreground=>$GUI{color}->{fg}->{dark},
            -background=>$GUI{color}->{bg}->{normal}
           )->pack(-side=>"left",
                   -fill=>"y",
                   -anchor=>"w");
  
  $GUI{RosterVerifyDelete}->{Buttons}->{top} = 
    $GUI{RosterVerifyDelete}->{top}->
      Frame(-background=>$GUI{color}->{bg}->{normal},
            -foreground=>$GUI{color}->{fg}->{dark},
           )->pack(-side=>"top",
                   -fill=>"both",
                   -expand=>1);
  $GUI{RosterVerifyDelete}->{Buttons}->{No} =
    $GUI{RosterVerifyDelete}->{Buttons}->{top}->
      Button(-text=>"No",
             -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
             -background=>$GUI{color}->{bg}->{normal},
             -foreground=>$GUI{color}->{fg}->{dark},
             -disabledforeground=>$GUI{color}->{fg}->{light},
             -font=>$GUI{fonts}->{normal},
             -command=>sub{
               &jarlRosterIF_VerifyDeleteCloseCB();
             }
            )->pack(-side=>"right",
                    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
                    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
  $GUI{RosterVerifyDelete}->{Buttons}->{Save} =
    $GUI{RosterVerifyDelete}->{Buttons}->{top}->
      Button(-text=>"Yes",
             -width=>$GUI{width}->{jarl}->{rosteritem}->{button},
             -background=>$GUI{color}->{bg}->{normal},
             -foreground=>$GUI{color}->{fg}->{dark},
             -disabledforeground=>$GUI{color}->{fg}->{light},
             -font=>$GUI{fonts}->{normal},
             -command=>sub{
	       $jabber{client}->RosterRemove(jid=>$toJID);
	       $jabber{client}->PresenceDBDelete($toJID);
               &jarlRosterIF_VerifyDeleteCloseCB();
             }
            )->pack(-side=>"right",
                    -pady=>$GUI{height}->{jarl}->{rosteritem}->{pad},
                    -padx=>$GUI{width}->{jarl}->{rosteritem}->{pad});
}


##############################################################################
#
# jarlRosterIF_VerifyDeleteCloseCB - closes the roster VerifyDelete GUI.
#
##############################################################################
sub jarlRosterIF_VerifyDeleteCloseCB {
  $GUI{RosterVerifyDelete}->{window}->destroy;
  delete($GUI{RosterVerifyDelete});
}


##############################################################################
#
# jarlRosterIF_PresenceIcon - returns the image to display for this presence.
#
##############################################################################
sub jarlRosterIF_PresenceIcon {
  return $GUI{Icons}->{&jarlRoster_PresenceIcon(@_)};
}


##############################################################################
#
# Stuff to do when we load the roster code.
#
##############################################################################
&jarlRosterIF_PopupGUI();


1;
