#!/usr/bin/perl
#
# vscan :: Virtual scan for Mew that give a single view for multiple folders
#
# Author:  Kazuhiko Yamamoto <kazu@is.aist-nara.ac.jp>
# Version: 0.9
#
# Created: June  17, 1995
# Revised: March 26, 1997
# Modified: July 25, 1995  	Shiegya Suzuki <shigeya@foretune.co.jp>
# Modified: November 28, 1995	Shigeya Suzuki <shigeya@foretune.co.jp>
# Modified: December 12, 1995	Shigeya Suzuki <shigeya@foretune.co.jp>
# Modified: March 13, 1996	Shigeya Suzuki <shigeya@foretune.co.jp>
# Modified: May 27, 1996	Shigeya Suzuki <shigeya@foretune.co.jp>
#
# Usage:
#   vscan [--pick pick_patterns] [--scan scan_options] +folder [+folder ...]
#
# In the end of line, "^M" for selective-display and folder/message follow. 

$debug = 0;
$pickcommand = "/usr/local/bin/pick";
$scancommand = "/usr/local/bin/scan";
$mhpathcommand = "/usr/local/bin/mhpath";

chop($mailfolder = `$mhpathcommand +`);

$folderalias = "$mailfolder/FolderAlias";

chop($pwd = `pwd`);

#
# scan FolderAlias file
#
if (-e $folderalias ) {
    open(F,$folderalias) || die "Can't open $folderalias: $!";
    while(<F>) {
	next if /^#/;
	chop;
	s/,/ /g; # change comma to space
	s/\s+/ /g; # remove extra spaces
	s/\s+:\s+/:/g; # too.
	if ((($foldername, $folderlist) = split(/:/)) == 2) {
	    $foldername =~ s/ //g; # remove space from name
	    $foldername =~ s/\+//g; # remove + from name
	    $folderlist =~ s/^\s+//g;
	    $folderalias{$foldername} = $folderlist;
	}
    }
    close(F);
}

$pick = 0;
$scan = 0;
foreach (@ARGV) {
    if ( /\+(.*)/ ) {
	push(@folders, &recurseexpand($_));
    } elsif ( $_ eq "--pick") {
	$pick = 1;
	$scan = 0;
    } elsif ( $_ eq "--scan") {
	$pick = 0;
	$scan = 1;
    } elsif ($scan) {
	s/^(.*)$/'$1'/ if m/ /;
	push(@scanargs, $_);
    } elsif ($pick) {
	s/^(.*)$/'$1'/ if m/ /;
	push(@pickargs, $_);
    }
}

$num = 1;
foreach $targetfolder (@folders) {
    print STDERR "FOLDER: $targetfolder\n" if $debug;
    if (@pickargs) {
	@messages = ();
	$pickcmd = "$pickcommand ".join(" ",@pickargs)." $targetfolder |";
	print STDERR "pickcmd: $pickcmd\n" if $debug;
	open(PICK, $pickcmd);
	while(<PICK>) {
	    chop;
	    push(@messages, $_);
	}
	close(PICK);
	print join(" ", @messages), "\n" if $debug;
    } else {
	push(@messages,"all");
    }
    if (@messages) {
	open(FOLDER, "$scancommand ".join(" ", @scanargs)." $targetfolder ".join(" ", @messages)." |");
	while(<FOLDER>) {
	    chop;
	    if (/ *([0-9]+)(.*)/) {
		# virtual number
		# contents
		# ^M for selective-display
		# +folder/message
		printf "%4d%s\015 %s %s\n", 
		$num, $2, $targetfolder, $1;
	    }
	    $num ++;
	}
	close(FOLDER);
    }
}

sub expandone {
    local($s) = shift;
    local(@r) = ();

    chdir($mailfolder);
    foreach $k(split(/\s+/,$s)) {
	if (m/[\*\?\{\}\[\]]/) {	# has wild match
	    s/^\+//;
	    foreach (<${k}>) {		# perl4 don't have map()!
	    	push(@r, "+$_");
	    }
    	}
        else {
	    push(@r, "$_");
	}
    }
    chdir($pwd);
    return @r;
}

sub recurseexpand {
    local($s) = shift;
    local(@r) = ();
    local(@k);
    local($k);

    if ($s =~ s/^\+//g) {
	if (defined($folderalias{$s}) ne "") {
	    foreach (split(/\s+/, $folderalias{$s})) {
		push(@r, &recurseexpand($_));
	    }
	    return @r;
	}
	if (@k = grep(/$s/, sort keys %folderalias)) {
	    foreach (@k) {
		push(@r, &recurseexpand("+$_"));
	    }
	    return @r;
	}

    }
    return &expandone($s);
}

# End of vscan
