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

package Jarl::Presence;

use strict;
use vars qw($VERSION);


$VERSION = "0.1";

sub new {
  my $proto = shift;
  my $self = { };

  $self->{PRESENCE} = {};

  bless($self, $proto);

  if ($#_ > -1) {
    $self->Set(@_);
  }

  return $self;
}


sub Set {
  my $self = shift;
  my (%args) = @_;
  $self->Nick(delete($args{nick})) if exists($args{nick});
  $self->Unified(delete($args{unified})) if exists($args{unified});
  $self->Channel(delete($args{channel})) if exists($args{channel});
  $args{type} = "available" unless exists($args{type});
  $args{show} = "" unless exists($args{show});
  $args{new} = 0 unless exists($args{new});
  my $new = delete($args{new});

  if (scalar(keys(%args)) > 0) {
    if (("$args{type}" eq "unavailable") && ($self->Channel() eq "")) {
      foreach my $group (keys(%{$self->{GROUPCHAT}})) {
	$self->DelGroupchat($group);
      }
    }
    $self->Type("$args{type}");
    $self->Show("$args{show}");
    $self->Status("$args{status}");
    $self->Priority($args{priority}) if exists($args{priority});
  }

  $self->PresenceSend($new);
}


sub Unified {
  my $self = shift;
  my ($unifiedObj) = @_;
  $self->{PRESENCE}->{unified} = $unifiedObj if defined($unifiedObj);
  $main::config{unifiedpresence} = 1
    unless exists($main::config{unifiedpresence});
  return if ($main::config{unifiedpresence} == 0);
  return $self->{PRESENCE}->{unified} if exists($self->{PRESENCE}->{unified});
  return;
}


sub DelUnified {
  my $self = shift;
  $self->{PRESENCE}->{unified} = undef;
}


sub Type {
  my $self = shift;
  my ($type) = @_;
  $self->{PRESENCE}->{type} = $type if defined($type);
  return $self->Unified()->Type($type) if defined($self->Unified());
  return $self->{PRESENCE}->{type};
}


sub Show {
  my $self = shift;
  my ($show) = @_;
  $self->{PRESENCE}->{show} = $show if defined($show);
  return $self->Unified()->Show($show) if defined($self->Unified());
  return $self->{PRESENCE}->{show};
}


sub Status {
  my $self = shift;
  my ($status) = @_;
  $self->{PRESENCE}->{status} = $status if defined($status);
  return $self->Unified()->Status($status) if defined($self->Unified());
  return (($self->{PRESENCE}->{status} ne "") ? 
	  $self->{PRESENCE}->{status} :
	  "Online");
}


sub Priority {
  my $self = shift;
  my ($priority) = @_;
  $self->{PRESENCE}->{priority} = $priority if defined($priority);
  return $self->Unified()->Priority($priority) if defined($self->Unified());
  return $self->{PRESENCE}->{priority} if exists($self->{PRESENCE}->{priority});
  return 0;
}


sub Channel {
  my $self = shift;
  my ($channel) = @_;
  $self->{PRESENCE}->{channel} = $channel if defined($channel);
  return $self->{PRESENCE}->{channel} if exists($self->{PRESENCE}->{channel});
  return "";
}


sub Nick {
  my $self = shift;
  my ($nick) = @_;
  $self->{PRESENCE}->{nick} = $nick if defined($nick);
  return $self->{PRESENCE}->{nick} if exists($self->{PRESENCE}->{nick});
  return "";
}


sub ReconnectPresenceSend {
  my $self = shift;
  my ($ignoreunified) = @_;

  $main::config{gpg}->{active} = 0
    unless exists($main::config{gpg}->{active});
  $main::config{gpg}->{passphrase} = ""
    unless exists($main::config{gpg}->{passphrase});

  &main::jarlGPGIF_PromptPassphrase()
    if (($main::config{gpg}->{active} == 1) &&
	($main::config{gpg}->{passphrase} eq ""));

  while(($main::config{gpg}->{passphrase} eq "") &&
	($main::config{gpg}->{active} == 1)) {
    select(undef,undef,undef,.1);
    &main::jarlMainIF_Update();
  }

  $ignoreunified = 0 unless defined($ignoreunified);

  return $self->Unified()->ReconnectPresenceSend() if (($ignoreunified == 0) &&
						    defined($self->Unified()));

  if ($main::jabber{connected} == 1) {
    $main::jabber{client}->
      PresenceSend((
		    ($self->Channel() ne "") ?
		    (to=>$self->Channel()."/".$self->Nick()) :
		    ()
		   ),
		   type=>"unavailable",
		  );
    my $presence =
      $main::jabber{client}->
	PresenceSend((
		      ($self->Channel() ne "") ?
		      (to=>$self->Channel()."/".$self->Nick()) :
		      ()
		     ),
		     (
		      (($self->Type() ne "available") && ($self->Type() ne "")) ?
		      (type=>$self->Type()) :
		      ()
		     ),
		     (
		      ($self->Show() ne "") ?
		      (show=>$self->Show()) :
		      ()
		     ),
		     (
		      ($self->Status() ne "") ?
		      (status=>$self->Status()) :
		      ()
		     ),
		     (
		      ($self->Priority() ne "") ?
		      (priority=>$self->Priority()) :
		      ()
		     ),
		     (
		      ($main::config{gpg}->{active} == 1) ?
		      (signature=>&main::jarlGPG_SignStatus($main::config{gpg}->{passphrase},$self->Status())) :
		      ()
		     ),
		    );
    &main::jarlMainIF_StatusBarChangePresence($presence)
      if ($self->Channel() eq "");
  }

  if ($main::config{unifiedpresence} == 1) {
    foreach my $group (keys(%{$self->{GROUPCHAT}})) {
      $self->{GROUPCHAT}->{$group}->ReconnectPresenceSend(1);
    }
  }
}


sub PresenceSend {
  my $self = shift;
  my ($ignoreunified) = @_;

  $main::config{gpg}->{active} = 0
    unless exists($main::config{gpg}->{active});
  $main::config{gpg}->{passphrase} = ""
    unless exists($main::config{gpg}->{passphrase});

  &main::jarlGPGIF_PromptPassphrase()
    if (($main::config{gpg}->{active} == 1) &&
	($main::config{gpg}->{passphrase} eq ""));

  while(($main::config{gpg}->{passphrase} eq "") &&
	($main::config{gpg}->{active} == 1)) {
    select(undef,undef,undef,.1);
    &main::jarlMainIF_Update();
  }

  $ignoreunified = 0 unless defined($ignoreunified);

  return $self->Unified()->PresenceSend() if (($ignoreunified == 0) &&
					      defined($self->Unified()));

  $main::jabber{connected} = 0 unless exists($main::jabber{connected});
  if ($main::jabber{connected} == 1) {
    my $presence =
      $main::jabber{client}->
	PresenceSend((
		      ($self->Channel() ne "") ?
		      (to=>$self->Channel()."/".$self->Nick()) :
		      ()
		     ),
		     (
		      (($self->Type() ne "available") && ($self->Type() ne "")) ?
		      (type=>$self->Type()) :
		      ()
		     ),
		     (
		      ($self->Show() ne "") ?
		      (show=>$self->Show()) :
		      ()
		     ),
		     (
		      ($self->Status() ne "") ?
		      (status=>$self->Status()) :
		      ()
		     ),
		     (
		      ($self->Priority() ne "") ?
		      (priority=>$self->Priority()) :
		      ()
		     ),
		     (
		      ($main::config{gpg}->{active} == 1) ?
		      (signature=>&main::jarlGPG_SignStatus($main::config{gpg}->{passphrase},$self->Status())) :
		      ()
		     ),
		    );
    &main::jarlMainIF_StatusBarChangePresence($presence)
      if ($self->Channel() eq "");
  }

  if ($main::config{unifiedpresence} == 1) {
    foreach my $group (keys(%{$self->{GROUPCHAT}})) {
      $self->{GROUPCHAT}->{$group}->PresenceSend(1);
    }
  }
}


sub AddGroupchat {
  my $self = shift;
  my ($jid,$nick) = @_;

  $self->{GROUPCHAT}->{$jid} =
    new Jarl::Presence(unified=>$self,
		       channel=>$jid,
		       nick=>$nick,
		       new=>1);
  return $self->{GROUPCHAT}->{$jid};
}


sub ModGroupchat {
  my $self = shift;
  my $jid = shift;
  $self->{GROUPCHAT}->{$jid}->Set(@_);
}


sub DelGroupchat {
  my $self = shift;
  my ($jid) = @_;
  
  return unless exists($self->{GROUPCHAT}->{$jid});

  $self->{GROUPCHAT}->{$jid}->DelUnified();
  $self->{GROUPCHAT}->{$jid}->Set(type=>"unavailable");
  delete($self->{GROUPCHAT}->{$jid});
}


sub ReconnectGroupchat {
  my $self = shift;
  my ($jid) = @_;
  
  $self->{GROUPCHAT}->{$jid}->ReconnectPresenceSend(1);
}


1;
