# $Id: Compose.pm,v 1.11 2001/04/14 03:54:09 muhri Exp $
# -*- perl -*-
package Pronto::Compose;
use strict;
use Lingua::Ispell;
use Text::ParseWords;
use SelfLoader;
my $spellstarted = 0;
my $last_dir = undef;
1;
__DATA__
sub init_msg_window {
	my ($vbox, $toolbar, $tb_item1, $tb_item2, $tb_item3, $tb_item4, $tb_item5, $hbox1, $hbox5, $scrollwin, $scrollbar, $window, $bg, $accel_group, $msg_window, $i, @entry, $textbox, $from_combo, @poplist,@msgbody, $from_label, $msglbl, @frmlabels, $sql, $query, @row, $default, $sigid, $pgp_hbox, $pgp_enc_togg, $pgp_sign_tog, $pgp_keycheck_tog, $width, $height, $spell_window);
	my @fields = ("","","","");
	my ($widget, $data, $fildref, $msgid, $actid, $forrep) = @_;
	# i inserted a hack for the fields, so the interface to send_mail does not change for the bcc field as field #2 (the ex-to field) is now bcc
	if ($fildref) { @fields = @$fildref; $fields[3]=$fields[2];$fields[2]="";}
	my (@attachments);
	my ($rcptcheck,$optbox,$priocombo);
	my @priolist=(_("1 (Highest)"),_("2 (High)"),_("3 (Normal)"),
			_("4 (Low)"),_("5 (Lowest)"));
	my $priodefault=_("3 (Normal)");
	my ($notebook, $nbox1, $nbox2);
	my ($smenu, $sm_message, $smm_menu, $sm_options, $smo_menu, $sm_sep, $sm_help, $hmm_help);
	my $font = Gtk::Gdk::Font->load($main::prefs{'FontComposer'}); 
	if ($main::prefs{'useGtkFontComposer'} eq "y") { $font = "" }
	$sql = "select descr, def,id from accounts";
	$query=$main::conn->prepare($sql);
	$query->execute();
	$i = 0;
	while (@row=$query->fetchrow_array()) {
		$poplist[$i] = $row[0];
		if (($row[1] eq "y") and (!$actid)) {
			$default = $row[0];
			$sigid = $row[2];
		}
		if (($actid) and ($row[2] == $actid)) {
			$default = $row[0];
			$sigid = $row[2];
		}
		$i++;
	}

	$msg_window = new Gtk::Window("toplevel");
	$msg_window->position(-mouse);
	$msg_window->set_title(_("Compose Message"));
	$msg_window->signal_connect("delete_event" => 
		sub {
			if(defined $spell_window) {
				$spell_window->destroy;
				undef $spell_window;
			}
			Gtk::false;
		});
        ($width,$height) = &main::get_win_size("MsgWinstartUp",500,540);
       	$msg_window->set_default_size($width,$height);
	$msg_window->set_policy(1,1,0);
	$msg_window->show;
	$msg_window->{'folder'} = 2;
	$accel_group = new Gtk::AccelGroup;
	$msg_window->add_accel_group($accel_group);
	$window = $msg_window->window;
	$bg = $msg_window->style->bg('normal');
	$vbox = new Gtk::VBox('0','0');
	$vbox->show;
	$msg_window->add($vbox);
	## the toolbar
	my $handlebox = new Gtk::HandleBox;
	$toolbar = new Gtk::Toolbar('horizontal','both');
	$toolbar->set_button_relief('none');
	$toolbar->set_tooltips($main::prefs{'ToolTips'});
	$toolbar->border_width('2');
	$handlebox->add($toolbar);
	## the send menubar
	$smenu=new Gtk::MenuBar;
	$smenu->show;
	## the Message Menu
	my ($smm_send, $smm_draft, $smm_spell, $smm_cancel, $smm_insert,$restore);
	$sm_message=new Gtk::MenuItem(_("Message"));
	$sm_message->show;
	$smenu->append($sm_message);
	$smm_menu=new Gtk::Menu;
	$smm_insert= new Gtk::MenuItem(_("Insert from file..."));
	$smm_insert->show;
	$smm_menu->append($smm_insert);
	$restore = new Gtk::MenuItem(_("Restore a session..."));
	$restore->show();
	$smm_menu->append($restore);
	$sm_sep=new Gtk::MenuItem;
	$sm_sep->show();
	$smm_menu->append($sm_sep);
	$smm_send=new Gtk::MenuItem(_("Send"));
	$accel_group->add( 0x073, "mod1-mask" ,['visible'], $smm_send, "activate");
	$smm_send->show();
	$smm_menu->append($smm_send);
	$smm_draft=new Gtk::MenuItem(_("Save as Draft"));
	$smm_draft->show();
	$smm_draft->signal_connect('activate' => sub { $msg_window->{'folder'} = 5; &Pronto::Data::Message::send_message(undef, $msg_window, $msgid, $forrep); });
	$smm_menu->append($smm_draft);
	$smm_spell=new Gtk::MenuItem(_("Spelling"));
	$smm_spell->signal_connect('activate', \&spellcheck,$msg_window,\$spell_window,$sigid,'n');
	$smm_spell->show();
	$accel_group->add(  0xFFC4, "release-mask" ,['visible'], $smm_spell, "activate");
	$smm_menu->append($smm_spell);
	$sm_sep=new Gtk::MenuItem;
	$sm_sep->show();
	$smm_menu->append($sm_sep);
	$smm_cancel=new Gtk::MenuItem(_("Cancel"));
	$accel_group->add( 0x063, "mod1-mask" ,['visible'], $smm_cancel, "activate"); 
	$smm_cancel->show();
	$smm_menu->append($smm_cancel);
	$sm_message->set_submenu($smm_menu);
	if (defined $main::ONETIME && $main::ONETIME == 1) { $smm_cancel->signal_connect('activate'=> sub { $msg_window->destroy; Gtk->exit(0);});}
	$smm_cancel->signal_connect('activate'=> sub {$msg_window->destroy;});
	 
	## the options menu
	my ($smo_receipt, $smo_prio, $smo_encrypt, $smoe_menu, $smop_menu);
	$sm_options=new Gtk::MenuItem(_("Options"));
	$sm_options->show;
	$smenu->append($sm_options);
	$smo_menu=new Gtk::Menu;
	$msg_window->{'receiptCheck'}=new Gtk::CheckMenuItem(_("Return-Receipt"));
	$msg_window->{'receiptCheck'}->set_show_toggle('1');
	$msg_window->{'receiptCheck'}->show();
	$smo_menu->append($msg_window->{'receiptCheck'});
	$smo_prio=new Gtk::MenuItem(_("Priority"));
	$smo_prio->show();
	$smo_menu->append($smo_prio);
	## the priority sub
	my ($smop_1, $smop_2, $smop_3, $smop_4, $smop_5);
	$smop_menu=new Gtk::Menu;			 
	$msg_window->{'priorityRadio'}[0]=new Gtk::RadioMenuItem($priolist[0]);
	$msg_window->{'priorityRadio'}[0]->show;
	$smop_menu->append($msg_window->{'priorityRadio'}[0]);
	$msg_window->{'priorityRadio'}[1]=new Gtk::RadioMenuItem($priolist[1],$msg_window->{'priorityRadio'}[0]);
	$msg_window->{'priorityRadio'}[1]->show;
	$smop_menu->append($msg_window->{'priorityRadio'}[1]);
	$msg_window->{'priorityRadio'}[2]=new Gtk::RadioMenuItem($priolist[2],$msg_window->{'priorityRadio'}[0]);
	$msg_window->{'priorityRadio'}[2]->set_active(1);
	$msg_window->{'priorityRadio'}[2]->show;
	$smop_menu->append($msg_window->{'priorityRadio'}[2]);
	$msg_window->{'priorityRadio'}[3]=new Gtk::RadioMenuItem($priolist[3],$msg_window->{'priorityRadio'}[0]);
	$msg_window->{'priorityRadio'}[3]->show;
	$smop_menu->append($msg_window->{'priorityRadio'}[3]);
	$msg_window->{'priorityRadio'}[4]=new Gtk::RadioMenuItem($priolist[4],$msg_window->{'priorityRadio'}[0]);
	$msg_window->{'priorityRadio'}[4]->show;
	$smop_menu->append($msg_window->{'priorityRadio'}[4]);
	$smo_prio->set_submenu($smop_menu);
	$sm_sep=new Gtk::MenuItem;
	$sm_sep->show();
	$smo_menu->append($sm_sep);
	$smo_encrypt=new Gtk::MenuItem(_("Encryption"));
	$smo_encrypt->show();
	$smo_menu->append($smo_encrypt);
	## the encription sub
	my ($smoe_encrypt, $smoe_sign, $smoe_keycheck);
	$smoe_menu=new Gtk::Menu;
	$msg_window->{'encryptCheck'}=new Gtk::CheckMenuItem(_("Encrypt"));
	$msg_window->{'encryptCheck'}->set_show_toggle('1');
	if ($main::prefs{'Encrypt'}) {$msg_window->{'encryptCheck'}->set_active(1);}
	$msg_window->{'encryptCheck'}->show();
	$smoe_menu->append($msg_window->{'encryptCheck'});
	$msg_window->{'signCheck'}=new Gtk::CheckMenuItem(_("Sign"));
	$msg_window->{'signCheck'}->set_show_toggle('1');
	if ($main::prefs{'Sign'}) {$msg_window->{'signCheck'}->set_active(1);}
	$msg_window->{'signCheck'}->show();
	$smoe_menu->append($msg_window->{'signCheck'});
	$smoe_keycheck=new Gtk::MenuItem("Key check");
	$smoe_keycheck->signal_connect('activate', \&Pronto::Crypt::GUI::keyserver_search_window);
	$smoe_keycheck->show();
	$smoe_menu->append($smoe_keycheck);
	$smo_encrypt->set_submenu($smoe_menu);
	$sm_options->set_submenu($smo_menu);
	## the help menu
	$sm_help=new Gtk::MenuItem(_("Help"));
	$sm_help->show;
	$smenu->append($sm_help);
	my $smh_menu=new Gtk::Menu;
	$hmm_help=new Gtk::MenuItem(_("Help"));
	$accel_group->add( 0xFFBE, "release-mask" ,['visible'], $hmm_help, "activate"); 
	$hmm_help->show();
	$sm_help->set_submenu($smh_menu);
	$smh_menu->append($hmm_help);
	 
	$vbox->pack_start($smenu,0,0,0);
        $toolbar->show;
	$handlebox->show;
	$vbox->pack_start($handlebox,0,0,0);

	$tb_item1 = $toolbar->append_item(_("Send"),_("Click here to send this message"), "",&main::new_pixmap("$main::prefs{'PixmapDir'}/tb_send.xpm", $window, $bg));
	$tb_item2 = $toolbar->append_item(_("Spelling"),_("Click here to spell-check this message"), "",&main::new_pixmap("$main::prefs{'PixmapDir'}/spellcheck.xpm", $window, $bg));
	$tb_item4 = $toolbar->append_item(_("Addressbook"), _("Click here to open the Addressbook"), "",&main::new_pixmap("$main::prefs{'PixmapDir'}/addressbook.xpm", $window, $bg));
	## notebook tab Mail
	$nbox1=new Gtk::VBox(0,0);
	$nbox1->show();
	$hbox1 = new Gtk::HBox(0,0);
	$hbox1->border_width('3');
	$hbox1->show;
	$from_label = new Gtk::Label("From:");
	$from_label->set_padding('5','5');
	$from_label->set_usize(40,10);
	$from_label->show;
	$hbox1->pack_start($from_label,0,0,0);
	$msg_window->{'fromCombo'} = new Gtk::Combo;
	$msg_window->{'fromCombo'}->set_case_sensitive('0');
	$msg_window->{'fromCombo'}->set_use_arrows('1');
	$msg_window->{'fromCombo'}->set_popdown_strings(@poplist);
	$msg_window->{'fromCombo'}->entry->set_text($default);
	$msg_window->{'fromCombo'}->show;
	$hbox1->pack_start( $msg_window->{'fromCombo'},1,1,0);
	$nbox1->pack_start($hbox1,0,0,0);
	@frmlabels = ("To:","Cc:","Bcc:","Subj:");
	my $tmp;
	$i=0;
	foreach $msglbl (@frmlabels) {
		my ($hbox, $label);
		$hbox = new Gtk::HBox(0,0);
		$hbox->border_width('3');
		$hbox->show;
		$label = new Gtk::Label($msglbl);
		$label->set_padding('5','5');
		$label->set_usize(40,10);
		$label->show;
		$hbox->pack_start($label,0,0,0);
		$tmp=$msglbl;
		$tmp=~s/://;
		$msg_window->{$tmp.'Entry'}= new Gtk::Entry;
		$msg_window->{$tmp.'Entry'}->set_text($fields[$i]);
		$msg_window->{$tmp.'Entry'}->set_editable('1');
		$msg_window->{$tmp.'Entry'}->show;
		$hbox->pack_start($msg_window->{$tmp.'Entry'},1,1,0);
		$nbox1->pack_start($hbox,0,0,0);
		$i++;
	}
	my ($avbox,$ahbox,$abutbox,$abutton,$afilelist,$ahbox2, $afilewin);

	$avbox= new Gtk::VBox(0,0);
	$avbox->border_width(3);
	$avbox->show;
	$ahbox=new Gtk::HBox(0,5);
	$ahbox->show();
	$avbox->pack_start($ahbox, 1,1,0);
 
	$afilewin=new Gtk::ScrolledWindow(undef,undef); 
	$afilewin->set_policy('automatic','automatic');
	$ahbox->pack_start($afilewin, 1,1,0);
	$afilewin->can_focus(0);
	my @titles=(_("Filename"),_("Size"));
	$msg_window->{'attachClist'}=new_with_titles Gtk::CList(@titles);
	&main::set_attachment_clist_drag_signals($msg_window->{'attachClist'});
	$msg_window->{'attachClist'}->set_selection_mode("single");
	$msg_window->{'attachClist'}->set_usize(50,50);
	$msg_window->{'attachClist'}->set_column_width(0,260);
	$afilewin->add($msg_window->{'attachClist'});
	$msg_window->{'attachClist'}->show();
	$afilewin->show();
 
	$abutbox = new Gtk::VButtonBox;
	$abutbox->set_usize(-1,32);
	$abutbox->set_layout_default('start');
	$ahbox->pack_start($abutbox, 0,1,5);

	$abutton = new_with_label Gtk::Button(_("Add..."));
	$abutton->set_usize(50,-1);
	$abutton->signal_connect('clicked', \&selectAttachFile,$msg_window->{'attachClist'});
	$abutbox->add($abutton);
	$abutton->show;

	$abutton = new_with_label Gtk::Button(_("Delete"));
	$abutton->set_usize(50,-1);
	$abutton->signal_connect('clicked', \&deleteAttachFile,$msg_window->{'attachClist'});
	$abutbox->add($abutton);
	$abutton->show;

	$abutton = new_with_label Gtk::Button(_("Clear All"));
	$abutton->set_usize(50,-1);
	$abutton->signal_connect('clicked', \&clearAttachFile,$msg_window->{'attachClist'});
	$abutbox->add($abutton);
	$abutton->show;
	$abutbox->show;
	$abutbox->show;
 
	$notebook=new Gtk::Notebook;
	my $lbl1=new Gtk::Label(_("Mail"));
	$lbl1->show;
	$notebook->append_page($nbox1,$lbl1);
	my $lbl2=new Gtk::Label(_("Attachments"));
	$lbl2->show;
	$notebook->append_page($avbox,$lbl2);
	$notebook->show();
	$vbox->pack_start($notebook, 0,0,0);

	$msg_window->{'ToEntry'}->signal_connect('focus_out_event' => \&alias_expand, $msg_window->{'ToEntry'});
	$msg_window->{'CcEntry'}->signal_connect('focus_out_event' => \&alias_expand, $msg_window->{'CcEntry'});
	$msg_window->{'BccEntry'}->signal_connect('focus_out_event' => \&alias_expand, $msg_window->{'BccEntry'});
	$msg_window->{'mailText'} = new Gtk::Text(undef,undef);
	$msg_window->{'ToEntry'}->signal_connect('focus_in_event', sub { 
	my ($this) = @_; $data->{'focused'} = $this; });
	$msg_window->{'CcEntry'}->signal_connect('focus_in_event', sub { my ($this) = @_; $data->{'focused'} = $this;});
	$msg_window->{'BccEntry'}->signal_connect('focus_in_event', sub { my ($this) = @_; $data->{'focused'} = $this; });

				
#	if (!$spellstarted) {
#		Gtk::Text::start_spell();
#		$spellstarted = 1;
#	}	

#	Gtk::Text::attach($msg_window->{'mailText'});
	$msg_window->{'mailText'}->set_word_wrap(1);
	$msg_window->{'SubjEntry'}->signal_connect("key_press_event" =>  sub {my($this, $event)=@_; if($event->{keyval} == 65289) {$this->signal_emit_stop("key_press_event");$msg_window->{'mailText'}->grab_focus;return 1}});
	$scrollbar = new Gtk::VScrollbar($msg_window->{'mailText'}->vadj);
	$scrollbar->show;
	$msg_window->{'mailText'}->set_editable('1');
	if ($msgid) {
		&Pronto::Read::view_message($main::conn, $msgid, $msg_window->{'mailText'}, 2, $forrep, undef, undef, undef, $msg_window->{'attachClist'});
	}
	unless (defined $forrep && $forrep == 3) {
		my @sig;
		if (($sigid) and (open(TMP, "<$main::prefs{'MailDir'}/sig/$sigid.sig")) && !$main::prefs{'ExternalSig'}) {
			undef $/;
			@sig = <TMP>;
			$/ = "\n";
			close(TMP);
		} elsif ($sigid && $main::prefs{'ExternalSig'}) {
			@sig = `$main::prefs{'SigCmd'}`;
		#	if (!@sig) { @sig = (" "); }
		}	
			
			if (@sig) {
				$msg_window->{'mailText'}->insert($font,'','',"\n-- \n");
				foreach(@sig) {
					$msg_window->{'mailText'}->insert($font,'','',"$_");
	       			}
				$msg_window->{'mailText'}->insert($font,'','',"\n");
			}

		
	}
	
	
	$msg_window->{'mailText'}->set_point(0);
	$msg_window->{'mailText'}->insert($font,'','',"\n");
	$msg_window->{'mailText'}->show;
	$hbox5 = new Gtk::HBox(0,0);
	$hbox5->border_width('3');
	$hbox5->pack_start($msg_window->{'mailText'},1,1,0);
	$hbox5->pack_start($scrollbar,0,0,0);
	$hbox5->show;
	$vbox->add($hbox5);
	if($main::prefs{'autospell'} eq 'y') {
		$tb_item1->signal_connect('clicked', \&spellcheck, $msg_window, \$spell_window, $sigid, 'y', $msgid, $forrep);
		$smm_send->signal_connect('activate', \&spellcheck, $msg_window, \$spell_window, $sigid, 'y', $msgid, $forrep);
	} else {
		$tb_item1->signal_connect('clicked', \&Pronto::Data::Message::send_message, $msg_window, $msgid, $forrep);
		$smm_send->signal_connect('activate', \&Pronto::Data::Message::send_message, $msg_window, $msgid, $forrep);
	}
	$smm_insert->signal_connect('activate', \&insertFromFileSelect, $msg_window );
	$restore->signal_connect('activate', \&Restore_Session, $msg_window);
	$tb_item2->signal_connect('clicked', \&spellcheck, $msg_window,\$spell_window,$sigid,'n');
	$data->{'to'} = $msg_window->{'ToEntry'};
	$data->{'cc'} = $msg_window->{'CcEntry'};
	$data->{'bcc'} = $msg_window->{'BccEntry'};
	$tb_item4->signal_connect('clicked', \&Pronto::AddressBook::init_win, $data);
 
	$msg_window->{'fromCombo'}->popwin->signal_connect("hide", \&switch_sig,  $msg_window->{'fromCombo'},  $msg_window->{'mailText'});
	$scrollbar->can_focus(0);
	$notebook->can_focus(1);
	$lbl1->can_focus(0);  
	$lbl2->can_focus(0);
	$msg_window->{'ToEntry'}->grab_focus;
 
	$msg_window->{'encryptCheck'}->signal_connect('toggled', \&toggle_enc);
	$msg_window->{'signCheck'}->signal_connect('toggled', \&toggle_sign);
	$toolbar->set_style($main::prefs{'toolbarstyle'});
	if ($main::prefs{'toolbar'} eq "n") { $handlebox->hide; }
	if (defined $main::ONETIME && $main::ONETIME == 1) { $msg_window->signal_connect("destroy", sub { $msg_window->destroy; Gtk->exit(0) });}
	$msg_window->signal_connect("destroy" => \&msg_window_destroy, $data);
	$msg_window->signal_connect("size-request" => \&main::save_win_size, "MsgWinstartUp", $msg_window->window);
	$msg_window->{'session_id'} = localtime;
	#do we enable auto_save
	if ($main::prefs{'autosave'}) {
		$msg_window->{'timer'} = Gtk->timeout_add(1000, \&do_auto_save, $msg_window);
	}
	return 1;
}


sub Drag_Data_Received
{
	my ($clist, $context, $x, $y, $data, $info, $time) = @_;
	if (($data->length >= 0) && ($data->format == 8)) {
		my @files = split(/\n/,$data->data);
		foreach my $file (@files) {
			chop($file);
			$file =~ s/^file:\/\///g; #netscape/mozilla
			$file =~ s/^file://g; #gmc 
			print $file."\n";
			next if (!-f $file);
			next if (!-e $file);
		 	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size)=stat $file;
			$size=$size/1024;
			$clist->append(($file,(sprintf("%8.2f",$size)."kb")));
		}			
		$context->finish(1, 0, $time);
		return 1;
	}
	$context->finish(0, 0, $time);
	return 0;	
}

sub do_auto_save
{
	my ($msg_window) = @_;
	if (defined $msg_window->{'mailText'}) {
		open(TMP,">$main::prefs{'MailDir'}/sessions/".$msg_window->{'session_id'}) or return 0;
		print TMP $msg_window->{'mailText'}->get_chars(0,-1);
		close(TMP);
		return 1;
	} else {
#		print "timer going out\n";
		return 0;
	}	
}	


sub Restore_Session
{
	my ($menuitem, $msg_window) = @_;
	my (@list,$dialog);
	opendir(DIR,"$main::prefs{'MailDir'}/sessions") or return &main::err_dialog("Couldn't read sessions dir !");
	while (defined (my $file = readdir DIR)) {
		next if $file =~ /^\.\.?$/;
		next if ($file eq $msg_window->{'session_id'});
		push @list, $file;
	}
	closedir(DIR);
	return &main::err_dialog(_("No stale sessions found !")) if (scalar(@list) == 0);
	$dialog = new Gtk::Dialog();
	$dialog->set_title(_("Restore Session"));
	$dialog->{'clist'} = new Gtk::CList(1);
	$dialog->{'sw'} = new Gtk::ScrolledWindow(undef,undef);
	$dialog->{'sw'}->set_policy('automatic','automatic');
	$dialog->{'sw'}->add($dialog->{'clist'});
	$dialog->vbox->pack_start($dialog->{'sw'},1,1,0);
	$dialog->{'restore'} = new Gtk::Button(_("Restore"));
	$dialog->{'delete'} = new Gtk::Button(_("Delete"));
	$dialog->action_area->pack_start($dialog->{'restore'},1,1,0);
	$dialog->action_area->pack_start($dialog->{'delete'},1,1,0);
	$dialog->set_default_size(200,150);
	foreach(@list) {
		chomp($_);
		$dialog->{'clist'}->append($_);
	}	
	$dialog->{'restore'}->signal_connect("clicked", \&restore_clicked, $msg_window, $dialog);
	$dialog->{'delete'}->signal_connect("clicked", \&delete_session, $dialog);
	$dialog->show_all();
	return;
}

sub delete_session
{
	my ($button,$dialog)=@_;
	my @selection = $dialog->{'clist'}->selection();
	return if (!@selection);
	my $file = $dialog->{'clist'}->get_text($selection[0],0);
	unlink($main::prefs{'MailDir'}."/sessions/".$file) or return &main::err_dialog(_("Couldn't remove session file!"));
	$dialog->{'clist'}->remove($selection[0]);
	return;
}	

sub restore_clicked
{
	my ($button, $msg_window, $dialog) = @_;
	return if (!defined($msg_window->{'mailText'}));
	my @selection = $dialog->{'clist'}->selection();
	return if (!@selection);
	my $file = $dialog->{'clist'}->get_text($selection[0],0);
	open(TMP,"$main::prefs{'MailDir'}/sessions/$file") or return &main::err_dialog(_("Couldn't read session file !"));
	$msg_window->{'mailText'}->freeze();
	$msg_window->{'mailText'}->set_point(0);
	$msg_window->{'mailText'}->forward_delete($msg_window->{'mailText'}->get_length());
	while (<TMP>) {
		$msg_window->{'mailText'}->insert('','','',"$_");
	}
	close(TMP);
	$msg_window->{'mailText'}->thaw();
	$dialog->destroy();
	return;
}	

sub msg_window_destroy {
 
 	my ($window, $data) = @_;
 	undef $data->{'to'};
 	undef $data->{'cc'};
 	undef $window->{'mailText'};
#	print("deleting session file $window->{'session_id'}\n");
	unlink($main::prefs{'MailDir'}."/sessions/".$window->{'session_id'});	
	$window->destroy;

}

sub alias_expand {
	my ($widget, $entry, $event) = @_;
	my ($sql, $text, @fields, $alias_check, $group_check, @new_fields, %new_fields);
	my ($aprox_id);
	$text = $entry->get_text;

	# Queries to check if the entry is in a group or an alias
	$sql = "SELECT id FROM groups WHERE name LIKE ?";
	$group_check = $main::conn->prepare ($sql);
	$sql = "SELECT address, alias FROM addresses WHERE alias LIKE ?";
	$alias_check = $main::conn->prepare ($sql);
	$sql = "SELECT address, alias, groups FROM addresses WHERE groups LIKE ?";
	$aprox_id    = $main::conn->prepare ($sql);

	# Get the fields from the text field
	@fields = quotewords(", ", 1, $text);

	# Go through all the fields
	for (@fields) {
		if (defined $_) {
			if (index ($_, '@') == -1) {
				my $rows;
	
				# Check groups first
				$rows = $group_check->execute ("%$_%");
				if ($rows > 0) {
					while (my ($id) = $group_check->fetchrow) {
						$aprox_id->execute ("%$id%");
						while (my ($address, $alias, $groups) = $aprox_id->fetchrow) {
							next unless $groups;
							if (grep { $id eq $_ } split "," => $groups) {
								$new_fields{$alias} = $address;
							}
						}
					}
					next;
				}

				# Check for aliases
				$rows = $alias_check->execute ("%$_%");
				if ($rows > 0) {
					my ($address, $alias) = $alias_check->fetchrow;
					$new_fields{$alias} = $address;
					next;
				}
			}
			else {
				push @new_fields, $_;
			}
		}
	}
	$text  = (@new_fields) ?  (join (", " => @new_fields)) : '';
	if (keys %new_fields) {
		$text .= ', ' if (@new_fields);
		for (keys %new_fields) {
			$text .= qq{"$_" <$new_fields{$_}>, };
		}
		chop $text; chop $text;
	}
	$entry->set_text ($text) if ($text && $text ne ""); 
	$entry->{'focus'} = 0;
	return 1;
}

sub toggle_enc {
 
 	if ($main::prefs{'Encrypt'}) {
  		$main::prefs{'Encrypt'} = 0;
 	} else {
  		$main::prefs{'Encrypt'} = 1;
 	}
 	
	&main::save_prefs();
}

sub toggle_sign {
 
 	if ($main::prefs{'Sign'}) {
  		$main::prefs{'Sign'} = 0;
 	} else {
  		$main::prefs{'Sign'} = 1;
 	}
 
 	&main::save_prefs();
}

sub switch_sig {
 	
	my ($widget, $from_combo, $textbox) = @_;
 	my ($friendly, $sql, $query, @row, @sig, $sigid, $body);
 	my $font = Gtk::Gdk::Font->load($main::prefs{'FontComposer'});
 	if ($main::prefs{'useGtkFontComposer'} eq "y") { $font = "" }
 	$body = $textbox->get_chars(0,-1);
 	$textbox->freeze;
 	$textbox->set_point(length($body));
 	$textbox->backward_delete(length($body));
 	$body =~ s/\n-- \n.*//s;
 	$textbox->insert($font,'','',$body);
 	$friendly = $from_combo->entry->get_text();
 	$sql = "select id from accounts where descr=?";
 	$query=$main::conn->prepare($sql);
 	$query->execute($friendly);
 	@row = $query->fetchrow_array();
 	$sigid = $row[0];
 	if (open(TMP,"<$main::prefs{'MailDir'}/sig/$sigid.sig") && !$main::prefs{'ExternalSig'}) {
  		@sig = <TMP>;
  		close(TMP);
	} elsif ($sigid && $main::prefs{'ExternalSig'}) {
		@sig = `$main::prefs{'SigCmd'}`;
	}
	if (@sig) {
  		$textbox->insert($font,'','',"\n-- \n");
  		foreach (@sig) {
   			$textbox->insert($font,'','',$_);
  		}
  		$textbox->insert($font,'','',"\n");
 	}
 	$textbox->thaw;
 	return 1;
}

sub insertFromFileSelect {
 
 	my ($widget, $win)=@_ ;
 	my ($fs_window);
 	$fs_window = new Gtk::FileSelection _("Choose file to insert into Message...");
 	$fs_window->position(-mouse);
 	$fs_window->signal_connect("destroy", sub {$fs_window->destroy;});
 	$fs_window->signal_connect("delete_event" => \&Gtk::false);
 	$fs_window->ok_button->signal_connect("clicked", \&insertFromFile, $fs_window, $win);
 	$fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;});
 	$fs_window->show;
 
 	return 1;
}

sub insertFromFile {
	my ($widget, $filewin, $win)=@_;
	my ($filename, $error, $tmp, $textbox);
	$textbox=$win->{'mailText'};
	$error=0;
	$filename=$filewin->get_filename();
	$filewin->destroy;
	open FILE, $filename or $error=1;
	if ($error == 1){
		&main::err_dialog("$filename " ._("could not get opened!"));
	} else {
		$tmp="";
		while (<FILE>){
			$tmp.=$_;
		}
		close FILE;
		$tmp.="\n".$textbox->get_chars(0,-1);
		$textbox->set_point(0);
		$textbox->forward_delete($textbox->get_length);
		$textbox->insert('','','',"$tmp");
	}
	return 1;
}

sub spellcheck {
 
 	my ($window,$msg_window,$spell_window,$sigid,$autospell,$msgid,$forrep) = @_;
 	my ($textbox,$body,@spell_list,$vbox,$tbox,$bg,$butbox,$ok_button,$combo,$i,$sum,$replace_button,$last_combo_connect,$next_button,$add_button,$last_add_connect);
 	if(defined $$spell_window) {
		return 1;
 	}
 	$textbox=$msg_window->{'mailText'};
 	if(-f $main::prefs{'ispellpath'}) {
 		$Lingua::Ispell::path = $main::prefs{'ispellpath'};
 	}
 	else {
		&main::err_dialog(_("The path to ispell or aspell is not set correctly"));
		return 1;
 	}
 	exec_ispell($textbox,\@spell_list,$sigid,\$sum);
 	if(($sum == 0) && ($autospell eq 'y')) {
		&Pronto::Data::Message::send_message($msg_window,$msg_window,$msgid,$forrep);
		return 1;
 	}
 	$i = 0;
 	$$spell_window = new Gtk::Window("toplevel");
 	$$spell_window->set_position("mouse");
 	$$spell_window->set_title(_("Spell Check"));
 	$$spell_window->signal_connect("destroy" => 
					sub { 
					$$spell_window->destroy;
					undef $$spell_window;
	 				});
 	$$spell_window->signal_connect("delete_event" => \&Gtk::false);
 	$$spell_window->set_default_size('180','130');
 	$$spell_window->set_policy(1,1,0);
 	$$spell_window->show;
 	$window = $$spell_window->window;
 	$vbox = new Gtk::VBox(0,0);
 	$$spell_window->add($vbox);
 	$vbox->show;
 	$tbox = new Gtk::Label("");
 	$vbox->pack_start($tbox,1,1,1);
 	$tbox->show;
 	$combo = new Gtk::Combo();
 	$vbox->pack_start($combo,1,1,1);
 	$combo->hide;
 	$replace_button = new Gtk::Button(_("Replace"));
 	$vbox->pack_start($replace_button,1,1,1);
 	$replace_button->hide;
 	$add_button = new Gtk::Button(_("Add to Dictionary"));
 	$vbox->pack_start($add_button,1,1,1);
 	$add_button->hide;
 	$butbox = new Gtk::HButtonBox;
 	$butbox->show;
 	$vbox->pack_start($butbox,1,1,1);
 	if($autospell eq 'y') {
		$ok_button = new_with_label Gtk::Button(_("Send"));
 	}
 	else {
 		$ok_button = new_with_label Gtk::Button(_("OK"));
 	}
 	$ok_button->set_usize(50,-1);
 	$ok_button->signal_connect('clicked', 
					sub { 
					$$spell_window->destroy;
					if($autospell eq 'y') {
						&Pronto::Data::Message::send_message($msg_window,$msg_window,$msgid,$forrep);
					}
	    				});
 	$ok_button->can_default(1);
 	$ok_button->grab_default;
 	$next_button = new_with_label Gtk::Button(_("Next"));
 	$next_button->set_usize(50,-1);
 	$next_button->signal_connect('clicked',
        					sub {
						if((++$i == $sum) && (0 != $sum)) {
						$i=-1;
						$tbox->set_text(_("End of Message\nPress Next to\nGo Back to Top"));
						$replace_button->hide;
						$combo->hide;
						$add_button->hide;
						exec_ispell($textbox,\@spell_list,$sigid,\$sum);
						}
						else {
                				spellcheck_next($textbox,$spell_list[$i],$tbox,$combo,$replace_button,$add_button,$i,$sum,\$last_combo_connect,\$last_add_connect,$next_button);
						}
        					});
 	$next_button->can_default(1);
 	$next_button->grab_default;
 	$butbox->add($next_button);
 	$next_button->show;
 	$butbox->add($ok_button);
 	$ok_button->show;
 	spellcheck_next($textbox,$spell_list[$i],$tbox,$combo,$replace_button,$add_button,$i,$sum,\$last_combo_connect,\$last_add_connect,$next_button);
 
 	return 1;
}

sub spellcheck_next {
 
 	my($textbox, $r, $tbox, $combo, $replace_button, $add_button, $i, $sum, $last_combo_connect,$last_add_connect,$next_button) = @_;
 	my($body,$end,$start,$word_num,$miss,$misses,$array,$j);
 	$word_num = $i+1;
 	$misses ="";
 	if($sum==0) {
        	$tbox->set_text(_("Found No Mispelled Words"));
		$next_button->hide;
		$combo->hide;
		$replace_button->hide;
		$add_button->hide;
 	}
 	if(defined $r) {
   		$array = $r->{'misses'};
   		$j=0;
   		$body = $textbox->get_chars(0,-1);
   		$body =~ s/\n/ /g;
   		$body =~ s/_/ /g;
   		$body =~ s/[0-9]/ /g;
   		if($body =~ m/\b$r->{'term'}\b/g) {
        	$end = pos $body;
        	$start = $end - length($r->{'term'});
        	if (!$array) { 
			$tbox->set_text("$word_num of $sum [$r->{'term'}]\n was not found in dictionary");
			$replace_button->hide; 
			$combo->hide; 
		} 
		else {
			$tbox->set_text("$word_num of $sum Mispelled Words\nSuggestions:");
        		$combo->set_popdown_strings(@$array);
        		$replace_button->show;
			$combo->show; 
		}	
        	if(defined $$last_combo_connect) {
			if($replace_button->signal_n_emissions('clicked')) {
				$replace_button->signal_emit_stop('clicked');
			}
                $replace_button->signal_disconnect($$last_combo_connect);
        	}
        	$$last_combo_connect=$replace_button->signal_connect('clicked',
                				sub{
                        			$textbox->freeze;
                        			$textbox->set_point($start);
                        			$textbox->forward_delete($end-$start);
                        			$textbox->insert("","","",$combo->entry->get_text());
                        			$textbox->thaw;
                        			$end = $start + length($combo->entry->get_text());
                        			$textbox->freeze;
                        			$textbox->select_region($start,$end);
                        			$textbox->thaw;
						$next_button->signal_emit('clicked');
                				});
		if(defined $$last_add_connect) {
			if($add_button->signal_n_emissions('clicked')) {
				$add_button->signal_emit_stop('clicked');
			}
                $add_button->signal_disconnect($$last_add_connect);
        	}
		$$last_add_connect=$add_button->signal_connect('clicked', sub{add_word($r->{'term'},$next_button);}); 
		$add_button->show;
        	$textbox->freeze;
        	$textbox->select_region($start,$end);
        	$textbox->thaw;
   	}
   	else {
        	$tbox->set_text("$word_num of $sum Spelling Changed");
        	$combo->hide;
        	$replace_button->hide;
		$add_button->hide;
   	}
 }
 
 	$tbox->show;

 	return 1;
}

sub exec_ispell{
 
 	my($textbox,$spell_list,$sigid,$sum) = @_;
 	my($body);
 	$body = $textbox->get_chars(0,-1);
 	$body =~ s/\n/ /g;
 	if (($sigid) and (open(TMP, "<$main::prefs{'MailDir'}/sig/$sigid.sig"))) {
   		my @sig = <TMP>;
   		close(TMP);
   		my $sig=join("",@sig);
  
   		$body=~ s/\Q$sig\E//;
 	}
 	$$sum=0;
 	@$spell_list = Lingua::Ispell::spellcheck( $body );
 	while(defined $$spell_list[$$sum]) {
   		$$sum++;
 	}
 
 	return 1;
}

sub add_word {
 	my ($word,$next_button) = @_;
 	my ($window,$vbox,$butbox,$button,$tbox);
 	$window = new Gtk::Window("toplevel");
 	$window->set_position("mouse");
 	$window->set_title("Add Word to Dictionary");
 	$window->signal_connect("destroy" => sub{$window->destroy;});
 	$window->signal_connect("delete_event" => \&Gtk::false);
 	$window->set_default_size('200','70');
 	$window->set_policy(1,1,0);
 	$window->show;
 	$vbox = new Gtk::VBox(1,1);
 	$window->add($vbox);
 	$vbox->show;
 	$tbox = new Gtk::Label("Add $word\nto the Dictionary?");
 	$vbox->pack_start($tbox,1,1,1);
 	$tbox->show;
 	$butbox = new Gtk::HButtonBox;
 	$vbox->pack_start($butbox,1,1,1);
 	$button = new Gtk::Button("No");
 	$button->signal_connect('clicked', sub{$window->destroy;});
 	$butbox->add($button);
 	$button->show;
 	$button = new Gtk::Button("Yes");
 	$button->signal_connect('clicked', 
					sub{
					Lingua::Ispell::add_word($word);
					$next_button->signal_emit('clicked');
					$window->destroy;
					});
 	$butbox->add($button);
 	$button->show;
 	$butbox->show;
 
 return 1;
}

sub attach_file {
 
 	my ($widget)=shift;
 	my ($attachments)=shift;
 	my ($attach_win,$window,$bg,$tbox,$hbox,$sep,$butbox,$button,$butbox1,$filelist,
     	$tmp,$hbox2, $filewin);
 	my ($attach_rows,$arrtmp);
 	$attach_rows=-1;
 	$attach_win = new Gtk::Window("dialog");
 	$attach_win->set_title(_("Attach files"));
 	$attach_win->signal_connect("destroy" => sub { $attach_win->destroy; });
 	$attach_win->signal_connect("delete_event" => \&Gtk::false);
 	$attach_win->set_default_size('350','200');
 	$attach_win->set_policy(1,1,0);
 	$attach_win->show;
 	$window = $attach_win->window;
 	$bg = $attach_win->style->bg('normal');
 	$hbox= new Gtk::VBox(0,0);
 	$attach_win->add($hbox);
 	$hbox->show;

 	$hbox2=new Gtk::HBox(0,5);

 	$hbox->pack_start($hbox2, 1,1,0);
 	$hbox2->show();
 
 	$filewin=new Gtk::ScrolledWindow(undef,undef); 
 	$filewin->set_policy('automatic','automatic');
 
 	$hbox2->pack_start($filewin, 1,1,0);
 	my @titles=("Filename","Size");
 	$filelist=new_with_titles Gtk::CList(@titles);
 	$filelist->set_selection_mode("single");
 	$filelist->set_usize(50,50);
 	$filelist->set_column_width(0,160);
# $filelist->signal_connect('select_row', \&selectAttach,\$attach_rows);
# $filelist->signal_connect('unselect_row', \&unSelectAttach,\$attach_rows);
 	$filewin->add($filelist);
# $hbox->pack_start($filelist, 0,0,0);
 	if (scalar(@$attachments)>0){
		for ($tmp=0;$tmp<scalar(@$attachments);$tmp++){
			$arrtmp=@$attachments[$tmp];
 		 	$filelist->append((@$arrtmp[0],@$arrtmp[1]));
		}
 	}
 	$filelist->show();
 	$filewin->show();
  
 	$butbox1 = new Gtk::VButtonBox;
 	$butbox1->set_usize(-1,32);
 	$butbox1->set_layout_default('start');
 	$hbox2->pack_start($butbox1, 0,1,5);
 
 	$button = new_with_label Gtk::Button("Add...");
 	$button->set_usize(50,-1);
	$button->signal_connect('clicked', \&selectAttachFile,$filelist);
 	$butbox1->add($button);
 	$button->show;

 	$button = new_with_label Gtk::Button("Delete");
 	$button->set_usize(50,-1);
 	$button->signal_connect('clicked', \&deleteAttachFile,$filelist);
 	$butbox1->add($button);
 	$button->show;
 	$butbox1->show;

 	$button = new_with_label Gtk::Button("Clear All");
 	$button->set_usize(50,-1);
 	$button->signal_connect('clicked', \&clearAttachFile,$filelist);
 	$butbox1->add($button);
 	$button->show;
 	$butbox1->show;
 
 	$sep = new Gtk::HSeparator;
 	$sep->set_usize(-1,5);
 	$hbox->pack_start($sep,0,1,0);
 	$sep->show;

 	$butbox = new Gtk::HButtonBox;
 	$butbox->set_usize(-1,32);
 	$hbox->pack_start($butbox, 0,1,0);
 	$butbox->show;
     
 	$button = new_with_label Gtk::Button(_("OK"));
 	$button->set_usize(50,-1);
 	$button->signal_connect('clicked', \&okAttach,$attach_win, $filelist, $attachments);
 	$button->can_default(1);
 	$button->grab_default;
 	$butbox->add($button);
 	$button->show;

 	$button = new_with_label Gtk::Button(_("Cancel"));
 	$button->set_usize(50,-1);
 	$button->signal_connect('clicked', sub { $attach_win->destroy; });
 	$button->can_default(1);
 	$button->grab_default;
 	$butbox->add($button);
 	$button->show;

 
 	return 1;
}

sub okAttach {
 	my ($widget,$attach_win,$list,$attachments)=@_;
 	my ($tmp,$tmp1,$tmp2);
 	if ($list->rows>=1){
   		for ($tmp=0;$tmp<$list->rows;$tmp++){
     			$tmp1=$list->get_text($tmp,0);
     			$tmp2=$list->get_text($tmp,1);   
		 	@$attachments[$tmp]=[$tmp1,$tmp2];
   		}
 	} else {
 	}
 	$attach_win->destroy;
}

sub clearAttachFile {
 
 	my ($widget,$listwidget)=@_;
 	$listwidget->clear();
 
 	return 1;
}

sub selectAttachFile {
 	my ($widget,$listwidget)=@_;
 	my ($fs_window);
 	$fs_window = new Gtk::FileSelection _("Select File to Attach...");
 	$fs_window->position(-mouse);
 	$fs_window->file_list->set_selection_mode('extended');
	$fs_window->signal_connect("destroy", sub {$fs_window->destroy;});
 	$fs_window->signal_connect("delete_event" => \&Gtk::false);
 	$fs_window->ok_button->signal_connect("clicked", \&addAttachFile, $fs_window, $listwidget);
 	$fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;});
	if ($last_dir) {
		$fs_window->set_filename($last_dir);
	}
	$fs_window->show;
 	return 1;
}

sub addAttachFile {
 
 	my ($widget,$fswin,$clist)=@_;
 	my (@selection);
       	@selection = $fswin->file_list->selection();
	if (!@selection) {
		my $file = $fswin->get_filename();
		if (!-f $file) {
			&main::err_dialog(_("Selected file $file couldn't be attached!\n"));
			return;
		} else {
			AppendAttachedFile($clist,$file);
		}	
	} else {
		$lastdir = $fswin->selection_text->get();
		$lastdir =~ s/(.*)\: //;
		foreach(@selection) {
			my $file = $fswin->file_list->get_text($_,0);
			if ($file) {
				$file = "$lastdir/$file";
				AppendAttachedFile($clist,$file);
			}
		}
	}
	$fswin->destroy();
	return;
}	

sub AppendAttachedFile
{
	my ($clist,$filename) = @_;
	my $error = 0;
 	open FILE, $filename or $error=1;
 	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size)=stat FILE;
 	close FILE or $error=1;
 	if ($error==0){
   		$size=$size/1024;
	 	$clist->append(($filename,(sprintf("%8.2f",$size)."kb")));
 		my @tmp = split('/',$filename);
		my $num=scalar(@tmp);
		$tmp[$num-1] = "";
		$last_dir = join('/',@tmp);
	} else {
 		&main::wr_debug("unable to open $filename.");
 	}
 	return 1;
}

sub deleteAttachFile {
 	
	my ($widget,$list)=@_;
 	if (defined $list->selection() && $list->selection()>=0){
 	  	$list->remove($list->selection());
       	}
	 return 1;
}

1;
