# -*- Perl -*-
#
# This is part of X-RUST 1.0 Beta 4
#
# Copyright (C) 1996 Craig Ruefenacht <ruefenac@cs.utah.edu> and the
#                    University of Utah, Department of Computer Scinece
#
#                    Shawn T. Amundson <amundson@cs.umn.edu> and the
#                    University of Minnesota Computer Science Department
#
# Abstract:  Take care of everything conserning mail for XRust.
#
# 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
# 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 the source distribution of RUST, in the license
# directory. If you don't have a copy of it, write to: 
#
# Free Software Foundation, Inc.
# 675 Mass Ave
# Cambridge, MA 02139, USA.
#

#
# $Id: Mail.pm,v 1.4 1997/05/21 15:12:24 ruefenac Exp $
#

package XRust::Mail;

use strict;
use vars qw(@ISA @EXPORT);

require Exporter;

@ISA = qw(Exporter);
@EXPORT = (
	  );

my $BREAKLINE = "--text follows this line--";

sub new {
    my $type = shift;
    my $queue_name = shift;
    my $request_num = shift;
    my $geometry = shift;
    my $text_font = shift;
    my $button_font = shift;
    my $config_sigfile = shift;
    my $xrust_password = shift;

    my $self = {};
    bless $self;

    $self->{'queue_name'} = $queue_name;
    $self->{'request_num'} = $request_num;

    $self->create_window($geometry, $text_font, $button_font, $config_sigfile, $xrust_password);

    $self;

}

sub create_window {
    my $self = shift;
    my $geometry = shift;
    my $text_font = shift;
    my $button_font = shift;
    my $config_sigfile = shift;
    my $xrust_password = shift;

    my $queue_name = $self->{'queue_name'};
    my $request_num = $self->{'request_num'};

    my $MW = MainWindow->new;
    $MW->geometry($geometry);
    $MW->title('Xrust Mail');

    $self->{'_window'} = $MW;


    #
    # ***** TEXT Widget STUFF *****
    #

    my $text_frame = $MW->Frame;
    $text_frame->pack(
		      -side => 'top',
		      -padx => 2,
		      -pady => 2,
		      -expand =>1
		      );

    my $vert_scroll = $text_frame->Scrollbar(
					     -orient => 'vertical'
					    );

    my $text = $text_frame->Text(
				 -yscrollcommand =>  [$vert_scroll => 'set'],
				 -width          => 80,
				 -height         => 25, 
				 -wrap           => 'none',
				 -setgrid        => 1,
				 -font           => $text_font
				);

	
    $vert_scroll->configure(-command => [$text => 'yview']);

    $vert_scroll->pack(
		       -side => 'right',
		       -fill => 'y'
		       );
    $text->pack(
		-expand => 1, 
		-fill => 'both'
	       );

    $self->{'_text'} = $text;

    $self->add_headers($xrust_password);

    $text->insert('current',"$BREAKLINE\n");

    $self->add_signature($config_sigfile);


    my $buttonbar = $MW->Frame;
    $buttonbar->pack(
		     -fill => 'x',
		     -side => 'top',
		     -padx => 2,
		     -pady => 2
		    );
    
    my $button_width = 10;
    my $send = $buttonbar->Button(
				  -text => 'Send',
				  -font => $button_font,
				  -width => $button_width,
				  -command => sub {
				      my $error;
				      my $mesg;
				      my $window = $self->{'_window'};
				      ($error,$mesg) = $self->send_mail;
				      if ($error) {
					  print STDERR "ERROR: $error, $mesg\n";
				      } else {
					  $window->destroy;
				      };
				  }
				 );
    $send->pack(
		-side => 'left'
		);

    my $resolve = $buttonbar->Button(
				  -text => 'Resolve',
				  -font => $button_font,
				  -width => $button_width,
				  -command => sub {
				      $text->delete("4.0","5.0");
				      $text->insert("4.0","X-Rust: resolve\n");
				  }
				 );
    $resolve->pack(
		   -side => 'left'
		   );

    my $yank_text = $buttonbar->Button(
					-text => 'Yank (Ctl-Y)',
					-font => $button_font,
					-width => $button_width,
					-command => sub {
					    my ($clip_text) = $text->SelectionGet;
					    &yank_text($clip_text, $text, 1);
					}
					);

    $yank_text->pack(
		   -side => 'left'
		   );


    my $clear_text = $buttonbar->Button(
					-text => 'Clear',
					-font => $button_font,
					-width => $button_width,
					-command => sub {
					    $text->delete("8.0", "end");
					    $self->add_signature($config_sigfile);
					}
					);

    $clear_text->pack(
		   -side => 'left'
		   );

    my $cancel = $buttonbar->Button(
				    -text => 'Cancel',
				    -font => $button_font,
				    -width => $button_width,
				    -command => sub {
					my $window = $self->{'_window'};
					$window->destroy;
				    }
				   );
    $cancel->pack(
		-side => 'right'
		);

    $text->bind('<Control-y>', sub { 
	my ($clip_text) = $text->SelectionGet;
	&yank_text($clip_text, $text, 1);
    }
		);

    $text->bind('<Control-m>', sub { 
	my ($clip_text) = $text->SelectionGet;
	&yank_text($clip_text, $text, 0);
    }
		);

}

sub add_headers {
    my $self = shift;
    my $xrust_password = shift;
    my $text = $self->{'_text'};

    my $queue_name = $self->{'queue_name'};
    my $request_num = $self->{'request_num'};

    my $to_field      = &get_header('To:',$queue_name,$request_num);
    my $subject_field = &get_header('Subject:',$queue_name,$request_num);
    my $cc_field      = &get_header('CC:',$queue_name,$request_num);

    $text->insert('current',"To: $to_field\n");
    $text->insert('current',"CC: $cc_field\n");
    $text->insert('current',"X-Rust-Password: $xrust_password\n");
    $text->insert('current',"X-Rust:\n");
    $text->insert('current',"Subject: $subject_field\n");

}


sub add_signature {

    my $self = shift;
    my $config_sigfile = shift;
    my $text = $self->{'_text'};
    
    my $sigfile = $ENV{'HOME'} . "/.xrust_sig";

    if (!(-f $sigfile)) {
	$sigfile = $ENV{'HOME'} . "/$config_sigfile";
    }

    if (-f $sigfile && -r $sigfile) {
	open(SIG,$sigfile) || warn "Could not open signature file, but it exists.\n";
	$text->insert('current',"\n");
	while(<SIG>) {
	    $text->insert('current',$_);
	}
	close(SIG);
    }


}

sub get_header {

    my $header = shift;
    my $queue_name = shift;
    my $request_num = shift;
    my $value = "";
    my @array;
    my $prefix;
    
    my $queue_index = Rust_Lib::set_queue_index(0, $queue_name);

    if ($header eq 'To:') {
	@array = split(/:/,$main::globals->{'alias_email_addr'});
	$value = $array[$queue_index];
    }
    if ($header eq 'Subject:') {
	@array = split(/:/,$main::globals->{'tag'});
	$value = $main::REQUESTS{$queue_name}->{$request_num}->{'subject'};
	$value = sprintf($array[$queue_index],$request_num,$value);
	$value = "Re: " . $value;
    }

    return $value;

}

sub send_mail {

    my $self = shift;

    my $sendmail = $main::BIN{'sendmail'};

    #
    # Error Codes
    #
    my @errors;
    $errors[0] = "Mail sent";
    $errors[1] = "Couldn't get headers of message!";
    $errors[2] = "Couldn't get body of message!";
    $errors[3] = "Couldn't open sendmail: $sendmail";
    $errors[4] = "Couldn't find ^$BREAKLINE";

    my $breakline = $self->get_breakline;
    if ($breakline < 0) {
	return (4,$errors[4]);
    }

    my $error;
    my ($error, @headers) = $self->get_headers;
    return ($error,$errors[$error]) if ($error);

    my ($error, @body)    = $self->get_body;
    return ($error,$errors[$error]) if ($error);

    $error = open (SENDMAIL,"| $sendmail");
    if (!$error) {
	return (3,$errors[3]);
    }

    foreach (@headers) {
	print SENDMAIL $_;
    }

    print SENDMAIL $_;

    print SENDMAIL "\n";  

    foreach (@body) {
	print SENDMAIL $_;
    }

    close(SENDMAIL);

    return (0,$errors[0]);
}


sub get_headers {

    my $self = shift;
    my $breakline = $self->get_breakline;
    if ($breakline < 0) {
	return 4;
    }

    my $text = $self->{'_text'};
    my @headers = $text->get("0.0","$breakline.0");

    return (0, @headers);

}

sub get_body {

    my $self = shift;
    my $breakline = $self->get_breakline;
    if ($breakline < 0) {
	return 4;
    }

    my $text = $self->{'_text'};
    my $firstline = $breakline + 1;

    my @body = $text->get("$firstline.0","end");

    return (0, @body);

}

sub get_breakline {

    my $self = shift;
    
    my $text = $self->{'_text'};
    my $breakline;

    my $index = $text->search(-regexp, "--","^$BREAKLINE", "0.0");

    if ($index eq "") {
	return -1;
    }

    return int($index);

}

sub yank_text {

    my $clip_text = shift;
    my $text = shift;
    my $inc_mark = shift;

    my ($insert_text);
    my (@text_lines) = split(/\n/, $clip_text);
    my (@yank_text, $each_line, $new_line, $insert_string);

#    foreach $each_line (@text_lines) {
#	print "A line is $each_line and that is that\n";
#	if (!($each_line)) {
#	    print "That was a blank line...\n";
#	}
#    }

    foreach $each_line (@text_lines) {
#	print "Now processing the line with $each_line as text\n";
	if ($inc_mark == 1) {
	    if (!($each_line)) {
#		print "Found a blank line\n";
		$new_line = "> \n";
	    } else {
		$new_line = ">  $each_line\n";
	    }
	} else {
	    if (!($each_line)) {
#		print "Found a blank line\n";
		$new_line = "%> \n";
	    } else {
		$new_line = "%>  $each_line\n";
	    }
	}
#	print "Pusing onto yank_text: $new_line";
	push(@yank_text, $new_line);
    }


    $insert_string = join('',@yank_text);
    $text->insert("insert",$insert_string);
}


1;


