##############################################################################
#
# Jarl - Chat Tk Interface Code
#
#   Perl code to handle showing the Jarl Chat GUI and interfacing with it.
#
##############################################################################

##############################################################################
#
#  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/
#
##############################################################################

##############################################################################
#
# jarlChatIF_AddMessage - function to add the <message/> to the proper chat tab.
#
##############################################################################
sub jarlChatIF_AddMessage {
  my ($tag,$type,$timestamp,$encrypted,$currentID,@message) = @_;

  $Debug->Log1("jarlChatIF_AddMessage: tag($tag) type($type) timestamp($timestamp)");
  $Debug->Log1("jarlChatIF_AddMessage: encrypted($encrypted) currentID($currentID)");
  $Debug->Log1("jarlChatIF_AddMessage: message(\"".join("\",\"",@message)."\")");

  my $priority = "low";

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    configure(-state=>"normal");

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    insert("end","\n")
      if ($GUI{Chat}->{$tag}->{vars}->{neednewline} == 1);
  $GUI{Chat}->{$tag}->{vars}->{neednewline} = 1;

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    insert("end","[".$timestamp."] ",[ "timestamp" , "lastinserted" ]);

  if ($encrypted == 1) {
    my $secureIcon =
      $GUI{Chat}->{$tag}->{ChatText}->{Text}->
	Label(-image=>$GUI{Icons}->{SecureMessage},
	      -background=>$GUI{color}->{jarl}->{main}->{bg}->{light});
    &jarlMainIF_RegisterIcon($secureIcon,"SecureMessage");
    $GUI{Chat}->{$tag}->{ChatText}->{Text}->
      windowCreate("end",
		   -window=>$secureIcon);
  }

  my (undef,undef,$lmargin,undef) =
    $GUI{Chat}->{$tag}->{ChatText}->{Text}->
      dlineinfo("lastinserted.first");

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagDelete("lastinserted");

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure($type."$currentID",
		 -lmargin1=>$lmargin,
		 -lmargin2=>$lmargin)
      unless (!defined($lmargin) || ($lmargin == 0));

  while ($#message > -1) {
    my $pieceType = shift(@message);
    my $piece = shift(@message);

    my @tagList = ( $pieceType, $type, $type."$currentID");
    if ($pieceType eq "link") {
      push(@tagList, "link-$piece");
      $GUI{Chat}->{$tag}->{ChatText}->{Text}->
	tagBind("link-$piece",
		"<Button-1>",
		sub{
		  &jarlFetchURL($piece);
		});
    }

    $GUI{Chat}->{$tag}->{ChatText}->{Text}->
      insert("end", $piece, \@tagList);

    $priority = "medium" if ($pieceType eq "highlight");
  }

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->yview("moveto",100)
    if ($GUI{Chat}->{$tag}->{vars}->{ScrollLock} == 1);
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    configure(-state=>"disabled");

  $TabBar->HighlightTab($tag,$priority);
}


##############################################################################
#
# jarlChatIF_ChatExists - returns 1 if the GUI for the chat exists, 0 if not.
#
##############################################################################
sub jarlChatIF_ChatExists {
  my ($tag) = @_;
  return exists($GUI{Chat}->{$tag});
}

##############################################################################
#
# jarlChatIF_NewChat - function to do all GUI calls needed to create a new
#                      chat.
#
##############################################################################
sub jarlChatIF_NewChat {
  my ($tag) = @_;

  $GUI{Chat}->{$tag}->{top} =
    $TabBar->AddTab(-type=>"docked",
		    -tag=>$tag,
		    -text=>"Chat - ".&jarlChat_ChatID($tag));
  &jarlChatIF_NewGUI($tag);
  &jarlChatIF_RaiseChat($tag);
}


##############################################################################
#
# jarlChatIF_RaiseChat - function to bring the specified chat to the top of
#                        the window list.
#
##############################################################################
sub jarlChatIF_RaiseChat {
  my ($tag) = @_;
  $TabBar->RaiseTab($tag);
}


##############################################################################
#
# jarlChatIF_NewGUI - populates a new Chat window.
#
##############################################################################
sub jarlChatIF_NewGUI {
  my ($tag) = @_;

  $GUI{Chat}->{$tag}->{vars}->{ScrollLock} = 1;
  $GUI{Chat}->{$tag}->{vars}->{neednewline} = 0;

  #---------------------------------------------------------------------------
  # Chat Window
  #---------------------------------------------------------------------------
  $GUI{Chat}->{$tag}->{ChatText}->{top}=
    $GUI{Chat}->{$tag}->{top}->
      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
	    -relief=>"sunken",
	    -borderwidth=>2
	   )->pack(-side=>"top",
		   -fill=>"both",
		   -expand=>1,
		   -padx=>5,
		   -pady=>5);

  $GUI{Chat}->{$tag}->{ChatText}->{Scrolled} =
    $GUI{Chat}->{$tag}->{ChatText}->{top}->
      Scrolled("Text",
	       -scrollbars=>"e",
	       -background=>$GUI{color}->{jarl}->{main}->{bg}->{light},
	       -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
	       -font=>$GUI{fonts}->{normal},
	       -borderwidth=>0,
	       -highlightthickness=>0,
	       -height=>0,
	       -width=>0,
	       -selectborderwidth=>0,
	       -exportselection=>1,
	       -takefocus=>0,
	       -wrap=>"word",
	       -cursor=>"xterm",
	       -state=>"disabled",
	      )->pack(-side=>"left",
		      -fill=>"both",
		      -expand=>1,
		      -padx=>0,
		      -pady=>0);

  $GUI{Chat}->{$tag}->{ChatText}->{Scrollbar} =
    $GUI{Chat}->{$tag}->{ChatText}->{Scrolled}->
      Subwidget("yscrollbar");
  $GUI{Chat}->{$tag}->{ChatText}->{Scrollbar}->
    configure(-width=>10,
	      -borderwidth=>1,
	      -highlightthickness=>0,
	      -relief=>"flat",
	      -command=>sub{
		my ($high,$low) =
		  $GUI{Chat}->{$tag}->{ChatText}->{Scrollbar}->get();
		$GUI{Chat}->{$tag}->{vars}->{ScrollLock} =
		  ($low == 1);
		$GUI{Chat}->{$tag}->{ChatText}->{Text}->yview(@_);
	      });
  $GUI{Chat}->{$tag}->{ChatText}->{Text} =
    $GUI{Chat}->{$tag}->{ChatText}->{Scrolled}->
      Subwidget("text");

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    bind("<Button-4>",
	 sub{
	   $GUI{Chat}->{$tag}->{ChatText}->{Text}->
	     yviewScroll(-1,"units");
	 });
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    bind("<Button-5>",
	 sub{
	   $GUI{Chat}->{$tag}->{ChatText}->{Text}->
	     yviewScroll(1,"units");
	 });

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    bind("<Configure>",
	 sub {
	   $GUI{Chat}->{$tag}->{ChatText}->{Text}->
	     see("end");
	 }
	);

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("server",
		 -foreground=>"green4");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("me",
		 -foreground=>"red");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("notme",
		 -foreground=>"blue");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("highlight",
		 -foreground=>"red");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("timestamp",
		 -foreground=>"gray30");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("action",
		 -foreground=>"purple");
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagConfigure("link",
		 -foreground=>"blue",
		 -font=>$GUI{fonts}->{link});

  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagBind("link",
	    "<Enter>",
	    sub{
	      $GUI{Chat}->{$tag}->{ChatText}->{Text}->
		configure(-cursor=>"hand2");
	    });
  $GUI{Chat}->{$tag}->{ChatText}->{Text}->
    tagBind("link",
	    "<Leave>",
	    sub{
	      $GUI{Chat}->{$tag}->{ChatText}->{Text}->
		configure(-cursor=>"xterm");
	    });

  $GUI{Chat}->{$tag}->{Say}->{top} =
    $GUI{Chat}->{$tag}->{top}->
      Frame(-background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
	    -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	   )->pack(-side=>"top",
		   -fill=>"x",
		   -padx=>5);
  $GUI{Chat}->{$tag}->{Say}->{Label} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Label(-text=>"Say:",
	    -anchor=>"e",
	    -font=>$GUI{fonts}->{normal},
	    -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	    -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal}
	   )->pack(-side=>"left",
		   -fill=>"y",
		   -anchor=>"e");
  $GUI{Chat}->{$tag}->{Say}->{Entry} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Entry(-textvariable=>\$GUI{Chat}->{$tag}->{vars}->{body},
	    -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{light},
	    -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	    -font=>$GUI{fonts}->{normal},
	   )->pack(-side=>'left',
		   -fill=>"x",
		   -expand=>1,
		   -anchor=>'w');

  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<Key-Up>", sub{
	   &jarlChatIF_CurrentSay($tag,&jarlChat_HistoryUp($tag));
	 });

  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<Key-Down>", sub{
	   &jarlChatIF_CurrentSay($tag,&jarlChat_HistoryDown($tag));
	 });

  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<Return>",sub{
	   &jarlChat_SendSay($tag);
	 });

  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<Map>",sub{
	   $GUI{Chat}->{$tag}->{Say}->{Entry}->focus();
	   $GUI{Chat}->{$tag}->{ChatText}->{Text}->see("end");
	 });

  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<Tab>",sub{
	   $GUI{Chat}->{$tag}->{vars}->{tab} = 1;
	   &jarlChat_CompleteNick($tag);
	 });
  $GUI{Chat}->{$tag}->{Say}->{Entry}->
    bind("<FocusOut>",sub{
	   $GUI{Chat}->{$tag}->{vars}->{tab} = 0
	     unless exists($GUI{Chat}->{$tag}->{vars}->{tab});
	   if ($GUI{Chat}->{$tag}->{vars}->{tab} == 1) {
	     $GUI{Chat}->{$tag}->{vars}->{tab} = 0;
	     $GUI{Chat}->{$tag}->{Say}->{Entry}->focus();
	   }
	 }
	);

  $GUI{Chat}->{$tag}->{Say}->{Leave} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Button(-image=>$GUI{Icons}->{Leave},
	     -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
	     -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       &jarlChat_Leave($tag);
	       $TabBar->DeleteTab($tag);
	       delete($GUI{Chat}->{$tag});
	     }
	    )->pack(-side=>"right");
  &jarlMainIF_RegisterIcon($GUI{Chat}->{$tag}->{Say}->{Leave},
			 "Leave");
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Chat}->{$tag}->{Say}->{Leave},
	   -balloonmsg=>"Exit Chat ");

  $GUI{Chat}->{$tag}->{Say}->{Clear} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Button(-image=>$GUI{Icons}->{Clear},
	     -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
	     -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       $GUI{Chat}->{$tag}->{ChatText}->{Text}->
		 configure(state=>"normal");
	       $GUI{Chat}->{$tag}->{ChatText}->{Text}->
		 delete("1.0","end");
	       $GUI{Chat}->{$tag}->{ChatText}->{Text}->
		 configure(state=>"disabled");
	       $GUI{Chat}->{$tag}->{vars}->{neednewline} = 0;
	     }
	    )->pack(-side=>"right");
  &jarlMainIF_RegisterIcon($GUI{Chat}->{$tag}->{Say}->{Clear},
			 "Clear");
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Chat}->{$tag}->{Say}->{Clear},
	   -balloonmsg=>"Clear the Chat ");

  $GUI{Chat}->{$tag}->{Say}->{SXPM} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Button(-image=>$GUI{Icons}->{Clear},
	     -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
	     -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{
	       my $sxpmMessage =
		 $jabber{client}->
		   SXPMSend(to=>&jarlChat_JID($tag),
			    type=>"chat",
			    boardheight=>500,
			    boardwidth=>500,
			    map=>{ '#'=>'',
				   ' '=>'None',
				   'a'=>'#000000',
				   'b'=>'#FF0000',
				   'c'=>'#00FF00',
				   'd'=>'#0000FF' },
			   );
	       &jarlChat_AddMessage(&jarlChat_JID($tag),$sxpmMessage);
	     }
	    )->pack(-side=>"right");
  &jarlMainIF_RegisterIcon($GUI{Chat}->{$tag}->{Say}->{SXPM},
			   "Clear");
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Chat}->{$tag}->{Say}->{SXPM},
	   -balloonmsg=>"Exchange SXPM with this User ");

  $GUI{Chat}->{$tag}->{Say}->{Secure} =
    $GUI{Chat}->{$tag}->{Say}->{top}->
      Button(-image=>((&jarlChat_Secure($tag) == 1) ?
		      $GUI{Icons}->{SecureOn} :
		      $GUI{Icons}->{SecureOff}),
	     -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
	     -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
	     -disabledforeground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{light},
	     -font=>$GUI{fonts}->{normal},
	     -command=>sub{

	       if (&jarlChat_Secure($tag) == 0) {
		 &jarlChat_UserSecure($tag,1);
		 &jarlChat_SecureChat(&jarlChat_JID($tag));
	       } else {
		 &jarlChat_UserSecure($tag,0);
		 &jarlChat_UnsecureChat(&jarlChat_JID($tag));
	       }
	     }
	    )->pack(-side=>"right");
  &jarlMainIF_RegisterIcon($GUI{Chat}->{$tag}->{Say}->{Secure},
			   ((&jarlChat_Secure($tag) == 1) ?
			    "SecureOn" :
			    "SecureOff"));
  $GUI{ToolBar}->{Balloon}->
    attach($GUI{Chat}->{$tag}->{Say}->{Secure},
	   -balloonmsg=>"Secure/Unsecure the Chat ");


  $GUI{Chat}->{$tag}->{top}->bell();
}


##############################################################################
#
# jarlChatIF_CurrentSay - if $value is defined then the Entry contents are set
#                         to $value, otherwise the contents of the Entry are
#                         returned.
#
##############################################################################
sub jarlChatIF_CurrentSay {
  my ($tag,$value) =  @_;
  $Debug->Log3("jarlChatIF_CurrentSay: tag($tag) value($value)");
  if (defined($value)) {
    $Debug->Log3("jarlChatIF_CurrentSay: set the entry to value($value)");
    $GUI{Chat}->{$tag}->{Say}->{Entry}->delete(0,"end");
    $GUI{Chat}->{$tag}->{Say}->{Entry}->insert(0,$value);
    $GUI{Chat}->{$tag}->{Say}->{Entry}->icursor("end");
    $GUI{Chat}->{$tag}->{Say}->{Entry}->xview(0);
    return;
  }
  $Debug->Log3("jarlChatIF_CurrentSay: return(".$GUI{Chat}->{$tag}->{Say}->{Entry}->get().")");
  return $GUI{Chat}->{$tag}->{Say}->{Entry}->get();
}


##############################################################################
#
# jarlChatIF_Secure - if $value is not defined then it returns 1 if the chat
#                     is secure, and 0 if not.  Otherwise, it sets the
#                     security of the chat to the $value (0 or 1 only).
#
##############################################################################
sub jarlChatIF_Secure {
  my ($tag,$value) = @_;

  &jarlMainIF_ChangeIcon($GUI{Chat}->{$tag}->{Say}->{Secure},
			 (($value == 1) ? "SecureOn" : "SecureOff"),
			 (($value == 1) ? "SecureOff" : "SecureOn"),
			);
}


1;
