##############################################################################
#
# Jarl - Normal Code
#
#   Perl code to handle creating, sending, storing, and whatever else with
# messages of type normal.
#
##############################################################################

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

##############################################################################
#
# jarlNormal_AddMessage - add the specified message into memory
#
##############################################################################
sub jarlNormal_AddMessage {
  my ($message,$type) = @_;

  $type = "normal" unless defined($type);

  if (ref($message) eq "Net::Jabber::Message") {
    if ($message->DefinedBody()) {

      my $sender = $message->GetFrom("jid")->GetJID();
      ($sender = $Roster->GetValue($sender,"name"))
	if ($Roster->GetValue($sender,"name") ne "");

      my $time;
      my @xDelays = $message->GetX("jabber:x:delay");
      if ($#xDelays == -1) {
	$time = time;
      } else {
	my $xTag = $xDelays[0];
	$time = &Net::Jabber::GetTimeStamp("utcdelaytime",$xTag->GetStamp(),"long");
      }
      my $timestamp = &Net::Jabber::GetTimeStamp("local",$time,"long");

      my $body = $message->GetBody();
      my $subject = $message->GetSubject();
      my $encrypted = 0;
      my @xEncrypted = $message->GetX("jabber:x:encrypted");
      if ($#xEncrypted > -1) {
	if (($config{gpg}->{active} == 1) && ($fromMe == 0)) {
	  $body = &jarlGPG_DecryptMessage($config{gpg}->{passphrase},
					  $xEncrypted[0]->GetMessage());
	}
	$encrypted = 1;
      }

      my @body = &jarlParser_ParseText($body,$jabber{myJID}->GetUserID());

      my $mid = &jarlMain_GetUID();
      $normal{messages}->{$mid} = {
				   type=>$type,
				   sender=>$sender,
				   date=>$timestamp,
				   time=>$time,
				   encrypted=>$encrypted,
				   subject=>$subject,
				   body=>\@body
				  };
      &jarlNormal_JID($mid,$message->GetFrom("jid")) if ($type eq "normal");
      &jarlNormal_Message($mid,$message) if ($type eq "normal");

      &jarlNormalIF_AddMessage($mid,%{$normal{messages}->{$mid}});
    }

    &jarlMainIF_AlertUser();
  }
}


##############################################################################
#
# jarlNormal_DeleteMessage - delete the message from memory.
#
##############################################################################
sub jarlNormal_DeleteMessage {
  my (@mids) = @_;

  foreach my $mid (@mids) {
    delete($normal{messages}->{$mid});
  }

  &jarlNormalIF_DeleteMessage(@mids);
}


##############################################################################
#
# jarlNormal_Message - if $value is not defined then it returns the message.
#                      Otherwise, it sets the message.
#
##############################################################################
sub jarlNormal_Message {
  my ($tag,$value) = @_;
  if (defined($value)) {
    $normal{mids}->{$tag}->{message} = $value;
  } else {
    return unless exists($normal{mids}->{$tag}->{message});
    return $normal{mids}->{$tag}->{message};
  }
}


##############################################################################
#
# jarlNormal_JID - if $value is not defined then it returns the jid.
#                   Otherwise, it sets the jid.
#
##############################################################################
sub jarlNormal_JID {
  my ($tag,$value) = @_;
  if (defined($value)) {
    $normal{mids}->{$tag}->{jid} = $value;
  } else {
    return $normal{mids}->{$tag}->{jid};
  }
}


##############################################################################
#
# jarlNormal_NormalID - if $value is not defined then it returns the jid.
#                       Otherwise, it sets the jid.
#
##############################################################################
sub jarlNormal_NormalID {
  my ($tag,$value) = @_;
  if (defined($value)) {
    $normal{mids}->{$tag}->{normalid} = $value;
  } else {
    return $normal{mids}->{$tag}->{normalid};
  }
}


##############################################################################
#
# jarlNormal_Secure - if $value is not defined then it returns 1 if the
#                      message is secure, and 0 if not.  Otherwise, it sets
#                      the security of the message to the $value (0 or 1
#                      only).
#
##############################################################################
sub jarlNormal_Secure {
  my ($tag,$value) = @_;
  if (defined($value)) {
    $normal{mids}->{$tag}->{secure} = $value;
    &jarlNormalIF_Secure($tag,$value);
  } else {
    return $normal{mids}->{$tag}->{secure};
  }
}


##############################################################################
#
# jarlNormal_UserSecure - if $value is not defined then it returns 1 if the
#                          message is secure, and 0 if not.  Otherwise, it
#                          sets the security of the message to the $value (0
#                          or 1 only).
#
##############################################################################
sub jarlNormal_UserSecure {
  my ($tag,$value) = @_;
  if (defined($value)) {
    $normal{mids}->{$tag}->{usersecure} = $value;
  } else {
    return $normal{mids}->{$tag}->{usersecure};
  }
}


##############################################################################
#
# jarlNormal_SecureMessage - make the message with the specified JID secure
#                             (if possible)
#
##############################################################################
sub jarlNormal_SecureMessage {
  my ($tag) = @_;

  $Debug->Log3("jarlNormal_SecureMessage: tag($tag)");

  my $JID = &jarlNormal_JID($tag)->GetJID();

  $Debug->Log3("jarlNormal_SecureMessage: JID($JID) usersecure(".&jarlNormal_UserSecure($tag).")");

  return if (&jarlNormal_UserSecure($tag) == 0);

  my $pubKey = $Roster->GetValue($JID,"gpgkeyid");

  $Debug->Log3("jarlNormal_SecureMessage: pubKey($pubKey)");

  &jarlGPG_FetchAndTrustKey($pubKey)
    if (defined($pubKey) &&
	(&jarlGPG_CheckKeyRing($pubKey) == 0) &&
	($config{gpg}->{autofetchtrust} == 1));

  my $secure = 1
    if (($config{gpg}->{active} == 1) &&
	defined($pubKey) &&
	&jarlGPG_CheckKeyRing($pubKey) == 1);

  $Debug->Log3("jarlNormal_SecureMessage: secure?($secure)");

  if ($secure == 0) {
    return if (&jarlNormal_Secure($tag) == 0);
    &jarlNormal_UnsecureMessage($fromJID);
    return;
  }

  return if &jarlNormal_Secure($tag);

  &jarlNormal_Secure($tag,1);
}


##############################################################################
#
# jarlNormal_UnsecureMessage - make the message with the specified tag
#                               unsecure
#
##############################################################################
sub jarlNormal_UnsecureMessage {
  my ($tag) = @_;

  &jarlNormal_Secure($tag,0);
}


##############################################################################
#
# jarlNormal_Send - send the current message.
#
##############################################################################
sub jarlNormal_Send {
  my ($mid) = @_;

  my $subject = &jarlNormalIF_CurrentSubject($mid);
  my $body = &jarlNormalIF_CurrentBody($mid);

  &jarlNormal_Message($mid)->SetMessage(to=>&jarlNormalIF_CurrentTo($mid));

  if (&jarlNormal_Secure($mid) == 0) {
    &jarlNormal_Message($mid)->SetMessage(subject=>$subject,
					  body=>$body);
  } else {
    &jarlNormal_Message($mid)->SetMessage(subject=>$subject,
					body=>"This message is encrypted.");

    my $pubKey =
      $Roster->GetValue(&jarlNormal_JID($mid)->GetJID(),"gpgkeyid");
    my $xEncrypted = &jarlNormal_Message($mid)->NewX("jabber:x:encrypted");
    $xEncrypted->SetEncrypted(message=>&jarlGPG_EncryptMessage($config{gpg}->{passphrase},$pubKey,$body));
  }
  $jabber{client}->Send(&jarlNormal_Message($mid));
}


##############################################################################
#
# jarlNormal_Compose - compose a new message.  If a message id is specified
#                      then make this a reply to that message, otherwise
#                      start a brand spanking new message.
#
##############################################################################
sub jarlNormal_Compose {
  my $type = shift;
  my $replymid;
  my $toJID;
  my $message;

  if ($type eq "reply") {
    $replymid = shift;
    $message = &jarlNormal_Message($replymid)->Reply();
    $toJID = $message->GetTo("jid");
  }
  if ($type eq "new") {
    $toJID = shift;
    $toJID = new Net::Jabber::JID($toJID)
      unless (ref($toJID) eq "Net::Jabber::JID");
    $message = new Net::Jabber::Message();
  }

  my $normalID = $Roster->GetValue($toJID->GetJID(),"name");
  $normalID = $toJID->GetUserID()
    if (!defined($normalID) || ($normalID eq ""));

  my $mid = &jarlMain_GetUID();
  &jarlNormal_Message($mid,$message);
  &jarlNormal_NormalID($mid,$normalID);
  &jarlNormal_JID($mid,&jarlNormal_JID($replymid)) if ($type eq "reply");
  &jarlNormal_JID($mid,$toJID) if ($type eq "new");

  &jarlNormalIF_NewNormal($mid);
  &jarlNormalIF_CurrentTo($mid,$toJID);
  &jarlNormalIF_CurrentSubject($mid,&jarlNormal_Message($mid)->GetSubject());
  &jarlNormalIF_CurrentBody($mid,&jarlNormal_Message($mid)->GetBody());
}


##############################################################################
#
# jarlNormal_DeleteNormal - delete the memory taken up by this normal
#                             session.
#
##############################################################################
sub jarlNormal_DeleteNormal {
  my ($mid) = @_;

  foreach my $jid (keys(%{$normal{jids}})) {
    delete($normal{jids}->{$jid}) if ($normal{jids}->{$jid} eq $mid);
  }
  delete($normal{mids}->{$mid});
}


1;
