#!/usr/bin/perl -wT

use strict;
use MIME::Base64;
use MIME::QuotedPrint;

my $home=$ENV{'HOME'};
if (-d "$home/Maildir") {
	main_maildir($home);
}
else {
	main_mbox();
}

#----------------------------------
sub main_maildir {
my $home=$_[0];

my @mails;
my @dirs=("new","cur","tmp");

foreach my $dir (@dirs) {
	my @tmpmails=get_files_in_maildir($dir,$home);
	push @mails,@tmpmails;
}

my @mails_in_order = sort @mails;

foreach my $mail (@mails_in_order) {
	my @mail_file_details=split(/#/,$mail);
	my $from_name;
	my $subject;
	my $done_with_this_mail="no";
	my @currentmail;
	
	if(open(CURRENTMAIL,"$home/Maildir/$mail_file_details[1]/$mail_file_details[0]")) {
		@currentmail=<CURRENTMAIL>;
		close(CURRENTMAIL);
	}

	my $maildir_flags=(split(/,/,$mail_file_details[0]))[2];
	
	# If the mail is marked as deleted (T - trashed), don't show it in the summary
	if((!(defined($maildir_flags))) or (!($maildir_flags=~/T/))) {

		my $currentmail_len=@currentmail;
		my $currentmail_position=0;

		while($currentmail_position < $currentmail_len) {

			my $maildir_line=$currentmail[$currentmail_position];

			if($maildir_line=~/^From:/i) {
				$from_name=extract_from($maildir_line);
			}
			elsif($maildir_line=~/^Subject:/i) {
				my $subject_line=$maildir_line;
				chomp($subject_line);

				# if the subject spans several lines we need to put it back together again
				if($currentmail[$currentmail_position+1]=~/^\s/) {
					my $subject_pos=$currentmail_position+1;
					while($currentmail[$subject_pos]=~/^\s/) {
						chomp($currentmail[$subject_pos]);
						$subject_line.=$currentmail[$subject_pos];
						$subject_pos++;
					}
					$subject_line.="\n";

				}
				$subject=extract_subject($subject_line);
				
			}
	
			if((defined($subject)) and (defined($from_name))) {
				display_line($from_name,$subject);
				$done_with_this_mail="yes";
		
				undef($subject);
				undef($from_name);
				$currentmail_position=$currentmail_len+10;
			}

		$currentmail_position++;
		}

		if($done_with_this_mail eq "no") {
			display_line($from_name,$subject);
			$done_with_this_mail="yes";
			undef($subject);
			undef($from_name);
		}
	}
	
}

if((defined($ENV{'SUMMARY_FOLDERS'})) and (! -z $ENV{'SUMMARY_FOLDERS'})) {
	summary_extra_folders($ENV{'SUMMARY_FOLDERS'},"Maildir",$ENV{'HOME'});
}

}
#----------------------------------

sub main_mbox {

my ($mailbegin,$from_name,$subject,$line,$mailbox,$deleted);
$mailbox=$ENV{'MAIL'} or die "\$MAIL not defined in your environment\n";

if ((! -e $mailbox ) or ( -z $mailbox )) {
	print "You have no mail.\n";
}
else {

	open(MAILBOX,$mailbox);
	while (my $mailboxline=<MAILBOX>) {

		# A ha! A "From " line.  That's the start of a mail that is.
		if($mailboxline=~/^From /) {
			$mailbegin=1;
			if(defined($from_name) or defined($subject)) {
				display_line($from_name,$subject);
				undef($subject);
	                        undef($from_name);
			}
		}

		# While we're processing the header, let's look for certain things
		if($mailbegin == 1) {
			if ($mailboxline=~/^From:/i) {
				$from_name=extract_from($mailboxline);	
			}
			elsif($mailboxline=~/^Subject:/i) {
				$subject=extract_subject($mailboxline);
			}
			elsif($mailboxline=~/^(X-)?Status:.*D/i) {
				$deleted="true";
			}
		}

		#if((defined($subject)) and (defined($from_name))) {
		# This happens once we get to the blank line which tells us the header is finished
		if(($mailbegin==1) and ($mailboxline eq "\n")) {
			if(!(defined($deleted))) {
				display_line($from_name,$subject);
			}
		
			$mailbegin=0;
			undef($subject);
			undef($from_name);
			undef($deleted);
	
		}
	}
	close(MAILBOX);

	if(defined($from_name) or defined($subject)) {
		display_line($from_name,$subject);
	}
}

if((defined($ENV{'SUMMARY_FOLDERS'})) and (! -z $ENV{'SUMMARY_FOLDERS'})) {
	summary_extra_folders($ENV{'SUMMARY_FOLDERS'},"mbox",$ENV{'HOME'});
}

}
#---------------------------------------

sub decode {

my $string=$_[0];
my ($encoded,$decoded);

if($string=~/\?(iso-8859|utf|windows)-?[0-9]{0,4}\?/i) {
	my @encoded_chunks=split(/\s+/,$string);

	foreach my $chunk (@encoded_chunks) {
		$encoded=(split(/\?/,$chunk))[3];

		if($chunk=~/\?(iso-8859-|utf|windows)-?[0-9]{0,4}\?q/i) {
			$decoded.=decode_qp($encoded);
			$decoded=~s/_/ /g;
		}
		elsif($chunk=~/\?(iso-8859-|utf|windows)-?[0-9]{0,4}\?b/i) {
			$decoded.=decode_base64($encoded);
		}
		else {	
			$decoded.=$chunk." ";
		}
	}
}
else {
	$decoded=$string;
}

return $decoded;
}

#--------------------------------------

sub extract_from {

my $from_line=$_[0];
my $from_name;

if(my @from_vars = $from_line=~/^From:\s+(?:\<(.*)\>|\"(.*)\"|(.*)\s*\<|.*?\((.*)\)|(.*))/i) {
	foreach my $from_var (@from_vars) {
		if(defined($from_var)) {
			$from_name=$from_var;
		}
	}

	if(defined($from_name)) {
		chomp($from_name);
		$from_name=decode($from_name);
	}
}

return $from_name;
}

#------------------------

sub extract_subject {

my $subject_line=$_[0];
my $subject;

if($subject_line=~/^Subject:\s+(.*)/i) {
	$subject=$1;
	chomp($subject);
	$subject=decode($subject);
}

return $subject;
}

#-------------------------

sub display_line {

my $from_name=$_[0];
my $subject=$_[1];
my $line;

if(!defined($from_name)) {
	$from_name=" ";
}
if(!defined($subject)) {
	$subject=" ";
}

$line=sprintf "%-21s", $from_name;
$line=$line." ".$subject;
$line=substr($line,0,80);
if($subject ne "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA") {
	print $line."\n";
}

}

#--------------------------

sub summary_extra_folders {

my $in=$_[0];
my $storage_method=$_[1];
my $home=$_[2];
chomp($in);

my @folders=split(/\,|:/,$in);

print "\n";

foreach my $folder (@folders) {
	if($storage_method eq "Maildir") {
		summary_maildir_folder($folder,$home);
	}
	elsif($storage_method eq "mbox") {
		summary_mbox_folder($folder);
	}
}

}

#------------------------

sub summary_maildir_folder {
my $folder=$_[0];
my $home=$_[1];
my @mails;
my $unread=0;

my @dirs=("new","cur","tmp");

foreach my $dir (@dirs) {
        my @tmpmails=get_files_in_maildir($dir,$home,$folder);
        push @mails,@tmpmails;
}

foreach my $mail (@mails) {
	if((!($mail=~/,[A-Z]*S[A-Z]*\#/i)) and (!($mail=~/^\.{1,2}\#/))) {
		$unread++;
	}
}

if($unread > 0) {
	print $folder." ".$unread." unread\n";
}

}
#------------------------

sub summary_mbox_folder {
my $folder=$_[0];

if(open(MAILFOLDER,$folder)) {
	my $mails=0;
	my $read=0;
	while(my $folderline = <MAILFOLDER>) {
		if($folderline=~/^From /) {
			$mails++;
		}
		elsif ($folderline=~/^Status: RO/) {
			$read++;
		}
	}
	if($read < $mails) {
		my @folder_parts=split(/\//,$folder);
		my $disp_folder=pop(@folder_parts);	
		print $disp_folder." ".($mails-$read)." unread\n";
	}

}
else {
	print "Unable to open $folder\n";
}

}

#------------------

sub get_files_in_maildir {
my $dir=$_[0];
my $home=$_[1];
my $folder=$_[2];

my @mails;

if(defined($folder)) {
	opendir(DIR,"$home/Maildir/.$folder/$dir") or print "Unable to open $home/Maildir/.$folder/$dir\n";
}
else {
	opendir(DIR,"$home/Maildir/$dir") or print "Unable to open $home/Maildir/$dir\n";
}

while(my $mail=readdir(DIR)) {
	if(!($mail=~/^\.{1,2}$/)) {
	        push @mails, "$mail#$dir";
	}
}
close(DIR);
return @mails;
}


