#!/usr/local/bin/perl
#
# Copyright (C) 1992 by Gustaf Neumann, Stefan Nusser
#
#      Wirtschaftsuniversitaet Wien,
#      Abteilung fuer Wirtschaftsinformatik
#      Augasse 2-6,
#      A-1090 Vienna, Austria
#      neumann@wu-wien.ac.at, nusser@wu-wien.ac.at
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that the above copyright notice appears in all copies and that both that
# copyright notice and this permission notice appear in all supporting
# documentation.  This software is provided "as is" without expressed or
# implied warranty.
#
# Date: Mon, Apr 13 1992
# Author: Gustaf Neumann
# Version: 0.92
#

%privOptions = (
	"f", "folder: name of the mail folder",
	"p", "print command: such as 'mp | lpr'",
	"s", "signature file: such as ~/.elm/signature",
	"F", ": fast startup mode",
	"C", ": prefer files for communication",
	"r", ": read only mode",
	);
$options = "u";

$WafeLib = $ENV{'WAFELIB'} || "/usr/lib/X11/wafe";
require "$WafeLib/perl/wafe.pl";
require 'wafe_mu.pl';

$mailIncludePrefix = $mailIncludePrefix || " |> ";
$incomingMailbox = $incomingMailbox 
    || $ENV{'MAIL'} 
    || "/usr/spool/mail/$wafe_mu'user";
$mailbox = $opt_f || $incomingMailbox;
$printCommand = $opt_p || $printCommand || "mp | multi | lpr";

$mailtext = &wafe'tmpFile("mailtext");
$faceDir = $faceDir || "$WafeLib/faces";
$opt_u = $opt_u || 5; # check mailbox every n seconds

$fast = $opt_F;
$useXPM = (!defined($noXPM) && $wafe'Packages =~ /\bXPM\b/);

if ($fast) {
    $subjectFile = &wafe'tmpFile("mailsubjects");
    open(SUBJECTS,">$subjectFile") && print SUBJECTS "\n" && close(SUBJECTS);
}


#
# readMailBox ( $fromByte )
# reads a mailbox and builds corresponding perl arrays

sub readMailBox {
    local($fromByte) = @_;
    local($encoding);
    return if ($MailBoxSize = -s $mailbox) == 0 || $MailBoxSize <= $fromByte;

    &wafe_mu'exclusiveLock(MBOX);
    seek(MBOX,$fromByte,0) if $fromByte >0;

    $/ = ""; $*=1; 
    while (<MBOX>) {

	if (/^From /) {
            if ($ContentType[$count]) {
                 $Body[$count] = 
                   &wafe_mu'MimeDecode($ContentType[$count],$Body[$count]);
            }
	    $count++;
            $encoding = $contentEncoding = "";
	    $Header[$count] = $_;
            $ContentType[$count] = "";
	    s/\n\s+//g;
	    for (split("\n")) {
#		print "LINE: <$_>\n";
		$Subject[$count] = $1 if m/^Subject: *(.*)$/;
		$To[$count] = $1 if m/^To: *(.*)$/;
		$From[$count] = $1 if m/^From: *(.*)$/;
		$Cc[$count] = $1 if m/^Cc: *(.*)$/;
		$Date[$count] = $1 if m/^Date: *(.*)$/;
    		$Priority[$count] = $1 if m/^Priority: *(.*)$/;
		$Status[$count] = $1 if m/^Status: *(.*)$/;
		$ReplyTo[$count] = $1 if m/^Reply\-To: *(.*)$/;
		$ContentType[$count] .= "\$type='$1';" 
		    if m/^Content\-[Tt]ype: *(.*)$/;
		$ContentType[$count] .= "\$encoding='$1';" 
		    if m/^Content\-[Tt]ransfer-[Ee]ncoding: *(.*)$/;
		$encoding = $1 if m/^X-Encoding:\s*(\S+)\s*$/;
	    }
            $unread ++ if ($Status[$count] !~ m/.*R.*/);
            if (($From[$count]=~ /\.se(\s|\b)/ && 
		 $defaultMailEncoding =~ /Swe/i) ||
#                ($To[$count]=~ /g11|g13/) ||  # Dov's very private option...
		    ($encoding eq "SweAscii")) {
                     $Subject[$count] = &wafe_mu'SweDecode($Subject[$count]);
                     $Header[$count] = &wafe_mu'SweDecode($Header[$count]);
                     $encoding= "SweAscii";
            }
            elsif ($encoding eq 'TeX') {
                $Subject[$count] = &wafe_mu'TeXdecode($Subject[$count]);
                $Header[$count] = &wafe_mu'TeXdecode($Header[$count]);
            }
	} else {
            $_ = &wafe_mu'TeXdecode($_) if $encoding eq 'TeX';
            $_ = &wafe_mu'SweDecode($_) if $encoding eq 'SweAscii';
	    $Body[$count] .= $_; 
	}
    }
 
    if ($ContentType[$count]) {
	$Body[$count] = 
             &wafe_mu'MimeDecode($ContentType[$count],$Body[$count]);
    }

    &wafe_mu'unLock(MBOX);
    $/ = "\n"; $*=0; 
}

#
# writeSubjects
# is used only in "fast-mode" and 
# generates a file containing the subject entries of the mailbox

sub writeSubjects {
    local($low,$high,$spattern,$bpattern) = @_;
    local($i,$line,$status);

    $subjectLines = "";
    for ($low .. $high) {
        $i = $low + $high - $_;
        $line = &subjectLine($i); 
        next if ($spattern && $Subject[$i] !~ /$spattern/i 
		 && $From[$i] !~ /$spattern/i);
        next if ($bpattern && $Body[$i] !~ /$bpattern/i);
        $line = substr($line . " " x 60,0,90);

        $status = (($Status[$i] =~ /.*R.*/) ? ' ' : 'N')
                . ($Deleted[$i] ? "D ":"  ");
        $subjectLines .= 
	    " " . substr($line,0,4) . $status . substr($line,4) . "\n" ;
        
    }
    open(SUBJECTS,">$subjectFile") || die "cannot open $subjectFile for writing";
    print SUBJECTS $subjectLines;
    close(SUBJECTS);
}

#
# subjectLine($i)
# returns a single formatted subject line of the mailbox entry $i

sub subjectLine {
    local($i) = @_;
    local($day,$asciimonth,$year,$h,$m,$name,$addr);
    $Date[$i] =~ /(\d+) +(\S+) +(\d+)\D+(\d+):(\d+)/;
    $day=$1; $asciimonth = $2; $year=($3>100) ? $3 : 1900+$3; $h=$4; $m=$5;

    ($name,$addr) = &wafe_mu'nameAddress( $ReplyTo[$i] || $From[$i]);
    $name = $addr if !$name;
    if (!$name) { 
	$Header[$i] =~ m/^\s*From\s+(\S+)\s+/;
	$name = $1 || $wafe_mu'user; 
	$From[$i] = $name; 
    }
   return sprintf( "%3d %-3s %2d %-18s %-6s %s", $i+1, $asciimonth, $day, 
                        substr($name,0,18), 
			'('.($Body[$i] =~ tr/\n/\n/) .')', $Subject[$i]);
}

#
# setLabelAttributes($i)
# sets color and bitmaps for the mailbox entry $i

sub setLabelAttributes {
    local($i) = @_;
    local($prior) = ($Priority[$i] =~ /.*Urg.*/) ? 'Urgent' : 'Ordinary';
    local($status) = ($Status[$i] =~ /.*R.*/) ? 'Read' : 'UnRead' ;
    local($index) = "$prior-$status";
    local($bitmap);
    BITMAP: {
        $bitmap = "deleted.xbm", last BITMAP if $Deleted[$i];
        $bitmap = "unread.xbm", last BITMAP  if $status eq 'UnRead';
        $bitmap = "read.xbm";
    }
    &Xui("sV l$i width 605 leftBitmap $bitmap $subjColors{$index}");
}


#
# setSubjectLine($from,$to)
# sets the subject lables for the reange of mailboxentries $from - $to
# using &subjectLine and &setLabelAttributes

sub setSubjectLabels {
    local($low,$high) = @_;
    local($line,$i,$toManage,$i);

    for ($low .. $high) {
	$i = $low + $high - $_; 
        ($line = &subjectLine($i)) =~ s/[\{\}\\\|]/\\$&/g;
	if ($Created[$i] != 1) {
 	    &Xui("labelLine $i {$line}");
	    $Created[$i] = 1;
            $toManage .= "l$i ";
	} 
        &setLabelAttributes($i);
	&Xui("sV l$i fromVert l".($i+1)) if $i < $high;
    }
    &Xui("sV l".($low-1)." fromVert l$low") if $low> 0;        
    &Xui("manageChild $toManage") if $toManage;
}

#
# displayMail($mailbody,$widget,$fname)
# displays the mail given in the first argument in the textwidget $widget
# by writing it to the file specified by $fname

sub displayMail {
       $asciiText{$_[2]} = $_[0];
       &wafe'fileTransaction($_[2], 
           "open(TMP, '>$_[2]') || die \"can't open $_[2] for writing!\";"
          .'print TMP  $main\'asciiText{"'.$_[2].'"};'
          .'close(TMP);'
          ."&wafe'setWidgetToFile('$_[1]','$_[2]');"
       );
}

#
# deleteMail($i)
# marks mailbox entry $i as deleted or undeleted
# depending on its state

sub deleteMail {
    local($doWith) = @_;
    return &warn("nothing selected and no current mail!") if $doWith < 0;
    $Deleted[$doWith] = !$Deleted[$doWith];
    if (!$fast) {
	&setSubjectLabels($doWith,$doWith);
    } else {
        local($delLine) = $doWith +1;
	$*=1; $subjectLines =~ /^\s*$delLine\D/; $*=0;
        local($pos) = length($`);
        local($char) = $Deleted[$doWith] ? 'D' : ' ';
        &Xui("doTextReplace subjects ".($pos+6)." ".($pos+7)." {$char}");
    }
}


#
# sendMode($mode)
# handles changes of the sendmode state and
# and refreshes the mail dieplay if not sendmode

sub sendMode {
    local($sendmode) = @_;

    if (!$sendmode) {
        local($from) = $ReplyTo[$CurrentMail] || $From[$CurrentMail];
        local($subject) = $Subject[$CurrentMail];
	$from =~ s/}/\\}/g;

        local($tmp) = 
	    ($FullHeader ? $Header[$CurrentMail] :"").
	    $Body[$CurrentMail];

    	if ($opt_C) {
	    &displayMail($tmp,'mailbody',$mailtext); 
	} else {
            &wafe'tunnel("COMM",$tmp,"sV mailbody type string string \$COMM");
        }
        &Xui("sV FromInfo label ".&TclQuote($from).";"
            ."sV SubjectInfo label ".&TclQuote($subject).";"
            ."sV DateInfo label {$Date[$CurrentMail]}");
    }

    &Xui("sV mailbody editType "
         .($sendmode? "edit wrap never" : "read wrap line"));
    &wafe'sensitive($CurrentMail != -1 && !$sendmode,
                    ("reply","forward","header","delete"));
    &wafe'sensitive($CurrentMail != -1 || $sendmode,("print","save"));
    &wafe'sensitive($sendmode,("send"));
    &wafe'sensitive(!$sendmode,("mail"));
    &wafe'sensitive(!$sendmode && ! $opt_r,("quit"));
    $SendMode = $sendmode;
}

#
# set default resources 

&wafe'setResources("",%textResources);

#
# the following settings are used several times

$textatt = "type file scrollVertical always string";
$every_hlabel = "justify left borderWidth 0 $backGround" 
    . ' top ChainTop bottom chainTop left chainLeft';	
$const_hlabel = "$every_hlabel  right chainLeft $boldFont";
$var_hlabel = "label {} $every_hlabel right chainRight " . $normalFont; 


#
# handle alternative representations in fast mode (asciiText widget is used) 
# and in oridnary mode (a viewport containing a from using command widgets)

$_ = $fast ? <<"__"
  label sgreplabel infoForm {
      fromVert info label "Subjectgrep:" top chainTop bottom chainTop 
      borderWidth 0 $backGround $boldFont
  }
  asciiText sgrep infoForm {
      fromVert info fromHoriz sgreplabel top chainTop bottom chainTop
      $normalFont $backGround editType edit width 200 borderWidth 0
  }
  action sgrep override {\\
     <Enter>: exec(sV %w $highLight)
     <Leave>: exec(sV %w $backGround)
     <Key>Return: exec(echo "sgrep [gV sgrep string]")
  }
  label bgreplabel infoForm {
     fromVert info fromHoriz sgrep top chainTop bottom chainTop
     label "Bodygrep:" borderWidth 0 $backGround $boldFont
  }
  asciiText bgrep infoForm {
     fromVert info fromHoriz bgreplabel top chainTop bottom chainTop 
     $normalFont $backGround editType edit width 200 borderWidth 0
  }
  action bgrep override {\\
     <Enter>: exec(sV %w $highLight)
     <Leave>: exec(sV %w $backGround)
     <Key>Return: exec(echo "bgrep [gV bgrep string]")
  }
  asciiText subjects infoForm {
     bottom chainBottom top chainTop
     scrollVertical always height 200 width 620 fromVert sgreplabel
     type file string $subjectFile $textFont $roColors cursor hand2
  }
  textSetSelectionArray subjects selectLine selectNull
  action subjects override {\\
     <Btn1Down>:   select-start() select-end(CUT_BUFFER0) \\
	             exec(echo read [fetchBuffer subjects 0]; markInText %w) \\
                     select-start() extend-adjust() next-line()
     <Btn1Up>:     no-op()
     <Btn1Motion>: no-op()
     <Key>d:       exec(oneOrMany %w {echo "delete \$result"})
     ~Ctrl<Key>s:  exec(oneOrMany %w \\
                     {global mail;set mail \$result; popup savemenu none})
     <Btn2Down>:   exec(sV %w cursor pencil) select-start()
     <Btn2Motion>: extend-adjust()
     <Btn2Up>:     extend-end(CUT_BUFFER0) exec(sV %w cursor hand2)
     <Btn3Up>:     no-op()
     <Btn3Down>:   no-op()
     <Btn3Motion>: no-op()
  }
__
: <<"__";
  viewport subjects infoForm {
     forceBars true allowVert true fromVert info height 200
  }
  form sb subjects defaultDistance 0 height 200 width 620
__

####################### tcl setup ##################
&Xui(<<'__');
#
# returns the first words of a selection

proc Selection {selection} {
    foreach line [split [string trimright $selection] \n] {
        lappend lines [lindex $line 0]
    }
    return $lines
}

#
# if something is selected return the list of ids, else -1

proc oneOrMany {w tcl} {
  textGetSelectionPos $w from to
  if $from!=$to {
    set length [expr $to-$from]
    for {set toread $length; set read 0; set content ""} {$read<$length} {
         set from [expr $from+$text(length)];set toread [expr $length-$read]} {
       textSourceRead $w $from text $toread
       set read [expr $text(length)+$read]
       append content [string range $text(ptr) 0 [expr $text(length)-1]]
    }
    set result [Selection [string range $content 0 $length]]
  } else { set result -1}
  eval $tcl
}

#
# remove character denoting unread mail (fast mode)

proc markInText {w} {
  sV $w editType edit
  textGetSelectionPos $w from to
  set text(firstPos) 0; set text(length) 1; set text(ptr) " ";
  textReplace $w [expr $from+5] [expr $from+6] text
  sV $w editType read
}

proc doTextReplace {w from to string} {
  sV $w editType edit
  set text(firstPos) 0; set text(length) [string length $string]
  set text(ptr) $string
  textReplace $w $from $to text
  sV $w editType read
}
__
### now we need perl variable substitutions
&TclCmd(<<"__");
#
# standard button settings

proc simpleButton {name father resources} {
      eval command \$name \$father $buttonAtts \$resources}

proc simpleButtonCB {name father resources} {
      simpleButton \$name \$father "\$resources callback {echo %w}"}

#
# Widget tree of the appliction
#         height 220 $backGround # preferredPaneSize 220 

paned paned topLevel orientation vertical width 620
   form infoForm paned {
      showGrip true borderWidth 0 defaultDistance 0 $backGround
   }
   label info infoForm $normalFont $infoColors bottom chainTop 
   $_

   form  headerf paned defaultDistance 0 min 65 max 65 $backGround
       label From headerf label {From:} $const_hlabel vertDistance 3
       label FromInfo headerf width 488 $var_hlabel fromHoriz From vertDistance 3
       label Subject  headerf label {Subject:} $const_hlabel fromVert From
       label SubjectInfo  headerf width 470 $var_hlabel fromHoriz Subject fromVert From
       label Date  headerf label {Date:} $const_hlabel fromVert Subject
       label DateInfo  headerf width 491 $var_hlabel fromHoriz Date fromVert Subject
       label bild headerf $backGround borderWidth 0 width 65 height 65 label {} \\
                horizDistance 541 right chainRight left chainRight 

   asciiText mailbody paned $textatt {/dev/null} height 350 \\
       autoFill true showGrip false $roColors $normalFont

   box buttons paned min 26 max 26 $backGround showGrip false
      simpleButtonCB quit buttons {}
      simpleButtonCB abort buttons {}

      simpleButtonCB mail buttons {}
      action mail override {<Btn3Up> : exec(echo "%w u")}
      simpleButtonCB reply buttons {sensitive false}
      action reply override {<Btn3Up> : exec(echo %w u")}
      simpleButtonCB forward buttons {sensitive false}
      action forward override {<Btn3Up> : exec(echo "%w u")}

      simpleButtonCB header buttons {sensitive false}
      simpleButtonCB delete buttons {sensitive false}
      simpleButtonCB print buttons {sensitive false}

      simpleButton save buttons \\
          {sensitive false callback {
            global mail; set mail -1; popup savemenu none}}

      transientShell  savemenu buttons $backGround
      callback savemenu popupCallback positionCursor 45

        dialog savetext savemenu label {File name or folder name:} \\
                 value {}  $backGround
        sV savetext.label $backGround $boldFont $threeD
        simpleButton savequit savetext \\
                 {label cancel callback {popdown savemenu}} 

        action savetext.value  override \\
	         "<Key>Return : exec(sendsave) XtMenuPopdown(savemenu)"


      label filler buttons label {} width 50 borderWidth 0 $backGround 
      simpleButtonCB send buttons {sensitive false}

      menuButton configButton buttons label Config menuName config $buttonAtts 


#
# build command widget for mailbox entry $i and configure it 

proc labelLine {i line} { global maxmail
  command l\$i sb unmanaged {
    label \$line borderWidth 0 width 605 $roColors
    justify left left chainLeft right chainRight top chainTop bottom chainTop
    callback "readmail \$i"
  }
  set i1 [expr \$i+1]
  action l\$i override "\\
    <Key>Return: exec(readmail \$i1)
    <LeaveWindow>: unhighlight()
    <Key>d:     exec(echo delete \$i1)
    <Key>p:     exec(echo print  \$i1)
    <Key>s:     exec(global mail;set mail \$i1;popup savemenu none)
    <Key>Down:  exec(sL +)
    <Key>Up:    exec(sL -)
    <Key>Next:  exec(sP +)
    <Key>Prior: exec(sP -)"
  if {\$i > \$maxmail} {set maxmail \$i}
}
__

#### the following commands do not need perl variable substitutions
&Xui(<<'__');
#
# send string "save xxxx" to the application and maintain 
# the global variable mail

proc sendsave {} {  global mail
  echo "save {$mail} [gV savetext value]"
  set $mail -1
}

#
# send string "read xxx" to the application and mark the current mail

proc readmail {i} { 
  global currentmail maxmail
  if {$i < 0} {set i 0}
  if {$i >= $maxmail} {set i $maxmail}
  echo "read $i"
  if {$currentmail > -1 && $currentmail <= $maxmail} {
    callActionProc l$currentmail {} unset
  }
  callActionProc l$i {} set
  set currentmail $i
}


#
# save and restore display position and caret of a text widget

proc savePos {w} {global displayPosition insertPosition
  set displayPosition($w) [gV $w displayPosition]
  set insertPosition($w) [gV $w insertPosition]
}
proc restorePos {w} {global displayPosition insertPosition
  sV $w displayPosition $displayPosition($w)
  sV $w insertPosition $insertPosition($w)
}

#
# scroll viewport by a single line up or down depending on pm (plus minus)

proc sL {pm} { global currentmail
  readmail [expr $currentmail$pm{-1}]
  set rel [expr 0$pm[gV l1 height].0/[gV sb height]]
  set pos [expr [gV vertical topOfThumb]+$rel]
  scrollbarSetThumb vertical $pos -1.0
  callCallbacks vertical jumpProc float $pos
}

#
# scroll viewport a page  up or down depending on pm (plus minus)

proc sP {pm} { global currentmail
  set lHeight [gV l1 height]
  set rel [expr 0$pm$lHeight.0/[gV sb height]]
  set lines [expr [gV subjects height]/$lHeight]
  readmail [expr $currentmail$pm{-1}*$lines]
  set pos [expr [gV vertical topOfThumb]+$rel*$lines]
  scrollbarSetThumb vertical $pos -1.0
  callCallbacks vertical jumpProc float $pos
}

#
# initialize global variables

set maxmail -1
set currentmail 5000
__

##################### uff, back in perl ############################

&wafe'applyActions("mailbody",(@textActions,
             'Ctrl<Key>w : exec(sV %w editType edit)',
             "Ctrl<Key>f : exec(sV %w $textFont)",
             "Ctrl<Key>v : exec(sV %w $normalFont)",
             ));
&wafe'applyActions("subjects",@textActions) if $fast;
$opt_r = $opt_r || 
    ($mailbox eq $incomingMailbox && -r "$tmpDir/mbox.$wafe_mu'user");
&wafe'sensitive(!$opt_r,("quit"));
&wafe_mu'createConfig("buttons","configButton",
		      ("mailIncludePrefix","printCommand","signatureFile",
                       "defaultMailHost","defaultMailEncoding"));

#
# read in mailbox

$mailbox = &wafe_mu'folderName("Mail",$mailbox);
$unread = 0;
$count=-1;
if (open(MBOX,"<$mailbox")) {
	&readMailBox(0);
	close(MBOX);
}
&info( ($opt_r ? "Mailbox READ ONLY!  " : "") . "mailbox $mailbox "
      .($count== -1? "is empty" : "contains ". ($count+1)." entries"));
&Xui("sV info width 620");

if ($fast) {
    &writeSubjects($[,$count,$spattern,$bpattern);   
    &Xui("sV subjects string $subjectFile"); 
} else {
    &setSubjectLabels($[,$count);
}
&Xui("sV topLevel iconPixmap ".($unread == 0? "mailempty":"mailfull"));
&Xui('realize; deleteWindowProtocol quit');


#
# the application is mapped to the screen, let see, what it talks to us.
#

$CurrentMail = -1; 
$FullHeader = 0;
$SendMode = 0;
$pos=0;

while(1) {
    $_ = &wafe'readTimeout($opt_u);
#   print "RECEIVED: <$_> \n";
    if (/^read\s+(\d+)/) {
        if ($SendMode) {
            &warn("Finish writing your mail before you read another mail!");
	    next;
        }
        $CurrentMail = $1;
        $CurrentMail-- if $fast;

	&info("Current message is ".($CurrentMail+1));
        &Xui("callActionProc l$CurrentMail {} set") if !$fast;

	if (!$Status[$CurrentMail] || $Status[$CurrentMail] eq "O") {
	    if (!$Status[$CurrentMail]) {
		$Header[$CurrentMail] = 
		    substr($Header[$CurrentMail],0,
                        length($Header[$CurrentMail])-1) 
			. "Status: OR\n\n";
	    } else {
		$Header[$CurrentMail] =~ s/Status: .*/Status: OR/o; 
	    }
            $unread --;
            &Xui("sV topLevel iconPixmap mailempty") if $unread == 0;
	    $Status[$CurrentMail] = 'OR';
	    &setLabelAttributes($CurrentMail) if !$fast;
	}
        &sendMode(0);

        ($name,$fromaddr) = &wafe_mu'nameAddress( 
	      $ReplyTo[$CurrentMail] || $From[$CurrentMail] );
	$fromaddr =~ m/([a-zA-Z0-9_\-\.\+]+)@?.*/;

        if ($useXPM && -r "$faceDir/$1.xpm") {
              &Xui("changePixmap bild bitmap $faceDir/$1.xpm");
        } else {
             local($bitmap);
             $bitmap = "$faceDir/$1.xbm" if -r "$faceDir/$1.xbm";
   	     &Xui("sV bild bitmap ". ($bitmap || "None"));
        }
    }

    if (/^header/) {
	$FullHeader = !$FullHeader;
        local($tmp) = ($FullHeader ? $Header[$CurrentMail] :"").$Body[$CurrentMail];
        &displayMail($tmp,'mailbody',$mailtext); 
    }

    if (/^(reply|forward)\s*(\w*)/) {
        &wafe_mu'returnMail($mailtext,"mailbody",$1,$2,
	      $ReplyTo[$CurrentMail] || $From[$CurrentMail],$Cc[$CurrentMail],
	      $Subject[$CurrentMail],$Date[$CurrentMail],$Body[$CurrentMail]);
    }

    if (/^mail\s*(\w*)/) {
        $urgent = ($1 ne "");

	open(MAILTEXT,">$mailtext") || die("can't open $mailtext for writing\n"); 
	print MAILTEXT "To: \nSubject: \n";
	print MAILTEXT "Priority: Urgent\n" if $urgent;
	print MAILTEXT "Date: ", &wafe_mu'mailDateNow(), "\n\n\n";
        print MAILTEXT "\n\n--\n$wafe_mu'signature" if $wafe_mu'signature;
	close(MAILTEXT);

        &Xui("sV mailbody type file string $mailtext");
        &sendMode(1);
	&Xui("callActionProc mailbody {} end-of-line");
    }

    if (/^send/) {
        &wafe_mu'send($mailtext,"mailbody");
    }

    if (/^print\s*(\d*)/) {
        &info("printing with $printCommand ...");

        local($i) =  $1 ne "" ? $1 : $CurrentMail;
        local($content) = ($SendMode && $1 eq "") ?
                     &wafe_mu'widgetContent($mailtext,"mailbody") :
		     $Header[$i] . $Body[$i];
#                     (&wafe_mu'SweEncode($Header[$i] . $Body[$i]),1);

        (&wafe_mu'printArgInto($content,"|$printCommand") &&
               &info("File printed")) || 
               &warn("cannote print using $printCommand");
    }

    if (/^save\s+\{(\-?\d+.*)\}\s+(.*)/) {
        local($doWith) =$1;
        local($name) = $2 || (($SendMode && $1 == -1) ? "outgoing":"incoming");
        $target = &wafe_mu'folderName("Mail",$name);
        local($ptarget) = ($target =~ /^\|/ ? $target : ">>$target");

	foreach (reverse split(" ",$doWith)) { 
	    local($i) =  $_ != -1 ? $_-1 : $CurrentMail;
	    local($content,$del) = ($SendMode && $_ == -1) ?
		(&wafe_mu'fromHeader($wafe_mu'user, 
                          &wafe_mu'widgetContent($mailtext,"mailbody")),0) :
	                  ("\n" . $Header[$i] . $Body[$i],1);

	    (&wafe_mu'printArgInto($content,$ptarget) &&
               &info("Mail saved into $target")) 
            ||  ( &warn("Mail cannot be saved into $target") && ($del = 0));
            &deleteMail($i) if $del;
        }
    }

    if (($spattern) = /^sgrep\s+(.*)$/) {
	&info("Seaching for pattern \"$spattern\" in Subject Lines ...");   
        $spattern =~ s/(\W)/\\\1/g;
        &writeSubjects($[,$count,$spattern,$bpattern);   
        &Xui("sV subjects string $subjectFile"); 
	&info("");   
    }
    if (($bpattern) = /^bgrep\s+(.*)$/) {
	&info("Seaching for pattern \"$bpattern\" in Mailbodies ...");   
        $bpattern =~ s/(\W)/\\\1/g;
        &writeSubjects($[,$count,$spattern,$bpattern);   
        &Xui("sV subjects string $subjectFile"); 
	&info("");   
    }

    if (/^delete\s*(-?\d*.*)/) {
        &Xui('oneOrMany subjects {echo "delete $result"}'), next 
              if $fast && $1 eq "";
        $1 = "" if $1 =~ /[^\d -]/;     #selection is messed up
	if ($1 eq "" || $1 == -1) { &deleteMail($CurrentMail); }
	else { foreach (split(" ",$1)) { &deleteMail($_-1); } }
    }

    if (($varname) = /^setconfig\s*(\S+)$/) {
        local($value);
        eval '$value = $'."$varname;";
        &Xui("sV configsetvaltext value {$value};popup configsetvalmenu none");
        undef $varname; 
    }
    if (($varname,$value) = /^setPerl\s(\S+)\s(.*)$/) {
        eval "\$$varname = \"".$value."\";";
        undef $varname; undef $value;
    }

    if (/^(quit|abort)/) {
        if ($SendMode) { 
             &sendMode(0);
	} else {
	    if ($1 eq 'quit') {
		&info("saving mailbox");
		open(MBOX, ">$mailbox");
		&wafe_mu'exclusiveLock(MBOX);
		for ( $[ .. $#Header ) {
		    print MBOX $Header[$_], $Body[$_] if $Deleted[$_] != 1;
		}
		&wafe_mu'unLock(MBOX);
		close(MBOX);
		&info("mailbox saved");
	    }

	    &wafe'cleanup();
            &Xui("quit");
	    exit;
	}
    }

    if ($MailBoxSize !=  -s $mailbox) {
	$new = -s $mailbox;
	&warn("Size of mailbox $mailbox changed from $MailBoxSize to $new Next: $count");

        if ($new > $MailBoxSize && !$shrunk) {
	    $oldCount = $count;
	    open(MBOX,"<$mailbox") || die "can't open $mailbox for reading\n";
	    &readMailBox($MailBoxSize);
	    close(MBOX);
            if ($fast) {
                &writeSubjects($[,$count,$spattern,$bpattern);   
                &Xui("sV subjects string $subjectFile"); 
            } else { 
               &setSubjectLabels($oldCount+1,$count);
            }
            &Xui("sV topLevel iconPixmap mailfull");
	    &info("New mail arrived");   
	} else {
	    &info("your mailbox SHRUNK! abort recommended!");
	    $shrunk = 1;
	    $opt_r = 1;
	    &wafe'sensitive(0,("quit"));
#	    $MailBoxSize = $new;
	}
    }

    &wafe'unlockTextWidget();
# print "RECEIVED: <<$_>> $unread, $count, $#Header, $MailBoxSize, ".(-s $mailbox)."\n";

}

